From 66f668f9860e3ae4e3ee8c5de1d372295390590e Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 3 May 2018 15:11:34 -0700 Subject: [PATCH 01/90] Implement iterate function --- opmd_viewer/openpmd_timeseries/main.py | 36 +++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 695f991a..1c1c60f4 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -10,6 +10,7 @@ import numpy as np import h5py as h5 +from tqdm import tqdm from .utilities import list_h5_files, apply_selection, fit_bins_to_grid from .plotter import Plotter from .particle_tracker import ParticleTracker @@ -20,7 +21,6 @@ from .data_reader.utilities import join_infile_path from .interactive import InteractiveViewer - # Define a custom Exception class OpenPMDException(Exception): "Exception raised for invalid use of the openPMD-viewer API" @@ -509,6 +509,40 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, # Return the result return(F, info) + + def iterate( self, called_method, *args, **kwargs ): + """ + TODO + """ + # Check the shape of results + result = called_method(*args, **kwargs, iteration=self.iterations[0]) + if type( result ) == tuple: + returns_tuple = True + tuple_length = len(result) + accumulated_result = ( [element] for element in result ) + else: + returns_tuple = False + accumulated_result = [ result ] + + # Call the method for all iterations + for iteration in tqmd(self.iterations[1:]): + result = called_method( *args, **kwargs, iteration=iteration ) + if returns_tuple: + for i in range(tuple_length): + accumulated_result[i].append( result[i] ) + else: + accumulated_result.append( result ) + + # Try to stack the arrays + if returns_tuple: + for i in range(tuple_length): + accumulated_result[i] = np.stack(accumulated_result[i], axis=0) + else: + accumulated_result = np.stack( accumulated_result, axis=0 ) + + return accumulated_result + + def _find_output(self, t, iteration): """ Find the output that correspond to the requested `t` or `iteration` From a9bede294f1b3f4c58a1d3111b8e1c4c143cecfe Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 3 May 2018 22:08:19 -0700 Subject: [PATCH 02/90] Add requirements for `iterate` --- conda_recipe/meta.yaml | 2 ++ requirements.txt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/conda_recipe/meta.yaml b/conda_recipe/meta.yaml index 957d4883..f112780c 100644 --- a/conda_recipe/meta.yaml +++ b/conda_recipe/meta.yaml @@ -20,6 +20,7 @@ requirements: - scipy - matplotlib - h5py + - tqdm run: - python - cython @@ -28,6 +29,7 @@ requirements: - matplotlib - h5py - jupyter + - tqdm test: imports: diff --git a/requirements.txt b/requirements.txt index e2aed537..0905111e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ numpy scipy h5py +tqdm + From 5f3491714d743f2f264be3e26852ae07f5ac4dce Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Fri, 4 May 2018 07:30:33 -0700 Subject: [PATCH 03/90] Fix PEP8 issues --- opmd_viewer/openpmd_timeseries/main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 1c1c60f4..a53de75e 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -21,6 +21,7 @@ from .data_reader.utilities import join_infile_path from .interactive import InteractiveViewer + # Define a custom Exception class OpenPMDException(Exception): "Exception raised for invalid use of the openPMD-viewer API" @@ -509,7 +510,6 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, # Return the result return(F, info) - def iterate( self, called_method, *args, **kwargs ): """ TODO @@ -542,7 +542,6 @@ def iterate( self, called_method, *args, **kwargs ): return accumulated_result - def _find_output(self, t, iteration): """ Find the output that correspond to the requested `t` or `iteration` From 63fc344141b61370ee7d5485da5773fc0e5fbedb Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Fri, 4 May 2018 08:41:05 -0700 Subject: [PATCH 04/90] Correct syntax error --- opmd_viewer/openpmd_timeseries/main.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index a53de75e..4371e893 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -514,8 +514,11 @@ def iterate( self, called_method, *args, **kwargs ): """ TODO """ + # Add the iteration key in the keyword aguments + kwargs['iteration'] = self.iterations[0] + # Check the shape of results - result = called_method(*args, **kwargs, iteration=self.iterations[0]) + result = called_method(*args, **kwargs) if type( result ) == tuple: returns_tuple = True tuple_length = len(result) @@ -526,6 +529,7 @@ def iterate( self, called_method, *args, **kwargs ): # Call the method for all iterations for iteration in tqmd(self.iterations[1:]): + kwargs['iteration'] = iteration result = called_method( *args, **kwargs, iteration=iteration ) if returns_tuple: for i in range(tuple_length): From 40f103a100aafe1a13ee17d43bbb7cbe9b384a15 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Fri, 4 May 2018 09:42:34 -0700 Subject: [PATCH 05/90] Corrected typo --- opmd_viewer/openpmd_timeseries/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 4371e893..a820dee3 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -528,7 +528,7 @@ def iterate( self, called_method, *args, **kwargs ): accumulated_result = [ result ] # Call the method for all iterations - for iteration in tqmd(self.iterations[1:]): + for iteration in tqdm(self.iterations[1:]): kwargs['iteration'] = iteration result = called_method( *args, **kwargs, iteration=iteration ) if returns_tuple: From 93d3f3e92ba9494138a094cdad44256ae1edbc41 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Fri, 4 May 2018 10:26:41 -0700 Subject: [PATCH 06/90] Fix typo --- opmd_viewer/openpmd_timeseries/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index a820dee3..276cbe53 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -530,7 +530,7 @@ def iterate( self, called_method, *args, **kwargs ): # Call the method for all iterations for iteration in tqdm(self.iterations[1:]): kwargs['iteration'] = iteration - result = called_method( *args, **kwargs, iteration=iteration ) + result = called_method( *args, **kwargs ) if returns_tuple: for i in range(tuple_length): accumulated_result[i].append( result[i] ) From 33487666d6da7c2fb8f0f9719fcad2dba8e633b8 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Fri, 4 May 2018 19:09:29 -0700 Subject: [PATCH 07/90] works in 3d --- .../data_reader/field_reader.py | 58 ++++++++++++------- .../data_reader/utilities.py | 43 ++++++++++---- 2 files changed, 69 insertions(+), 32 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index e42a81e2..a68ed79f 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -179,7 +179,7 @@ def read_field_circ( filename, field_path, m=0, theta=0. ): def read_field_3d( filename, field_path, axis_labels, - slicing=0., slicing_dir='y'): + slicing=[0.], slicing_dir=['y']): """ Extract a given field from an HDF5 file in the openPMD format, when the geometry is 3d cartesian. @@ -196,19 +196,19 @@ def read_field_3d( filename, field_path, axis_labels, axis_labels: list of strings The name of the dimensions of the array (e.g. ['x', 'y', 'z']) - slicing : float, optional + slicing : float or list of float, optional Only used for 3dcartesian geometry - A number between -1 and 1 that indicates where to slice the data, - along the direction `slicing_dir` + numbers between -1 and 1 that indicates where to slice the data, + along directions given in `slicing_dir` -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box If slicing is None, the full 3D grid is returned. - slicing_dir : str, optional + slicing_dir : str or list of str, optional Only used for 3dcartesian geometry - The direction along which to slice the data - Either 'x', 'y' or 'z' + Direction along which to slice the data + Elements can be 'x', 'y' or 'z' Returns ------- @@ -217,6 +217,12 @@ def read_field_3d( filename, field_path, axis_labels, info : a FieldMetaInformation object (contains information about the grid; see the corresponding docstring) """ + + if slicing is not None and not isinstance(slicing, list): + slicing = [slicing] + if slicing_dir is not None and not isinstance(slicing_dir, list): + slicing_dir = [slicing_dir] + # Open the HDF5 file dfile = h5py.File( filename, 'r' ) # Extract the dataset and and corresponding group @@ -229,22 +235,34 @@ def read_field_3d( filename, field_path, axis_labels, # Slice selection if slicing is not None: # Get the integer that correspond to the slicing direction - slicing_index = axis_labels.index(slicing_dir) - # Number of cells along the slicing direction - n_cells = shape[ slicing_index ] - # Index of the slice (prevent stepping out of the array) - i_cell = int( 0.5 * (slicing + 1.) * n_cells ) - i_cell = max( i_cell, 0 ) - i_cell = min( i_cell, n_cells - 1) + list_slicing_index = [] + list_i_cell = [] + new_labels = axis_labels + for count, slicing_dir_item in enumerate(slicing_dir): + slicing_index = axis_labels.index(slicing_dir_item) + list_slicing_index.append(slicing_index) + # Number of cells along the slicing direction + n_cells = shape[ slicing_index ] + # Index of the slice (prevent stepping out of the array) + i_cell = int( 0.5 * (slicing[count] + 1.) * n_cells ) + i_cell = max( i_cell, 0 ) + i_cell = min( i_cell, n_cells - 1) + list_i_cell.append(i_cell) + # Remove metainformation relative to the slicing index - shape.pop( slicing_index ) - grid_spacing.pop( slicing_index ) - global_offset.pop( slicing_index ) - new_labels = axis_labels[:slicing_index] + \ - axis_labels[slicing_index + 1:] + # Successive pops starting from last element + list_indices_to_clean = list_slicing_index[:] + list_indices_to_clean.sort(reverse=True) + for index_to_clean in list_indices_to_clean: + shape.pop( index_to_clean ) + grid_spacing.pop( index_to_clean ) + global_offset.pop( index_to_clean ) + new_labels = new_labels[:index_to_clean] + \ + new_labels[index_to_clean + 1:] + axes = { i: new_labels[i] for i in range(len(new_labels)) } # Extraction of the data - F = get_data( dset, i_cell, slicing_index ) + F = get_data( dset, list_i_cell, list_slicing_index ) info = FieldMetaInformation( axes, shape, grid_spacing, global_offset, group.attrs['gridUnitSI'], dset.attrs['position'] ) else: diff --git a/opmd_viewer/openpmd_timeseries/data_reader/utilities.py b/opmd_viewer/openpmd_timeseries/data_reader/utilities.py index 97dcc6a9..3ef33b3e 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/utilities.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/utilities.py @@ -59,12 +59,12 @@ def get_data(dset, i_slice=None, pos_slice=None, output_type=np.float64): dset: an h5py.Dataset or h5py.Group (when constant) The object from which the data is extracted - i_slice: int, optional - The index of the slice to be taken + pos_slice: int or list of int, optional + Direction of each slice. + When None, no slice is performed - pos_slice: int, optional - The position at which to slice the array - When None, no slice is performed + i_slice: int or list of int, optional + Indices of slices to be taken output_type: a numpy type The type to which the returned array should be converted @@ -73,24 +73,43 @@ def get_data(dset, i_slice=None, pos_slice=None, output_type=np.float64): -------- An np.ndarray (non-constant dataset) or a single double (constant dataset) """ + # For back-compatibility: Convert pos_slice and i_slice to + # single-element list if they are not lists (e.g. float + # and int respectively). + if pos_slice is not None and not isinstance(pos_slice, list) : + pos_slice = [pos_slice] + if i_slice is not None and not isinstance(i_slice, list) : + i_slice = [i_slice] + # Case of a constant dataset if isinstance(dset, h5py.Group): shape = dset.attrs['shape'] # Restrict the shape if slicing is enabled if pos_slice is not None: - shape = shape[:pos_slice] + shape[pos_slice + 1:] + shape = shape[:pos_slice[0]] + shape[pos_slice[0] + 1:] # Create the corresponding dataset data = dset.attrs['value'] * np.ones(shape) + # Case of a non-constant dataset elif isinstance(dset, h5py.Dataset): if pos_slice is None: data = dset[...] - elif pos_slice == 0: - data = dset[i_slice, ...] - elif pos_slice == 1: - data = dset[:, i_slice, ...] - elif pos_slice == 2: - data = dset[:, :, i_slice] + else: + # Get largest element of pos_slice and its index + max_pos = max(pos_slice) + ind_max_pos = pos_slice.index(max_pos) + # Create index list list_index of type + # [:, :, :, ...] where Ellipsis starts at ind_max_pos + 1 + length_list_index = max_pos + 2 + list_index = [np.s_[:]] * (max_pos + 2) + list_index[max_pos+1] = np.s_[...] + # Fill list_index with elements of i_slice + for count, dir_index in enumerate(pos_slice): + list_index[dir_index] = i_slice[count] + # Convert list_index into a tuple + tuple_index = tuple(list_index) + # Slice dset according to tuple_index + data = dset[tuple_index] # Convert to the right type if data.dtype != output_type: From e5c8479010e38cb5f2b254cd975c04760a1686c7 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Fri, 4 May 2018 19:20:36 -0700 Subject: [PATCH 08/90] works in 2d --- .../data_reader/field_reader.py | 62 +++++++++++++++---- opmd_viewer/openpmd_timeseries/main.py | 9 ++- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index a68ed79f..5d7d5b75 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -57,7 +57,8 @@ def read_field_1d( filename, field_path, axis_labels ): return( F, info ) -def read_field_2d( filename, field_path, axis_labels ): +def read_field_2d( filename, field_path, axis_labels, + slicing=None, slicing_dir=None ): """ Extract a given field from an HDF5 file in the openPMD format, when the geometry is 2d cartesian. @@ -81,25 +82,64 @@ def read_field_2d( filename, field_path, axis_labels ): info : a FieldMetaInformation object (contains information about the grid; see the corresponding docstring) """ + if slicing is not None and not isinstance(slicing, list): + slicing = [slicing] + if slicing_dir is not None and not isinstance(slicing_dir, list): + slicing_dir = [slicing_dir] + # Open the HDF5 file dfile = h5py.File( filename, 'r' ) # Extract the dataset and and corresponding group group, dset = find_dataset( dfile, field_path ) - - # Extract the data in 2D Cartesian - F = get_data( dset ) - - # Extract the metainformation - axes = { 0: axis_labels[0], 1: axis_labels[1] } - info = FieldMetaInformation( axes, F.shape, - group.attrs['gridSpacing'], group.attrs['gridGlobalOffset'], - group.attrs['gridUnitSI'], dset.attrs['position'] ) + + # Dimensions of the grid + shape = list( get_shape( dset ) ) + grid_spacing = list( group.attrs['gridSpacing'] ) + global_offset = list( group.attrs['gridGlobalOffset'] ) + # Slice selection + if slicing is not None: + # Get the integer that correspond to the slicing direction + list_slicing_index = [] + list_i_cell = [] + new_labels = axis_labels + for count, slicing_dir_item in enumerate(slicing_dir): + slicing_index = axis_labels.index(slicing_dir_item) + list_slicing_index.append(slicing_index) + # Number of cells along the slicing direction + n_cells = shape[ slicing_index ] + # Index of the slice (prevent stepping out of the array) + i_cell = int( 0.5 * (slicing[count] + 1.) * n_cells ) + i_cell = max( i_cell, 0 ) + i_cell = min( i_cell, n_cells - 1) + list_i_cell.append(i_cell) + + # Remove metainformation relative to the slicing index + # Successive pops starting from last element + list_indices_to_clean = list_slicing_index[:] + list_indices_to_clean.sort(reverse=True) + for index_to_clean in list_indices_to_clean: + shape.pop( index_to_clean ) + grid_spacing.pop( index_to_clean ) + global_offset.pop( index_to_clean ) + new_labels = new_labels[:index_to_clean] + \ + new_labels[index_to_clean + 1:] + + axes = { i: new_labels[i] for i in range(len(new_labels)) } + # Extraction of the data + F = get_data( dset, list_i_cell, list_slicing_index ) + info = FieldMetaInformation( axes, shape, grid_spacing, global_offset, + group.attrs['gridUnitSI'], dset.attrs['position'] ) + else: + F = get_data( dset ) + axes = { i: axis_labels[i] for i in range(len(axis_labels)) } + info = FieldMetaInformation( axes, F.shape, + group.attrs['gridSpacing'], group.attrs['gridGlobalOffset'], + group.attrs['gridUnitSI'], dset.attrs['position'] ) # Close the file dfile.close() return( F, info ) - def read_field_circ( filename, field_path, m=0, theta=0. ): """ Extract a given field from an HDF5 file in the openPMD format, diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 276cbe53..7bccc60e 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -348,7 +348,7 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, return(data_list) def get_field(self, field=None, coord=None, t=None, iteration=None, - m='all', theta=0., slicing=0., slicing_dir='y', + m='all', theta=0., slicing=None, slicing_dir=None, output=True, plot=False, plot_range=[[None, None], [None, None]], **kw): """ @@ -472,9 +472,14 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, F, info = read_field_1d(filename, field_path, axis_labels) # - For 2D elif geometry == "2dcartesian": - F, info = read_field_2d(filename, field_path, axis_labels) + F, info = read_field_2d( + filename, field_path, axis_labels, slicing, slicing_dir) # - For 3D elif geometry == "3dcartesian": + if slicing_dir == None: + slicing_dir = 'y' + if slicing == None: + slicing = 0. F, info = read_field_3d( filename, field_path, axis_labels, slicing, slicing_dir) # - For thetaMode From 4166ab05b7d6a4136ca51c838e837465db7778ce Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Fri, 4 May 2018 19:36:44 -0700 Subject: [PATCH 09/90] docstring and cleaning --- .../data_reader/field_reader.py | 29 +++++++++++++------ .../data_reader/utilities.py | 20 ++++++------- opmd_viewer/openpmd_timeseries/main.py | 25 +++++++++------- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 5d7d5b75..327b9e53 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -75,6 +75,18 @@ def read_field_2d( filename, field_path, axis_labels, axis_labels: list of strings The name of the dimensions of the array (e.g. ['x', 'y', 'z']) + slicing : float or list of float, optional + numbers between -1 and 1 that indicates where to slice the data, + along directions given in `slicing_dir` + -1 : lower edge of the simulation box + 0 : middle of the simulation box + 1 : upper edge of the simulation box + If slicing is None, the full 3D grid is returned. + + slicing_dir : str or list of str, optional + Direction along which to slice the data + Elements can be 'x' and/or 'z' + Returns ------- A tuple with @@ -91,7 +103,7 @@ def read_field_2d( filename, field_path, axis_labels, dfile = h5py.File( filename, 'r' ) # Extract the dataset and and corresponding group group, dset = find_dataset( dfile, field_path ) - + # Dimensions of the grid shape = list( get_shape( dset ) ) grid_spacing = list( group.attrs['gridSpacing'] ) @@ -112,7 +124,7 @@ def read_field_2d( filename, field_path, axis_labels, i_cell = max( i_cell, 0 ) i_cell = min( i_cell, n_cells - 1) list_i_cell.append(i_cell) - + # Remove metainformation relative to the slicing index # Successive pops starting from last element list_indices_to_clean = list_slicing_index[:] @@ -123,7 +135,7 @@ def read_field_2d( filename, field_path, axis_labels, global_offset.pop( index_to_clean ) new_labels = new_labels[:index_to_clean] + \ new_labels[index_to_clean + 1:] - + axes = { i: new_labels[i] for i in range(len(new_labels)) } # Extraction of the data F = get_data( dset, list_i_cell, list_slicing_index ) @@ -140,6 +152,7 @@ def read_field_2d( filename, field_path, axis_labels, dfile.close() return( F, info ) + def read_field_circ( filename, field_path, m=0, theta=0. ): """ Extract a given field from an HDF5 file in the openPMD format, @@ -237,7 +250,6 @@ def read_field_3d( filename, field_path, axis_labels, The name of the dimensions of the array (e.g. ['x', 'y', 'z']) slicing : float or list of float, optional - Only used for 3dcartesian geometry numbers between -1 and 1 that indicates where to slice the data, along directions given in `slicing_dir` -1 : lower edge of the simulation box @@ -246,9 +258,8 @@ def read_field_3d( filename, field_path, axis_labels, If slicing is None, the full 3D grid is returned. slicing_dir : str or list of str, optional - Only used for 3dcartesian geometry Direction along which to slice the data - Elements can be 'x', 'y' or 'z' + Elements can be 'x', 'y' and/or 'z' Returns ------- @@ -257,7 +268,7 @@ def read_field_3d( filename, field_path, axis_labels, info : a FieldMetaInformation object (contains information about the grid; see the corresponding docstring) """ - + if slicing is not None and not isinstance(slicing, list): slicing = [slicing] if slicing_dir is not None and not isinstance(slicing_dir, list): @@ -288,7 +299,7 @@ def read_field_3d( filename, field_path, axis_labels, i_cell = max( i_cell, 0 ) i_cell = min( i_cell, n_cells - 1) list_i_cell.append(i_cell) - + # Remove metainformation relative to the slicing index # Successive pops starting from last element list_indices_to_clean = list_slicing_index[:] @@ -299,7 +310,7 @@ def read_field_3d( filename, field_path, axis_labels, global_offset.pop( index_to_clean ) new_labels = new_labels[:index_to_clean] + \ new_labels[index_to_clean + 1:] - + axes = { i: new_labels[i] for i in range(len(new_labels)) } # Extraction of the data F = get_data( dset, list_i_cell, list_slicing_index ) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/utilities.py b/opmd_viewer/openpmd_timeseries/data_reader/utilities.py index 3ef33b3e..1c61729c 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/utilities.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/utilities.py @@ -60,11 +60,11 @@ def get_data(dset, i_slice=None, pos_slice=None, output_type=np.float64): The object from which the data is extracted pos_slice: int or list of int, optional - Direction of each slice. - When None, no slice is performed + Slice direction(s). + When None, no slicing is performed i_slice: int or list of int, optional - Indices of slices to be taken + Indices of slices to be taken. output_type: a numpy type The type to which the returned array should be converted @@ -76,11 +76,11 @@ def get_data(dset, i_slice=None, pos_slice=None, output_type=np.float64): # For back-compatibility: Convert pos_slice and i_slice to # single-element list if they are not lists (e.g. float # and int respectively). - if pos_slice is not None and not isinstance(pos_slice, list) : + if pos_slice is not None and not isinstance(pos_slice, list): pos_slice = [pos_slice] - if i_slice is not None and not isinstance(i_slice, list) : + if i_slice is not None and not isinstance(i_slice, list): i_slice = [i_slice] - + # Case of a constant dataset if isinstance(dset, h5py.Group): shape = dset.attrs['shape'] @@ -97,12 +97,10 @@ def get_data(dset, i_slice=None, pos_slice=None, output_type=np.float64): else: # Get largest element of pos_slice and its index max_pos = max(pos_slice) - ind_max_pos = pos_slice.index(max_pos) - # Create index list list_index of type - # [:, :, :, ...] where Ellipsis starts at ind_max_pos + 1 - length_list_index = max_pos + 2 + # Create index list list_index of type + # [:, :, :, ...] where Ellipsis starts at max_pos + 1 list_index = [np.s_[:]] * (max_pos + 2) - list_index[max_pos+1] = np.s_[...] + list_index[max_pos + 1] = np.s_[...] # Fill list_index with elements of i_slice for count, dir_index in enumerate(pos_slice): list_index[dir_index] = i_slice[count] diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 7bccc60e..5bdb58e3 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -383,19 +383,22 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, Only used for thetaMode geometry The angle of the plane of observation, with respect to the x axis - slicing : float, optional - Only used for 3dcartesian geometry - A number between -1 and 1 that indicates where to slice the data, - along the direction `slicing_dir` + slicing : float or list of float, optional + Numbers between -1 and 1 that indicate where to slice the data, + along the directions in `slicing_dir` -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box - If slicing is None, the full 3D grid is returned. + If slicing is None, the full grid is returned. + Default is None for 2D and 0 for 3d Cartesian - slicing_dir : str, optional - Only used for 3dcartesian geometry - The direction along which to slice the data - Either 'x', 'y' or 'z' + slicing_dir : str or list of str, optional + Direction along which to slice the data + Elements can be: + - 2d: 'x' and/or 'z' + - 3d: 'x', 'y' and/or 'z' + - 1d/circ: not implemented + Default is None for 2D and 'y' for 3d Cartesian output : bool, optional Whether to return the requested quantity @@ -476,9 +479,9 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, filename, field_path, axis_labels, slicing, slicing_dir) # - For 3D elif geometry == "3dcartesian": - if slicing_dir == None: + if slicing_dir is None: slicing_dir = 'y' - if slicing == None: + if slicing is None: slicing = 0. F, info = read_field_3d( filename, field_path, axis_labels, slicing, slicing_dir) From 0f8cead57cedfa24700d8d349d770aff2f18ad5f Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Fri, 4 May 2018 19:49:08 -0700 Subject: [PATCH 10/90] Minor cleaning for PR --- .../openpmd_timeseries/data_reader/field_reader.py | 12 ++++++------ .../openpmd_timeseries/data_reader/utilities.py | 6 +++--- opmd_viewer/openpmd_timeseries/main.py | 13 +++++++------ 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 327b9e53..d2b758dd 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -76,7 +76,7 @@ def read_field_2d( filename, field_path, axis_labels, The name of the dimensions of the array (e.g. ['x', 'y', 'z']) slicing : float or list of float, optional - numbers between -1 and 1 that indicates where to slice the data, + Number(s) between -1 and 1 that indicates where to slice the data, along directions given in `slicing_dir` -1 : lower edge of the simulation box 0 : middle of the simulation box @@ -84,7 +84,7 @@ def read_field_2d( filename, field_path, axis_labels, If slicing is None, the full 3D grid is returned. slicing_dir : str or list of str, optional - Direction along which to slice the data + Direction(s) along which to slice the data Elements can be 'x' and/or 'z' Returns @@ -126,7 +126,7 @@ def read_field_2d( filename, field_path, axis_labels, list_i_cell.append(i_cell) # Remove metainformation relative to the slicing index - # Successive pops starting from last element + # Successive pops starting from last coordinate to slice list_indices_to_clean = list_slicing_index[:] list_indices_to_clean.sort(reverse=True) for index_to_clean in list_indices_to_clean: @@ -250,7 +250,7 @@ def read_field_3d( filename, field_path, axis_labels, The name of the dimensions of the array (e.g. ['x', 'y', 'z']) slicing : float or list of float, optional - numbers between -1 and 1 that indicates where to slice the data, + number(s) between -1 and 1 that indicates where to slice the data, along directions given in `slicing_dir` -1 : lower edge of the simulation box 0 : middle of the simulation box @@ -258,7 +258,7 @@ def read_field_3d( filename, field_path, axis_labels, If slicing is None, the full 3D grid is returned. slicing_dir : str or list of str, optional - Direction along which to slice the data + Direction(s) along which to slice the data Elements can be 'x', 'y' and/or 'z' Returns @@ -301,7 +301,7 @@ def read_field_3d( filename, field_path, axis_labels, list_i_cell.append(i_cell) # Remove metainformation relative to the slicing index - # Successive pops starting from last element + # Successive pops starting from last coordinate to slice list_indices_to_clean = list_slicing_index[:] list_indices_to_clean.sort(reverse=True) for index_to_clean in list_indices_to_clean: diff --git a/opmd_viewer/openpmd_timeseries/data_reader/utilities.py b/opmd_viewer/openpmd_timeseries/data_reader/utilities.py index 1c61729c..94b12c99 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/utilities.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/utilities.py @@ -74,7 +74,7 @@ def get_data(dset, i_slice=None, pos_slice=None, output_type=np.float64): An np.ndarray (non-constant dataset) or a single double (constant dataset) """ # For back-compatibility: Convert pos_slice and i_slice to - # single-element list if they are not lists (e.g. float + # single-element lists if they are not lists (e.g. float # and int respectively). if pos_slice is not None and not isinstance(pos_slice, list): pos_slice = [pos_slice] @@ -95,9 +95,9 @@ def get_data(dset, i_slice=None, pos_slice=None, output_type=np.float64): if pos_slice is None: data = dset[...] else: - # Get largest element of pos_slice and its index + # Get largest element of pos_slice max_pos = max(pos_slice) - # Create index list list_index of type + # Create list of indices list_index of type # [:, :, :, ...] where Ellipsis starts at max_pos + 1 list_index = [np.s_[:]] * (max_pos + 2) list_index[max_pos + 1] = np.s_[...] diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 5bdb58e3..8669e81b 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -384,21 +384,22 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, The angle of the plane of observation, with respect to the x axis slicing : float or list of float, optional - Numbers between -1 and 1 that indicate where to slice the data, + Number(s) between -1 and 1 that indicate where to slice the data, along the directions in `slicing_dir` -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box If slicing is None, the full grid is returned. - Default is None for 2D and 0 for 3d Cartesian + Default is None for 2D and [0.] for 3d Cartesian slicing_dir : str or list of str, optional - Direction along which to slice the data + Direction(s) along which to slice the data Elements can be: - 2d: 'x' and/or 'z' - 3d: 'x', 'y' and/or 'z' - 1d/circ: not implemented - Default is None for 2D and 'y' for 3d Cartesian + Returned array is reduced by 1 dimension per slicing. + Default is None for 2D and ['y'] for 3d Cartesian output : bool, optional Whether to return the requested quantity @@ -480,9 +481,9 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, # - For 3D elif geometry == "3dcartesian": if slicing_dir is None: - slicing_dir = 'y' + slicing_dir = ['y'] if slicing is None: - slicing = 0. + slicing = [0.] F, info = read_field_3d( filename, field_path, axis_labels, slicing, slicing_dir) # - For thetaMode From 22ab33c745016b8e76d93b437b687ff936e8515e Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Mon, 7 May 2018 18:51:12 -0700 Subject: [PATCH 11/90] added check in read_field_2d so that slicing along y returns no error --- opmd_viewer/openpmd_timeseries/data_reader/field_reader.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index d2b758dd..ec49844f 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -94,6 +94,12 @@ def read_field_2d( filename, field_path, axis_labels, info : a FieldMetaInformation object (contains information about the grid; see the corresponding docstring) """ + # Simple check for backward compatibility + # The slider works and tests pass + if slicing_dir == 'y': + slicing = None + slicing_dir = None + if slicing is not None and not isinstance(slicing, list): slicing = [slicing] if slicing_dir is not None and not isinstance(slicing_dir, list): From 2731bcff45e7b2311f83d5f2a571aa511383f9a4 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Tue, 8 May 2018 08:38:38 -0700 Subject: [PATCH 12/90] back to y as default slicing_dir. clean slicing_dir if contains elements not in axis_label --- opmd_viewer/addons/pic/lpa_diagnostics.py | 29 ++++++++++++++----- .../data_reader/field_reader.py | 24 ++++++++------- opmd_viewer/openpmd_timeseries/main.py | 10 +++---- 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/opmd_viewer/addons/pic/lpa_diagnostics.py b/opmd_viewer/addons/pic/lpa_diagnostics.py index 7cfc5d59..d352633e 100644 --- a/opmd_viewer/addons/pic/lpa_diagnostics.py +++ b/opmd_viewer/addons/pic/lpa_diagnostics.py @@ -695,11 +695,16 @@ def get_spectrum( self, t=None, iteration=None, pol=None, if pol not in ['x', 'y']: raise ValueError('The `pol` argument is missing or erroneous.') if pol == 'x': - slicing_dir = 'y' theta = 0 else: - slicing_dir = 'x' theta = np.pi / 2. + if "3dcartesian" in self.avail_geom: + if pol == 'x': + slicing_dir = 'y' + else: + slicing_dir = 'x' + else: + slicing_dir = None # Get field data field, info = self.get_field( t=t, iteration=iteration, field='E', @@ -755,13 +760,18 @@ def get_a0( self, t=None, iteration=None, pol=None ): """ if pol not in ['x', 'y']: raise ValueError('The `pol` argument is missing or erroneous.') - if pol == 'x': - slicing_dir = 'y' theta = 0 else: - slicing_dir = 'x' theta = np.pi / 2. + if "3dcartesian" in self.avail_geom: + if pol == 'x': + slicing_dir = 'y' + else: + slicing_dir = 'x' + else: + slicing_dir = None + # Get the peak field from field envelope Emax = np.amax(self.get_laser_envelope(t=t, iteration=iteration, pol=pol, theta=theta, @@ -804,11 +814,16 @@ def get_ctau( self, t=None, iteration=None, pol=None, method='fit' ): if pol not in ['x', 'y']: raise ValueError('The `pol` argument is missing or erroneous.') if pol == 'x': - slicing_dir = 'y' theta = 0 else: - slicing_dir = 'x' theta = np.pi / 2. + if "3dcartesian" in self.avail_geom: + if pol == 'x': + slicing_dir = 'y' + else: + slicing_dir = 'x' + else: + slicing_dir = None # Get the field envelope E, info = self.get_laser_envelope(t=t, iteration=iteration, pol=pol, theta=theta, diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index ec49844f..4e1680b9 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -94,16 +94,14 @@ def read_field_2d( filename, field_path, axis_labels, info : a FieldMetaInformation object (contains information about the grid; see the corresponding docstring) """ - # Simple check for backward compatibility - # The slider works and tests pass - if slicing_dir == 'y': - slicing = None - slicing_dir = None - + # Convert slicing and slicing_dir to lists if slicing is not None and not isinstance(slicing, list): slicing = [slicing] if slicing_dir is not None and not isinstance(slicing_dir, list): slicing_dir = [slicing_dir] + # slicing_dir is the intersection of slicing_dir with axis_labels + if slicing_dir is not None: + slicing_dir = [value for value in slicing_dir if value in axis_labels] # Open the HDF5 file dfile = h5py.File( filename, 'r' ) @@ -115,7 +113,7 @@ def read_field_2d( filename, field_path, axis_labels, grid_spacing = list( group.attrs['gridSpacing'] ) global_offset = list( group.attrs['gridGlobalOffset'] ) # Slice selection - if slicing is not None: + if slicing_dir is not None: # Get the integer that correspond to the slicing direction list_slicing_index = [] list_i_cell = [] @@ -274,12 +272,17 @@ def read_field_3d( filename, field_path, axis_labels, info : a FieldMetaInformation object (contains information about the grid; see the corresponding docstring) """ - + # Convert slicing and slicing_dir to lists if slicing is not None and not isinstance(slicing, list): slicing = [slicing] if slicing_dir is not None and not isinstance(slicing_dir, list): slicing_dir = [slicing_dir] - + # slicing_dir is the intersection of slicing_dir with axis_labels + if slicing_dir is not None: + slicing_dir = [value for value in slicing_dir if value in axis_labels] + # Need to: + # - Do a similar thing for slicing + # - Test if list is empty, and replace with None # Open the HDF5 file dfile = h5py.File( filename, 'r' ) # Extract the dataset and and corresponding group @@ -289,8 +292,9 @@ def read_field_3d( filename, field_path, axis_labels, shape = list( get_shape( dset ) ) grid_spacing = list( group.attrs['gridSpacing'] ) global_offset = list( group.attrs['gridGlobalOffset'] ) + # Slice selection - if slicing is not None: + if slicing_dir is not None: # Get the integer that correspond to the slicing direction list_slicing_index = [] list_i_cell = [] diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 8669e81b..d08837f7 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -348,7 +348,7 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, return(data_list) def get_field(self, field=None, coord=None, t=None, iteration=None, - m='all', theta=0., slicing=None, slicing_dir=None, + m='all', theta=0., slicing=0., slicing_dir='y', output=True, plot=False, plot_range=[[None, None], [None, None]], **kw): """ @@ -476,14 +476,14 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, F, info = read_field_1d(filename, field_path, axis_labels) # - For 2D elif geometry == "2dcartesian": + # This should be removed at some point + if slicing_dir is 'y': + slicing_dir = None + slicing = None F, info = read_field_2d( filename, field_path, axis_labels, slicing, slicing_dir) # - For 3D elif geometry == "3dcartesian": - if slicing_dir is None: - slicing_dir = ['y'] - if slicing is None: - slicing = [0.] F, info = read_field_3d( filename, field_path, axis_labels, slicing, slicing_dir) # - For thetaMode From fad40cfbf0ae90d2b7473b13fd81d7d3019d24e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxence=20Th=C3=A9venet?= Date: Tue, 8 May 2018 10:03:06 -0700 Subject: [PATCH 13/90] cleaning for 2D and 3D --- .../data_reader/field_reader.py | 25 ++++++++++++------- opmd_viewer/openpmd_timeseries/main.py | 4 --- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 4e1680b9..51bdc651 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -99,9 +99,13 @@ def read_field_2d( filename, field_path, axis_labels, slicing = [slicing] if slicing_dir is not None and not isinstance(slicing_dir, list): slicing_dir = [slicing_dir] - # slicing_dir is the intersection of slicing_dir with axis_labels + # Pop slicing directions in arguments that are not in axis_label if slicing_dir is not None: - slicing_dir = [value for value in slicing_dir if value in axis_labels] + ind_to_pop = [slicing_dir.index(val) for val in slicing_dir if + val not in axis_labels ] + for ind in ind_to_pop: + slicing_dir.pop(ind) + slicing.pop(ind) # Open the HDF5 file dfile = h5py.File( filename, 'r' ) @@ -112,8 +116,9 @@ def read_field_2d( filename, field_path, axis_labels, shape = list( get_shape( dset ) ) grid_spacing = list( group.attrs['gridSpacing'] ) global_offset = list( group.attrs['gridGlobalOffset'] ) + # Slice selection - if slicing_dir is not None: + if slicing_dir: # Get the integer that correspond to the slicing direction list_slicing_index = [] list_i_cell = [] @@ -277,12 +282,14 @@ def read_field_3d( filename, field_path, axis_labels, slicing = [slicing] if slicing_dir is not None and not isinstance(slicing_dir, list): slicing_dir = [slicing_dir] - # slicing_dir is the intersection of slicing_dir with axis_labels + # Pop slicing directions in arguments that are not in axis_label if slicing_dir is not None: - slicing_dir = [value for value in slicing_dir if value in axis_labels] - # Need to: - # - Do a similar thing for slicing - # - Test if list is empty, and replace with None + ind_to_pop = [slicing_dir.index(val) for val in slicing_dir if + val not in axis_labels ] + for ind in ind_to_pop: + slicing_dir.pop(ind) + slicing.pop(ind) + # Open the HDF5 file dfile = h5py.File( filename, 'r' ) # Extract the dataset and and corresponding group @@ -294,7 +301,7 @@ def read_field_3d( filename, field_path, axis_labels, global_offset = list( group.attrs['gridGlobalOffset'] ) # Slice selection - if slicing_dir is not None: + if slicing_dir: # Get the integer that correspond to the slicing direction list_slicing_index = [] list_i_cell = [] diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index d08837f7..50fd809f 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -476,10 +476,6 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, F, info = read_field_1d(filename, field_path, axis_labels) # - For 2D elif geometry == "2dcartesian": - # This should be removed at some point - if slicing_dir is 'y': - slicing_dir = None - slicing = None F, info = read_field_2d( filename, field_path, axis_labels, slicing, slicing_dir) # - For 3D From 2d4ed40f59e98320270b7bf2db473f31520d554e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxence=20Th=C3=A9venet?= Date: Tue, 8 May 2018 11:05:20 -0700 Subject: [PATCH 14/90] replace function read_field_1d,2d,3d with read_field_cartesian. Now slicing works in 1d, 2d 3d --- .../openpmd_timeseries/cython_function.c | 9297 +++++++++++++++++ ...n_function.cpython-36m-x86_64-linux-gnu.so | Bin 0 -> 301032 bytes .../data_reader/field_reader.py | 160 +- opmd_viewer/openpmd_timeseries/main.py | 13 +- 4 files changed, 9307 insertions(+), 163 deletions(-) create mode 100644 opmd_viewer/openpmd_timeseries/cython_function.c create mode 100755 opmd_viewer/openpmd_timeseries/cython_function.cpython-36m-x86_64-linux-gnu.so diff --git a/opmd_viewer/openpmd_timeseries/cython_function.c b/opmd_viewer/openpmd_timeseries/cython_function.c new file mode 100644 index 00000000..4f9fc0fa --- /dev/null +++ b/opmd_viewer/openpmd_timeseries/cython_function.c @@ -0,0 +1,9297 @@ +/* Generated by Cython 0.27.3 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "depends": [], + "name": "opmd_viewer.openpmd_timeseries.cython_function", + "sources": [ + "opmd_viewer/openpmd_timeseries/cython_function.pyx" + ] + }, + "module_name": "opmd_viewer.openpmd_timeseries.cython_function" +} +END: Cython Metadata */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.6+ or Python 3.3+. +#else +#define CYTHON_ABI "0_27_3" +#define CYTHON_FUTURE_DIVISION 0 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #if PY_VERSION_HEX >= 0x02070000 + #define HAVE_LONG_LONG + #endif +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#ifdef PYPY_VERSION + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 +#elif defined(PYSTON_VERSION) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLONG_INTERNALS) + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT (0 && PY_VERSION_HEX >= 0x03050000) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #include "longintrepr.h" + #undef SHIFT + #undef BASE + #undef MASK +#endif +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #define Py_OptimizeFlag 0 +#endif +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyClass_Type +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyType_Type +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#if PY_VERSION_HEX < 0x030700A0 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject **args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject **args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #define __Pyx_PyCFunctionFast _PyCFunctionFast + #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords +#endif +#if CYTHON_FAST_PYCCALL +#define __Pyx_PyFastCFunction_Check(func)\ + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))))) +#else +#define __Pyx_PyFastCFunction_Check(func) 0 +#endif +#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) + #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_PYSTON + #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) +#endif +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t PyInt_AsLong +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func)) +#else + #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int32 uint32_t; + #endif + #endif +#else + #include +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) && __cplusplus >= 201103L + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #elif __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__ ) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif + +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +#if defined(WIN32) || defined(MS_WINDOWS) + #define _USE_MATH_DEFINES +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + + +#define __PYX_ERR(f_index, lineno, Ln_error) \ +{ \ + __pyx_filename = __pyx_f[f_index]; __pyx_lineno = lineno; __pyx_clineno = __LINE__; goto Ln_error; \ +} + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__opmd_viewer__openpmd_timeseries__cython_function +#define __PYX_HAVE_API__opmd_viewer__openpmd_timeseries__cython_function +#include +#include +#include "numpy/arrayobject.h" +#include "numpy/ufuncobject.h" +#include +#include "pythread.h" +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0 +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +#define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False)) +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +static PyObject *__pyx_m = NULL; +static PyObject *__pyx_d; +static PyObject *__pyx_b; +static PyObject *__pyx_cython_runtime; +static PyObject *__pyx_empty_tuple; +static PyObject *__pyx_empty_bytes; +static PyObject *__pyx_empty_unicode; +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm= __FILE__; +static const char *__pyx_filename; + +/* Header.proto */ +#if !defined(CYTHON_CCOMPLEX) + #if defined(__cplusplus) + #define CYTHON_CCOMPLEX 1 + #elif defined(_Complex_I) + #define CYTHON_CCOMPLEX 1 + #else + #define CYTHON_CCOMPLEX 0 + #endif +#endif +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #include + #else + #include + #endif +#endif +#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) + #undef _Complex_I + #define _Complex_I 1.0fj +#endif + + +static const char *__pyx_f[] = { + "opmd_viewer/openpmd_timeseries/cython_function.pyx", + "__init__.pxd", + "type.pxd", + "bool.pxd", + "complex.pxd", +}; +/* BufferFormatStructs.proto */ +#define IS_UNSIGNED(type) (((type) -1) > 0) +struct __Pyx_StructField_; +#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0) +typedef struct { + const char* name; + struct __Pyx_StructField_* fields; + size_t size; + size_t arraysize[8]; + int ndim; + char typegroup; + char is_unsigned; + int flags; +} __Pyx_TypeInfo; +typedef struct __Pyx_StructField_ { + __Pyx_TypeInfo* type; + const char* name; + size_t offset; +} __Pyx_StructField; +typedef struct { + __Pyx_StructField* field; + size_t parent_offset; +} __Pyx_BufFmt_StackElem; +typedef struct { + __Pyx_StructField root; + __Pyx_BufFmt_StackElem* head; + size_t fmt_offset; + size_t new_count, enc_count; + size_t struct_alignment; + int is_complex; + char enc_type; + char new_packmode; + char enc_packmode; + char is_valid_array; +} __Pyx_BufFmt_Context; + + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":743 + * # in Cython to enable them only on the right systems. + * + * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t + */ +typedef npy_int8 __pyx_t_5numpy_int8_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":744 + * + * ctypedef npy_int8 int8_t + * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< + * ctypedef npy_int32 int32_t + * ctypedef npy_int64 int64_t + */ +typedef npy_int16 __pyx_t_5numpy_int16_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":745 + * ctypedef npy_int8 int8_t + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< + * ctypedef npy_int64 int64_t + * #ctypedef npy_int96 int96_t + */ +typedef npy_int32 __pyx_t_5numpy_int32_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":746 + * ctypedef npy_int16 int16_t + * ctypedef npy_int32 int32_t + * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< + * #ctypedef npy_int96 int96_t + * #ctypedef npy_int128 int128_t + */ +typedef npy_int64 __pyx_t_5numpy_int64_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":750 + * #ctypedef npy_int128 int128_t + * + * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t + */ +typedef npy_uint8 __pyx_t_5numpy_uint8_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":751 + * + * ctypedef npy_uint8 uint8_t + * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< + * ctypedef npy_uint32 uint32_t + * ctypedef npy_uint64 uint64_t + */ +typedef npy_uint16 __pyx_t_5numpy_uint16_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":752 + * ctypedef npy_uint8 uint8_t + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< + * ctypedef npy_uint64 uint64_t + * #ctypedef npy_uint96 uint96_t + */ +typedef npy_uint32 __pyx_t_5numpy_uint32_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":753 + * ctypedef npy_uint16 uint16_t + * ctypedef npy_uint32 uint32_t + * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< + * #ctypedef npy_uint96 uint96_t + * #ctypedef npy_uint128 uint128_t + */ +typedef npy_uint64 __pyx_t_5numpy_uint64_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":757 + * #ctypedef npy_uint128 uint128_t + * + * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< + * ctypedef npy_float64 float64_t + * #ctypedef npy_float80 float80_t + */ +typedef npy_float32 __pyx_t_5numpy_float32_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":758 + * + * ctypedef npy_float32 float32_t + * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< + * #ctypedef npy_float80 float80_t + * #ctypedef npy_float128 float128_t + */ +typedef npy_float64 __pyx_t_5numpy_float64_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":767 + * # The int types are mapped a bit surprising -- + * # numpy.int corresponds to 'l' and numpy.long to 'q' + * ctypedef npy_long int_t # <<<<<<<<<<<<<< + * ctypedef npy_longlong long_t + * ctypedef npy_longlong longlong_t + */ +typedef npy_long __pyx_t_5numpy_int_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":768 + * # numpy.int corresponds to 'l' and numpy.long to 'q' + * ctypedef npy_long int_t + * ctypedef npy_longlong long_t # <<<<<<<<<<<<<< + * ctypedef npy_longlong longlong_t + * + */ +typedef npy_longlong __pyx_t_5numpy_long_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":769 + * ctypedef npy_long int_t + * ctypedef npy_longlong long_t + * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< + * + * ctypedef npy_ulong uint_t + */ +typedef npy_longlong __pyx_t_5numpy_longlong_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":771 + * ctypedef npy_longlong longlong_t + * + * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<< + * ctypedef npy_ulonglong ulong_t + * ctypedef npy_ulonglong ulonglong_t + */ +typedef npy_ulong __pyx_t_5numpy_uint_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":772 + * + * ctypedef npy_ulong uint_t + * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<< + * ctypedef npy_ulonglong ulonglong_t + * + */ +typedef npy_ulonglong __pyx_t_5numpy_ulong_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":773 + * ctypedef npy_ulong uint_t + * ctypedef npy_ulonglong ulong_t + * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< + * + * ctypedef npy_intp intp_t + */ +typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":775 + * ctypedef npy_ulonglong ulonglong_t + * + * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< + * ctypedef npy_uintp uintp_t + * + */ +typedef npy_intp __pyx_t_5numpy_intp_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":776 + * + * ctypedef npy_intp intp_t + * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< + * + * ctypedef npy_double float_t + */ +typedef npy_uintp __pyx_t_5numpy_uintp_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":778 + * ctypedef npy_uintp uintp_t + * + * ctypedef npy_double float_t # <<<<<<<<<<<<<< + * ctypedef npy_double double_t + * ctypedef npy_longdouble longdouble_t + */ +typedef npy_double __pyx_t_5numpy_float_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":779 + * + * ctypedef npy_double float_t + * ctypedef npy_double double_t # <<<<<<<<<<<<<< + * ctypedef npy_longdouble longdouble_t + * + */ +typedef npy_double __pyx_t_5numpy_double_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":780 + * ctypedef npy_double float_t + * ctypedef npy_double double_t + * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< + * + * ctypedef npy_cfloat cfloat_t + */ +typedef npy_longdouble __pyx_t_5numpy_longdouble_t; +/* Declarations.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + typedef ::std::complex< float > __pyx_t_float_complex; + #else + typedef float _Complex __pyx_t_float_complex; + #endif +#else + typedef struct { float real, imag; } __pyx_t_float_complex; +#endif +static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float); + +/* Declarations.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + typedef ::std::complex< double > __pyx_t_double_complex; + #else + typedef double _Complex __pyx_t_double_complex; + #endif +#else + typedef struct { double real, imag; } __pyx_t_double_complex; +#endif +static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); + + +/*--- Type declarations ---*/ + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":782 + * ctypedef npy_longdouble longdouble_t + * + * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<< + * ctypedef npy_cdouble cdouble_t + * ctypedef npy_clongdouble clongdouble_t + */ +typedef npy_cfloat __pyx_t_5numpy_cfloat_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":783 + * + * ctypedef npy_cfloat cfloat_t + * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<< + * ctypedef npy_clongdouble clongdouble_t + * + */ +typedef npy_cdouble __pyx_t_5numpy_cdouble_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":784 + * ctypedef npy_cfloat cfloat_t + * ctypedef npy_cdouble cdouble_t + * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<< + * + * ctypedef npy_cdouble complex_t + */ +typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t; + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":786 + * ctypedef npy_clongdouble clongdouble_t + * + * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew1(a): + */ +typedef npy_cdouble __pyx_t_5numpy_complex_t; + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, int); + void (*DECREF)(void*, PyObject*, int); + void (*GOTREF)(void*, PyObject*, int); + void (*GIVEREF)(void*, PyObject*, int); + void* (*SetupContext)(const char*, int, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) +#endif + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ + const char* function_name); + +/* ArgTypeTest.proto */ +#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ + ((likely((Py_TYPE(obj) == type) | (none_allowed && (obj == Py_None)))) ? 1 :\ + __Pyx__ArgTypeTest(obj, type, name, exact)) +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); + +/* IsLittleEndian.proto */ +static CYTHON_INLINE int __Pyx_Is_Little_Endian(void); + +/* BufferFormatCheck.proto */ +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts); +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type); + +/* BufferGetAndValidate.proto */ +#define __Pyx_GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)\ + ((obj == Py_None || obj == NULL) ?\ + (__Pyx_ZeroBuffer(buf), 0) :\ + __Pyx__GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)) +static int __Pyx__GetBufferAndValidate(Py_buffer* buf, PyObject* obj, + __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); +static void __Pyx_ZeroBuffer(Py_buffer* buf); +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); +static Py_ssize_t __Pyx_minusones[] = { -1, -1, -1, -1, -1, -1, -1, -1 }; +static Py_ssize_t __Pyx_zeros[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +#define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0) +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* GetModuleGlobalName.proto */ +static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* GetItemInt.proto */ +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ + __Pyx_GetItemInt_Generic(o, to_py_func(i)))) +#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, + int is_list, int wraparound, int boundscheck); + +/* SetItemInt.proto */ +#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) :\ + __Pyx_SetItemInt_Generic(o, to_py_func(i), v))) +static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v); +static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, + int is_list, int wraparound, int boundscheck); + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* DictGetItem.proto */ +#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY +static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { + PyObject *value; + value = PyDict_GetItemWithError(d, key); + if (unlikely(!value)) { + if (!PyErr_Occurred()) { + PyObject* args = PyTuple_Pack(1, key); + if (likely(args)) + PyErr_SetObject(PyExc_KeyError, args); + Py_XDECREF(args); + } + return NULL; + } + Py_INCREF(value); + return value; +} +#else + #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) +#endif + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* RaiseNoneIterError.proto */ +static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); + +/* ExtTypeTest.proto */ +static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* PyErrExceptionMatches.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* BufferStructDeclare.proto */ +typedef struct { + Py_ssize_t shape, strides, suboffsets; +} __Pyx_Buf_DimInfo; +typedef struct { + size_t refcount; + Py_buffer pybuffer; +} __Pyx_Buffer; +typedef struct { + __Pyx_Buffer *rcbuffer; + char *data; + __Pyx_Buf_DimInfo diminfo[8]; +} __Pyx_LocalBuf_ND; + +#if PY_MAJOR_VERSION < 3 + static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); + static void __Pyx_ReleaseBuffer(Py_buffer *view); +#else + #define __Pyx_GetBuffer PyObject_GetBuffer + #define __Pyx_ReleaseBuffer PyBuffer_Release +#endif + + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* RealImag.proto */ +#if CYTHON_CCOMPLEX + #ifdef __cplusplus + #define __Pyx_CREAL(z) ((z).real()) + #define __Pyx_CIMAG(z) ((z).imag()) + #else + #define __Pyx_CREAL(z) (__real__(z)) + #define __Pyx_CIMAG(z) (__imag__(z)) + #endif +#else + #define __Pyx_CREAL(z) ((z).real) + #define __Pyx_CIMAG(z) ((z).imag) +#endif +#if defined(__cplusplus) && CYTHON_CCOMPLEX\ + && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) + #define __Pyx_SET_CREAL(z,x) ((z).real(x)) + #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) +#else + #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) + #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) +#endif + +/* Arithmetic.proto */ +#if CYTHON_CCOMPLEX + #define __Pyx_c_eq_float(a, b) ((a)==(b)) + #define __Pyx_c_sum_float(a, b) ((a)+(b)) + #define __Pyx_c_diff_float(a, b) ((a)-(b)) + #define __Pyx_c_prod_float(a, b) ((a)*(b)) + #define __Pyx_c_quot_float(a, b) ((a)/(b)) + #define __Pyx_c_neg_float(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zero_float(z) ((z)==(float)0) + #define __Pyx_c_conj_float(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_abs_float(z) (::std::abs(z)) + #define __Pyx_c_pow_float(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zero_float(z) ((z)==0) + #define __Pyx_c_conj_float(z) (conjf(z)) + #if 1 + #define __Pyx_c_abs_float(z) (cabsf(z)) + #define __Pyx_c_pow_float(a, b) (cpowf(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex, __pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex); + static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex); + #if 1 + static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex); + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex, __pyx_t_float_complex); + #endif +#endif + +/* Arithmetic.proto */ +#if CYTHON_CCOMPLEX + #define __Pyx_c_eq_double(a, b) ((a)==(b)) + #define __Pyx_c_sum_double(a, b) ((a)+(b)) + #define __Pyx_c_diff_double(a, b) ((a)-(b)) + #define __Pyx_c_prod_double(a, b) ((a)*(b)) + #define __Pyx_c_quot_double(a, b) ((a)/(b)) + #define __Pyx_c_neg_double(a) (-(a)) + #ifdef __cplusplus + #define __Pyx_c_is_zero_double(z) ((z)==(double)0) + #define __Pyx_c_conj_double(z) (::std::conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (::std::abs(z)) + #define __Pyx_c_pow_double(a, b) (::std::pow(a, b)) + #endif + #else + #define __Pyx_c_is_zero_double(z) ((z)==0) + #define __Pyx_c_conj_double(z) (conj(z)) + #if 1 + #define __Pyx_c_abs_double(z) (cabs(z)) + #define __Pyx_c_pow_double(a, b) (cpow(a, b)) + #endif + #endif +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex, __pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex); + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex); + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex); + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex, __pyx_t_double_complex); + #endif +#endif + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(void); + +/* PyIdentifierFromString.proto */ +#if !defined(__Pyx_PyIdentifier_FromString) +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s) +#else + #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s) +#endif +#endif + +/* ModuleImport.proto */ +static PyObject *__Pyx_ImportModule(const char *name); + +/* TypeImport.proto */ +static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + + +/* Module declarations from 'cpython.buffer' */ + +/* Module declarations from 'libc.string' */ + +/* Module declarations from 'libc.stdio' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.type' */ +static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; + +/* Module declarations from 'cpython.version' */ + +/* Module declarations from 'cpython.exc' */ + +/* Module declarations from 'cpython.module' */ + +/* Module declarations from 'cpython.mem' */ + +/* Module declarations from 'cpython.tuple' */ + +/* Module declarations from 'cpython.list' */ + +/* Module declarations from 'cpython.sequence' */ + +/* Module declarations from 'cpython.mapping' */ + +/* Module declarations from 'cpython.iterator' */ + +/* Module declarations from 'cpython.number' */ + +/* Module declarations from 'cpython.int' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.bool' */ +static PyTypeObject *__pyx_ptype_7cpython_4bool_bool = 0; + +/* Module declarations from 'cpython.long' */ + +/* Module declarations from 'cpython.float' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.complex' */ +static PyTypeObject *__pyx_ptype_7cpython_7complex_complex = 0; + +/* Module declarations from 'cpython.string' */ + +/* Module declarations from 'cpython.unicode' */ + +/* Module declarations from 'cpython.dict' */ + +/* Module declarations from 'cpython.instance' */ + +/* Module declarations from 'cpython.function' */ + +/* Module declarations from 'cpython.method' */ + +/* Module declarations from 'cpython.weakref' */ + +/* Module declarations from 'cpython.getargs' */ + +/* Module declarations from 'cpython.pythread' */ + +/* Module declarations from 'cpython.pystate' */ + +/* Module declarations from 'cpython.cobject' */ + +/* Module declarations from 'cpython.oldbuffer' */ + +/* Module declarations from 'cpython.set' */ + +/* Module declarations from 'cpython.bytes' */ + +/* Module declarations from 'cpython.pycapsule' */ + +/* Module declarations from 'cpython' */ + +/* Module declarations from 'cpython.object' */ + +/* Module declarations from 'cpython.ref' */ + +/* Module declarations from 'numpy' */ + +/* Module declarations from 'numpy' */ +static PyTypeObject *__pyx_ptype_5numpy_dtype = 0; +static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0; +static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0; +static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0; +static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0; +static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/ + +/* Module declarations from 'cython' */ + +/* Module declarations from 'libc.math' */ + +/* Module declarations from 'opmd_viewer.openpmd_timeseries.cython_function' */ +static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t = { "int64_t", NULL, sizeof(__pyx_t_5numpy_int64_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int64_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int64_t), 0 }; +static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t = { "uint64_t", NULL, sizeof(__pyx_t_5numpy_uint64_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_uint64_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_uint64_t), 0 }; +static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t = { "float64_t", NULL, sizeof(__pyx_t_5numpy_float64_t), { 0 }, 0, 'R', 0, 0 }; +#define __Pyx_MODULE_NAME "opmd_viewer.openpmd_timeseries.cython_function" +extern int __pyx_module_is_main_opmd_viewer__openpmd_timeseries__cython_function; +int __pyx_module_is_main_opmd_viewer__openpmd_timeseries__cython_function = 0; + +/* Implementation of 'opmd_viewer.openpmd_timeseries.cython_function' */ +static PyObject *__pyx_builtin_xrange; +static PyObject *__pyx_builtin_ValueError; +static PyObject *__pyx_builtin_range; +static PyObject *__pyx_builtin_RuntimeError; +static PyObject *__pyx_builtin_ImportError; +static const char __pyx_k_N[] = "N"; +static const char __pyx_k_i[] = "i"; +static const char __pyx_k_w[] = "w"; +static const char __pyx_k_np[] = "np"; +static const char __pyx_k_q1[] = "q1"; +static const char __pyx_k_q2[] = "q2"; +static const char __pyx_k_pid[] = "pid"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_S_low[] = "S_low"; +static const char __pyx_k_dtype[] = "dtype"; +static const char __pyx_k_nbins[] = "nbins"; +static const char __pyx_k_numpy[] = "numpy"; +static const char __pyx_k_range[] = "range"; +static const char __pyx_k_zeros[] = "zeros"; +static const char __pyx_k_S1_low[] = "S1_low"; +static const char __pyx_k_S2_low[] = "S2_low"; +static const char __pyx_k_i_fill[] = "i_fill"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_n_ptcl[] = "n_ptcl"; +static const char __pyx_k_xrange[] = "xrange"; +static const char __pyx_k_float64[] = "float64"; +static const char __pyx_k_nbins_1[] = "nbins_1"; +static const char __pyx_k_nbins_2[] = "nbins_2"; +static const char __pyx_k_q1_cell[] = "q1_cell"; +static const char __pyx_k_q2_cell[] = "q2_cell"; +static const char __pyx_k_bins_end[] = "bins_end"; +static const char __pyx_k_i_select[] = "i_select"; +static const char __pyx_k_hist_data[] = "hist_data"; +static const char __pyx_k_i_low_bin[] = "i_low_bin"; +static const char __pyx_k_N_selected[] = "N_selected"; +static const char __pyx_k_ValueError[] = "ValueError"; +static const char __pyx_k_bins_end_1[] = "bins_end_1"; +static const char __pyx_k_bins_end_2[] = "bins_end_2"; +static const char __pyx_k_bins_start[] = "bins_start"; +static const char __pyx_k_i1_low_bin[] = "i1_low_bin"; +static const char __pyx_k_i2_low_bin[] = "i2_low_bin"; +static const char __pyx_k_ImportError[] = "ImportError"; +static const char __pyx_k_bin_spacing[] = "bin_spacing"; +static const char __pyx_k_inv_spacing[] = "inv_spacing"; +static const char __pyx_k_RuntimeError[] = "RuntimeError"; +static const char __pyx_k_bins_start_1[] = "bins_start_1"; +static const char __pyx_k_bins_start_2[] = "bins_start_2"; +static const char __pyx_k_selected_pid[] = "selected_pid"; +static const char __pyx_k_bin_spacing_1[] = "bin_spacing_1"; +static const char __pyx_k_bin_spacing_2[] = "bin_spacing_2"; +static const char __pyx_k_inv_spacing_1[] = "inv_spacing_1"; +static const char __pyx_k_inv_spacing_2[] = "inv_spacing_2"; +static const char __pyx_k_histogram_cic_1d[] = "histogram_cic_1d"; +static const char __pyx_k_histogram_cic_2d[] = "histogram_cic_2d"; +static const char __pyx_k_original_indices[] = "original_indices"; +static const char __pyx_k_selected_indices[] = "selected_indices"; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_extract_indices_cython[] = "extract_indices_cython"; +static const char __pyx_k_preserve_particle_index[] = "preserve_particle_index"; +static const char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous"; +static const char __pyx_k_numpy_core_multiarray_failed_to[] = "numpy.core.multiarray failed to import"; +static const char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)"; +static const char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd"; +static const char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported"; +static const char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous"; +static const char __pyx_k_numpy_core_umath_failed_to_impor[] = "numpy.core.umath failed to import"; +static const char __pyx_k_opmd_viewer_openpmd_timeseries_c[] = "opmd_viewer/openpmd_timeseries/cython_function.pyx"; +static const char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short."; +static const char __pyx_k_opmd_viewer_openpmd_timeseries_c_2[] = "opmd_viewer.openpmd_timeseries.cython_function"; +static PyObject *__pyx_kp_u_Format_string_allocated_too_shor; +static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2; +static PyObject *__pyx_n_s_ImportError; +static PyObject *__pyx_n_s_N; +static PyObject *__pyx_n_s_N_selected; +static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor; +static PyObject *__pyx_n_s_RuntimeError; +static PyObject *__pyx_n_s_S1_low; +static PyObject *__pyx_n_s_S2_low; +static PyObject *__pyx_n_s_S_low; +static PyObject *__pyx_n_s_ValueError; +static PyObject *__pyx_n_s_bin_spacing; +static PyObject *__pyx_n_s_bin_spacing_1; +static PyObject *__pyx_n_s_bin_spacing_2; +static PyObject *__pyx_n_s_bins_end; +static PyObject *__pyx_n_s_bins_end_1; +static PyObject *__pyx_n_s_bins_end_2; +static PyObject *__pyx_n_s_bins_start; +static PyObject *__pyx_n_s_bins_start_1; +static PyObject *__pyx_n_s_bins_start_2; +static PyObject *__pyx_n_s_cline_in_traceback; +static PyObject *__pyx_n_s_dtype; +static PyObject *__pyx_n_s_extract_indices_cython; +static PyObject *__pyx_n_s_float64; +static PyObject *__pyx_n_s_hist_data; +static PyObject *__pyx_n_s_histogram_cic_1d; +static PyObject *__pyx_n_s_histogram_cic_2d; +static PyObject *__pyx_n_s_i; +static PyObject *__pyx_n_s_i1_low_bin; +static PyObject *__pyx_n_s_i2_low_bin; +static PyObject *__pyx_n_s_i_fill; +static PyObject *__pyx_n_s_i_low_bin; +static PyObject *__pyx_n_s_i_select; +static PyObject *__pyx_n_s_import; +static PyObject *__pyx_n_s_inv_spacing; +static PyObject *__pyx_n_s_inv_spacing_1; +static PyObject *__pyx_n_s_inv_spacing_2; +static PyObject *__pyx_n_s_main; +static PyObject *__pyx_n_s_n_ptcl; +static PyObject *__pyx_n_s_nbins; +static PyObject *__pyx_n_s_nbins_1; +static PyObject *__pyx_n_s_nbins_2; +static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous; +static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou; +static PyObject *__pyx_n_s_np; +static PyObject *__pyx_n_s_numpy; +static PyObject *__pyx_kp_s_numpy_core_multiarray_failed_to; +static PyObject *__pyx_kp_s_numpy_core_umath_failed_to_impor; +static PyObject *__pyx_kp_s_opmd_viewer_openpmd_timeseries_c; +static PyObject *__pyx_n_s_opmd_viewer_openpmd_timeseries_c_2; +static PyObject *__pyx_n_s_original_indices; +static PyObject *__pyx_n_s_pid; +static PyObject *__pyx_n_s_preserve_particle_index; +static PyObject *__pyx_n_s_q1; +static PyObject *__pyx_n_s_q1_cell; +static PyObject *__pyx_n_s_q2; +static PyObject *__pyx_n_s_q2_cell; +static PyObject *__pyx_n_s_range; +static PyObject *__pyx_n_s_selected_indices; +static PyObject *__pyx_n_s_selected_pid; +static PyObject *__pyx_n_s_test; +static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd; +static PyObject *__pyx_n_s_w; +static PyObject *__pyx_n_s_xrange; +static PyObject *__pyx_n_s_zeros; +static PyObject *__pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_extract_indices_cython(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_original_indices, PyArrayObject *__pyx_v_selected_indices, PyArrayObject *__pyx_v_pid, PyArrayObject *__pyx_v_selected_pid, PyBoolObject *__pyx_v_preserve_particle_index); /* proto */ +static PyObject *__pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_2histogram_cic_1d(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_q1, PyArrayObject *__pyx_v_w, int __pyx_v_nbins, double __pyx_v_bins_start, double __pyx_v_bins_end); /* proto */ +static PyObject *__pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_4histogram_cic_2d(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_q1, PyArrayObject *__pyx_v_q2, PyArrayObject *__pyx_v_w, int __pyx_v_nbins_1, double __pyx_v_bins_start_1, double __pyx_v_bins_end_1, int __pyx_v_nbins_2, double __pyx_v_bins_start_2, double __pyx_v_bins_end_2); /* proto */ +static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ +static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */ +static PyObject *__pyx_tuple_; +static PyObject *__pyx_tuple__2; +static PyObject *__pyx_tuple__3; +static PyObject *__pyx_tuple__4; +static PyObject *__pyx_tuple__5; +static PyObject *__pyx_tuple__6; +static PyObject *__pyx_tuple__7; +static PyObject *__pyx_tuple__8; +static PyObject *__pyx_tuple__9; +static PyObject *__pyx_tuple__10; +static PyObject *__pyx_tuple__12; +static PyObject *__pyx_tuple__14; +static PyObject *__pyx_codeobj__11; +static PyObject *__pyx_codeobj__13; +static PyObject *__pyx_codeobj__15; + +/* "opmd_viewer/openpmd_timeseries/cython_function.pyx":9 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * def extract_indices_cython( # <<<<<<<<<<<<<< + * np.ndarray[np.int64_t, ndim=1] original_indices, + * np.ndarray[np.int64_t, ndim=1] selected_indices, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_1extract_indices_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_11opmd_viewer_18openpmd_timeseries_15cython_function_extract_indices_cython[] = "\n Go through the sorted arrays `pid` and `selected_pid`, and record\n the indices (of the array `pid`) where they match, by storing them\n in the array `selected_indices` (this array is thus modified in-place)\n\n Return the number of elements that were filled in `selected_indices`\n "; +static PyMethodDef __pyx_mdef_11opmd_viewer_18openpmd_timeseries_15cython_function_1extract_indices_cython = {"extract_indices_cython", (PyCFunction)__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_1extract_indices_cython, METH_VARARGS|METH_KEYWORDS, __pyx_doc_11opmd_viewer_18openpmd_timeseries_15cython_function_extract_indices_cython}; +static PyObject *__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_1extract_indices_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_original_indices = 0; + PyArrayObject *__pyx_v_selected_indices = 0; + PyArrayObject *__pyx_v_pid = 0; + PyArrayObject *__pyx_v_selected_pid = 0; + PyBoolObject *__pyx_v_preserve_particle_index = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("extract_indices_cython (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_original_indices,&__pyx_n_s_selected_indices,&__pyx_n_s_pid,&__pyx_n_s_selected_pid,&__pyx_n_s_preserve_particle_index,0}; + PyObject* values[5] = {0,0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_original_indices)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_selected_indices)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("extract_indices_cython", 1, 5, 5, 1); __PYX_ERR(0, 9, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_pid)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("extract_indices_cython", 1, 5, 5, 2); __PYX_ERR(0, 9, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_selected_pid)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("extract_indices_cython", 1, 5, 5, 3); __PYX_ERR(0, 9, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_preserve_particle_index)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("extract_indices_cython", 1, 5, 5, 4); __PYX_ERR(0, 9, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "extract_indices_cython") < 0)) __PYX_ERR(0, 9, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 5) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + } + __pyx_v_original_indices = ((PyArrayObject *)values[0]); + __pyx_v_selected_indices = ((PyArrayObject *)values[1]); + __pyx_v_pid = ((PyArrayObject *)values[2]); + __pyx_v_selected_pid = ((PyArrayObject *)values[3]); + __pyx_v_preserve_particle_index = ((PyBoolObject *)values[4]); + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("extract_indices_cython", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 9, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("opmd_viewer.openpmd_timeseries.cython_function.extract_indices_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_original_indices), __pyx_ptype_5numpy_ndarray, 1, "original_indices", 0))) __PYX_ERR(0, 10, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_selected_indices), __pyx_ptype_5numpy_ndarray, 1, "selected_indices", 0))) __PYX_ERR(0, 11, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_pid), __pyx_ptype_5numpy_ndarray, 1, "pid", 0))) __PYX_ERR(0, 12, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_selected_pid), __pyx_ptype_5numpy_ndarray, 1, "selected_pid", 0))) __PYX_ERR(0, 13, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_preserve_particle_index), __pyx_ptype_7cpython_4bool_bool, 1, "preserve_particle_index", 0))) __PYX_ERR(0, 14, __pyx_L1_error) + __pyx_r = __pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_extract_indices_cython(__pyx_self, __pyx_v_original_indices, __pyx_v_selected_indices, __pyx_v_pid, __pyx_v_selected_pid, __pyx_v_preserve_particle_index); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_extract_indices_cython(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_original_indices, PyArrayObject *__pyx_v_selected_indices, PyArrayObject *__pyx_v_pid, PyArrayObject *__pyx_v_selected_pid, PyBoolObject *__pyx_v_preserve_particle_index) { + unsigned int __pyx_v_i; + unsigned int __pyx_v_i_select; + unsigned int __pyx_v_i_fill; + unsigned int __pyx_v_N; + unsigned int __pyx_v_N_selected; + __Pyx_LocalBuf_ND __pyx_pybuffernd_original_indices; + __Pyx_Buffer __pyx_pybuffer_original_indices; + __Pyx_LocalBuf_ND __pyx_pybuffernd_pid; + __Pyx_Buffer __pyx_pybuffer_pid; + __Pyx_LocalBuf_ND __pyx_pybuffernd_selected_indices; + __Pyx_Buffer __pyx_pybuffer_selected_indices; + __Pyx_LocalBuf_ND __pyx_pybuffernd_selected_pid; + __Pyx_Buffer __pyx_pybuffer_selected_pid; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + size_t __pyx_t_3; + size_t __pyx_t_4; + size_t __pyx_t_5; + size_t __pyx_t_6; + size_t __pyx_t_7; + size_t __pyx_t_8; + size_t __pyx_t_9; + size_t __pyx_t_10; + size_t __pyx_t_11; + PyObject *__pyx_t_12 = NULL; + __Pyx_RefNannySetupContext("extract_indices_cython", 0); + __pyx_pybuffer_original_indices.pybuffer.buf = NULL; + __pyx_pybuffer_original_indices.refcount = 0; + __pyx_pybuffernd_original_indices.data = NULL; + __pyx_pybuffernd_original_indices.rcbuffer = &__pyx_pybuffer_original_indices; + __pyx_pybuffer_selected_indices.pybuffer.buf = NULL; + __pyx_pybuffer_selected_indices.refcount = 0; + __pyx_pybuffernd_selected_indices.data = NULL; + __pyx_pybuffernd_selected_indices.rcbuffer = &__pyx_pybuffer_selected_indices; + __pyx_pybuffer_pid.pybuffer.buf = NULL; + __pyx_pybuffer_pid.refcount = 0; + __pyx_pybuffernd_pid.data = NULL; + __pyx_pybuffernd_pid.rcbuffer = &__pyx_pybuffer_pid; + __pyx_pybuffer_selected_pid.pybuffer.buf = NULL; + __pyx_pybuffer_selected_pid.refcount = 0; + __pyx_pybuffernd_selected_pid.data = NULL; + __pyx_pybuffernd_selected_pid.rcbuffer = &__pyx_pybuffer_selected_pid; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_original_indices.rcbuffer->pybuffer, (PyObject*)__pyx_v_original_indices, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 9, __pyx_L1_error) + } + __pyx_pybuffernd_original_indices.diminfo[0].strides = __pyx_pybuffernd_original_indices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_original_indices.diminfo[0].shape = __pyx_pybuffernd_original_indices.rcbuffer->pybuffer.shape[0]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_selected_indices.rcbuffer->pybuffer, (PyObject*)__pyx_v_selected_indices, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 9, __pyx_L1_error) + } + __pyx_pybuffernd_selected_indices.diminfo[0].strides = __pyx_pybuffernd_selected_indices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_selected_indices.diminfo[0].shape = __pyx_pybuffernd_selected_indices.rcbuffer->pybuffer.shape[0]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_pid.rcbuffer->pybuffer, (PyObject*)__pyx_v_pid, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 9, __pyx_L1_error) + } + __pyx_pybuffernd_pid.diminfo[0].strides = __pyx_pybuffernd_pid.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_pid.diminfo[0].shape = __pyx_pybuffernd_pid.rcbuffer->pybuffer.shape[0]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_selected_pid.rcbuffer->pybuffer, (PyObject*)__pyx_v_selected_pid, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 9, __pyx_L1_error) + } + __pyx_pybuffernd_selected_pid.diminfo[0].strides = __pyx_pybuffernd_selected_pid.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_selected_pid.diminfo[0].shape = __pyx_pybuffernd_selected_pid.rcbuffer->pybuffer.shape[0]; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":22 + * Return the number of elements that were filled in `selected_indices` + * """ + * cdef unsigned int i = 0 # <<<<<<<<<<<<<< + * cdef unsigned int i_select = 0 + * cdef unsigned int i_fill = 0 + */ + __pyx_v_i = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":23 + * """ + * cdef unsigned int i = 0 + * cdef unsigned int i_select = 0 # <<<<<<<<<<<<<< + * cdef unsigned int i_fill = 0 + * cdef unsigned int N = pid.shape[0] + */ + __pyx_v_i_select = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":24 + * cdef unsigned int i = 0 + * cdef unsigned int i_select = 0 + * cdef unsigned int i_fill = 0 # <<<<<<<<<<<<<< + * cdef unsigned int N = pid.shape[0] + * cdef unsigned int N_selected = selected_pid.shape[0] + */ + __pyx_v_i_fill = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":25 + * cdef unsigned int i_select = 0 + * cdef unsigned int i_fill = 0 + * cdef unsigned int N = pid.shape[0] # <<<<<<<<<<<<<< + * cdef unsigned int N_selected = selected_pid.shape[0] + * + */ + __pyx_v_N = (__pyx_v_pid->dimensions[0]); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":26 + * cdef unsigned int i_fill = 0 + * cdef unsigned int N = pid.shape[0] + * cdef unsigned int N_selected = selected_pid.shape[0] # <<<<<<<<<<<<<< + * + * # Go through both sorted arrays (pid and selected_pid) and match them. + */ + __pyx_v_N_selected = (__pyx_v_selected_pid->dimensions[0]); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":31 + * # i.e. whenever the same number appears in both arrays, + * # record the corresponding original index in selected_indices + * while i < N and i_select < N_selected: # <<<<<<<<<<<<<< + * + * if pid[i] < selected_pid[i_select]: + */ + while (1) { + __pyx_t_2 = ((__pyx_v_i < __pyx_v_N) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L5_bool_binop_done; + } + __pyx_t_2 = ((__pyx_v_i_select < __pyx_v_N_selected) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L5_bool_binop_done:; + if (!__pyx_t_1) break; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":33 + * while i < N and i_select < N_selected: + * + * if pid[i] < selected_pid[i_select]: # <<<<<<<<<<<<<< + * i += 1 + * elif pid[i] == selected_pid[i_select]: + */ + __pyx_t_3 = __pyx_v_i; + __pyx_t_4 = __pyx_v_i_select; + __pyx_t_1 = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_pid.rcbuffer->pybuffer.buf, __pyx_t_3, __pyx_pybuffernd_pid.diminfo[0].strides)) < (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_selected_pid.rcbuffer->pybuffer.buf, __pyx_t_4, __pyx_pybuffernd_selected_pid.diminfo[0].strides))) != 0); + if (__pyx_t_1) { + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":34 + * + * if pid[i] < selected_pid[i_select]: + * i += 1 # <<<<<<<<<<<<<< + * elif pid[i] == selected_pid[i_select]: + * selected_indices[i_fill] = original_indices[i] + */ + __pyx_v_i = (__pyx_v_i + 1); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":33 + * while i < N and i_select < N_selected: + * + * if pid[i] < selected_pid[i_select]: # <<<<<<<<<<<<<< + * i += 1 + * elif pid[i] == selected_pid[i_select]: + */ + goto __pyx_L7; + } + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":35 + * if pid[i] < selected_pid[i_select]: + * i += 1 + * elif pid[i] == selected_pid[i_select]: # <<<<<<<<<<<<<< + * selected_indices[i_fill] = original_indices[i] + * i_fill += 1 + */ + __pyx_t_5 = __pyx_v_i; + __pyx_t_6 = __pyx_v_i_select; + __pyx_t_1 = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_pid.rcbuffer->pybuffer.buf, __pyx_t_5, __pyx_pybuffernd_pid.diminfo[0].strides)) == (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_selected_pid.rcbuffer->pybuffer.buf, __pyx_t_6, __pyx_pybuffernd_selected_pid.diminfo[0].strides))) != 0); + if (__pyx_t_1) { + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":36 + * i += 1 + * elif pid[i] == selected_pid[i_select]: + * selected_indices[i_fill] = original_indices[i] # <<<<<<<<<<<<<< + * i_fill += 1 + * i_select += 1 + */ + __pyx_t_7 = __pyx_v_i; + __pyx_t_8 = __pyx_v_i_fill; + *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_selected_indices.rcbuffer->pybuffer.buf, __pyx_t_8, __pyx_pybuffernd_selected_indices.diminfo[0].strides) = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_original_indices.rcbuffer->pybuffer.buf, __pyx_t_7, __pyx_pybuffernd_original_indices.diminfo[0].strides)); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":37 + * elif pid[i] == selected_pid[i_select]: + * selected_indices[i_fill] = original_indices[i] + * i_fill += 1 # <<<<<<<<<<<<<< + * i_select += 1 + * elif pid[i] > selected_pid[i_select]: + */ + __pyx_v_i_fill = (__pyx_v_i_fill + 1); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":38 + * selected_indices[i_fill] = original_indices[i] + * i_fill += 1 + * i_select += 1 # <<<<<<<<<<<<<< + * elif pid[i] > selected_pid[i_select]: + * i_select += 1 + */ + __pyx_v_i_select = (__pyx_v_i_select + 1); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":35 + * if pid[i] < selected_pid[i_select]: + * i += 1 + * elif pid[i] == selected_pid[i_select]: # <<<<<<<<<<<<<< + * selected_indices[i_fill] = original_indices[i] + * i_fill += 1 + */ + goto __pyx_L7; + } + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":39 + * i_fill += 1 + * i_select += 1 + * elif pid[i] > selected_pid[i_select]: # <<<<<<<<<<<<<< + * i_select += 1 + * if preserve_particle_index: + */ + __pyx_t_9 = __pyx_v_i; + __pyx_t_10 = __pyx_v_i_select; + __pyx_t_1 = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_pid.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_pid.diminfo[0].strides)) > (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_selected_pid.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_selected_pid.diminfo[0].strides))) != 0); + if (__pyx_t_1) { + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":40 + * i_select += 1 + * elif pid[i] > selected_pid[i_select]: + * i_select += 1 # <<<<<<<<<<<<<< + * if preserve_particle_index: + * # Fill the index, to indicate that the particle is absent + */ + __pyx_v_i_select = (__pyx_v_i_select + 1); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":41 + * elif pid[i] > selected_pid[i_select]: + * i_select += 1 + * if preserve_particle_index: # <<<<<<<<<<<<<< + * # Fill the index, to indicate that the particle is absent + * selected_indices[i_fill] = -1 + */ + __pyx_t_1 = __Pyx_PyObject_IsTrue(((PyObject *)__pyx_v_preserve_particle_index)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 41, __pyx_L1_error) + if (__pyx_t_1) { + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":43 + * if preserve_particle_index: + * # Fill the index, to indicate that the particle is absent + * selected_indices[i_fill] = -1 # <<<<<<<<<<<<<< + * i_fill += 1 + * + */ + __pyx_t_11 = __pyx_v_i_fill; + *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_selected_indices.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_selected_indices.diminfo[0].strides) = -1LL; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":44 + * # Fill the index, to indicate that the particle is absent + * selected_indices[i_fill] = -1 + * i_fill += 1 # <<<<<<<<<<<<<< + * + * return( i_fill ) + */ + __pyx_v_i_fill = (__pyx_v_i_fill + 1); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":41 + * elif pid[i] > selected_pid[i_select]: + * i_select += 1 + * if preserve_particle_index: # <<<<<<<<<<<<<< + * # Fill the index, to indicate that the particle is absent + * selected_indices[i_fill] = -1 + */ + } + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":39 + * i_fill += 1 + * i_select += 1 + * elif pid[i] > selected_pid[i_select]: # <<<<<<<<<<<<<< + * i_select += 1 + * if preserve_particle_index: + */ + } + __pyx_L7:; + } + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":46 + * i_fill += 1 + * + * return( i_fill ) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_12 = __Pyx_PyInt_From_unsigned_int(__pyx_v_i_fill); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 46, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __pyx_r = __pyx_t_12; + __pyx_t_12 = 0; + goto __pyx_L0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":9 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * def extract_indices_cython( # <<<<<<<<<<<<<< + * np.ndarray[np.int64_t, ndim=1] original_indices, + * np.ndarray[np.int64_t, ndim=1] selected_indices, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_12); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_original_indices.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_pid.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_selected_indices.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_selected_pid.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("opmd_viewer.openpmd_timeseries.cython_function.extract_indices_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_original_indices.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_pid.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_selected_indices.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_selected_pid.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "opmd_viewer/openpmd_timeseries/cython_function.pyx":51 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * def histogram_cic_1d( # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] q1, + * np.ndarray[np.float64_t, ndim=1] w, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_3histogram_cic_1d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_11opmd_viewer_18openpmd_timeseries_15cython_function_2histogram_cic_1d[] = "\n Return an 1D histogram of the values in `q1` weighted by `w`,\n consisting of `nbins` evenly-spaced bins between `bins_start`\n and `bins_end`. Contribution to each bins is determined by the\n CIC weighting scheme (i.e. linear weights).\n "; +static PyMethodDef __pyx_mdef_11opmd_viewer_18openpmd_timeseries_15cython_function_3histogram_cic_1d = {"histogram_cic_1d", (PyCFunction)__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_3histogram_cic_1d, METH_VARARGS|METH_KEYWORDS, __pyx_doc_11opmd_viewer_18openpmd_timeseries_15cython_function_2histogram_cic_1d}; +static PyObject *__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_3histogram_cic_1d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_q1 = 0; + PyArrayObject *__pyx_v_w = 0; + int __pyx_v_nbins; + double __pyx_v_bins_start; + double __pyx_v_bins_end; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("histogram_cic_1d (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_q1,&__pyx_n_s_w,&__pyx_n_s_nbins,&__pyx_n_s_bins_start,&__pyx_n_s_bins_end,0}; + PyObject* values[5] = {0,0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_q1)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_w)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("histogram_cic_1d", 1, 5, 5, 1); __PYX_ERR(0, 51, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_nbins)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("histogram_cic_1d", 1, 5, 5, 2); __PYX_ERR(0, 51, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bins_start)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("histogram_cic_1d", 1, 5, 5, 3); __PYX_ERR(0, 51, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bins_end)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("histogram_cic_1d", 1, 5, 5, 4); __PYX_ERR(0, 51, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "histogram_cic_1d") < 0)) __PYX_ERR(0, 51, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 5) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + } + __pyx_v_q1 = ((PyArrayObject *)values[0]); + __pyx_v_w = ((PyArrayObject *)values[1]); + __pyx_v_nbins = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_nbins == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 54, __pyx_L3_error) + __pyx_v_bins_start = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_bins_start == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 54, __pyx_L3_error) + __pyx_v_bins_end = __pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_bins_end == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 54, __pyx_L3_error) + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("histogram_cic_1d", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 51, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("opmd_viewer.openpmd_timeseries.cython_function.histogram_cic_1d", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_q1), __pyx_ptype_5numpy_ndarray, 1, "q1", 0))) __PYX_ERR(0, 52, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w), __pyx_ptype_5numpy_ndarray, 1, "w", 0))) __PYX_ERR(0, 53, __pyx_L1_error) + __pyx_r = __pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_2histogram_cic_1d(__pyx_self, __pyx_v_q1, __pyx_v_w, __pyx_v_nbins, __pyx_v_bins_start, __pyx_v_bins_end); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_2histogram_cic_1d(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_q1, PyArrayObject *__pyx_v_w, int __pyx_v_nbins, double __pyx_v_bins_start, double __pyx_v_bins_end) { + double __pyx_v_bin_spacing; + double __pyx_v_inv_spacing; + int __pyx_v_n_ptcl; + int __pyx_v_i_low_bin; + double __pyx_v_q1_cell; + double __pyx_v_S_low; + PyObject *__pyx_v_hist_data = NULL; + int __pyx_v_i; + __Pyx_LocalBuf_ND __pyx_pybuffernd_q1; + __Pyx_Buffer __pyx_pybuffer_q1; + __Pyx_LocalBuf_ND __pyx_pybuffernd_w; + __Pyx_Buffer __pyx_pybuffer_w; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + double __pyx_t_1; + Py_ssize_t __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + int __pyx_t_9; + Py_ssize_t __pyx_t_10; + int __pyx_t_11; + int __pyx_t_12; + int __pyx_t_13; + Py_ssize_t __pyx_t_14; + long __pyx_t_15; + Py_ssize_t __pyx_t_16; + __Pyx_RefNannySetupContext("histogram_cic_1d", 0); + __pyx_pybuffer_q1.pybuffer.buf = NULL; + __pyx_pybuffer_q1.refcount = 0; + __pyx_pybuffernd_q1.data = NULL; + __pyx_pybuffernd_q1.rcbuffer = &__pyx_pybuffer_q1; + __pyx_pybuffer_w.pybuffer.buf = NULL; + __pyx_pybuffer_w.refcount = 0; + __pyx_pybuffernd_w.data = NULL; + __pyx_pybuffernd_w.rcbuffer = &__pyx_pybuffer_w; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_q1.rcbuffer->pybuffer, (PyObject*)__pyx_v_q1, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 51, __pyx_L1_error) + } + __pyx_pybuffernd_q1.diminfo[0].strides = __pyx_pybuffernd_q1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_q1.diminfo[0].shape = __pyx_pybuffernd_q1.rcbuffer->pybuffer.shape[0]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_w.rcbuffer->pybuffer, (PyObject*)__pyx_v_w, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 51, __pyx_L1_error) + } + __pyx_pybuffernd_w.diminfo[0].strides = __pyx_pybuffernd_w.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_w.diminfo[0].shape = __pyx_pybuffernd_w.rcbuffer->pybuffer.shape[0]; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":62 + * """ + * # Define various scalars + * cdef double bin_spacing = (bins_end-bins_start)/nbins # <<<<<<<<<<<<<< + * cdef double inv_spacing = 1./bin_spacing + * cdef int n_ptcl = len(w) + */ + __pyx_t_1 = (__pyx_v_bins_end - __pyx_v_bins_start); + if (unlikely(__pyx_v_nbins == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 62, __pyx_L1_error) + } + __pyx_v_bin_spacing = (__pyx_t_1 / __pyx_v_nbins); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":63 + * # Define various scalars + * cdef double bin_spacing = (bins_end-bins_start)/nbins + * cdef double inv_spacing = 1./bin_spacing # <<<<<<<<<<<<<< + * cdef int n_ptcl = len(w) + * cdef int i_low_bin + */ + if (unlikely(__pyx_v_bin_spacing == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 63, __pyx_L1_error) + } + __pyx_v_inv_spacing = (1. / __pyx_v_bin_spacing); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":64 + * cdef double bin_spacing = (bins_end-bins_start)/nbins + * cdef double inv_spacing = 1./bin_spacing + * cdef int n_ptcl = len(w) # <<<<<<<<<<<<<< + * cdef int i_low_bin + * cdef double q1_cell + */ + __pyx_t_2 = PyObject_Length(((PyObject *)__pyx_v_w)); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 64, __pyx_L1_error) + __pyx_v_n_ptcl = __pyx_t_2; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":70 + * + * # Allocate array for histogrammed data + * hist_data = np.zeros( nbins, dtype=np.float64 ) # <<<<<<<<<<<<<< + * + * # Go through particle array and bin the data + */ + __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_zeros); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_nbins); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); + __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_7) < 0) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_hist_data = __pyx_t_7; + __pyx_t_7 = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":73 + * + * # Go through particle array and bin the data + * for i in xrange(n_ptcl): # <<<<<<<<<<<<<< + * # Calculate the index of lower bin to which this particle contributes + * q1_cell = (q1[i] - bins_start) * inv_spacing + */ + __pyx_t_8 = __pyx_v_n_ptcl; + for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { + __pyx_v_i = __pyx_t_9; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":75 + * for i in xrange(n_ptcl): + * # Calculate the index of lower bin to which this particle contributes + * q1_cell = (q1[i] - bins_start) * inv_spacing # <<<<<<<<<<<<<< + * i_low_bin = floor( q1_cell ) + * # Calculate corresponding CIC shape and deposit the weight + */ + __pyx_t_10 = __pyx_v_i; + __pyx_v_q1_cell = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_q1.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_q1.diminfo[0].strides)) - __pyx_v_bins_start) * __pyx_v_inv_spacing); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":76 + * # Calculate the index of lower bin to which this particle contributes + * q1_cell = (q1[i] - bins_start) * inv_spacing + * i_low_bin = floor( q1_cell ) # <<<<<<<<<<<<<< + * # Calculate corresponding CIC shape and deposit the weight + * S_low = 1. - (q1_cell - i_low_bin) + */ + __pyx_v_i_low_bin = ((int)floor(__pyx_v_q1_cell)); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":78 + * i_low_bin = floor( q1_cell ) + * # Calculate corresponding CIC shape and deposit the weight + * S_low = 1. - (q1_cell - i_low_bin) # <<<<<<<<<<<<<< + * if (i_low_bin >= 0) and (i_low_bin < nbins): + * hist_data[ i_low_bin ] += w[i] * S_low + */ + __pyx_v_S_low = (1. - (__pyx_v_q1_cell - __pyx_v_i_low_bin)); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":79 + * # Calculate corresponding CIC shape and deposit the weight + * S_low = 1. - (q1_cell - i_low_bin) + * if (i_low_bin >= 0) and (i_low_bin < nbins): # <<<<<<<<<<<<<< + * hist_data[ i_low_bin ] += w[i] * S_low + * if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): + */ + __pyx_t_12 = ((__pyx_v_i_low_bin >= 0) != 0); + if (__pyx_t_12) { + } else { + __pyx_t_11 = __pyx_t_12; + goto __pyx_L6_bool_binop_done; + } + __pyx_t_12 = ((__pyx_v_i_low_bin < __pyx_v_nbins) != 0); + __pyx_t_11 = __pyx_t_12; + __pyx_L6_bool_binop_done:; + if (__pyx_t_11) { + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":80 + * S_low = 1. - (q1_cell - i_low_bin) + * if (i_low_bin >= 0) and (i_low_bin < nbins): + * hist_data[ i_low_bin ] += w[i] * S_low # <<<<<<<<<<<<<< + * if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): + * hist_data[ i_low_bin + 1 ] += w[i] * (1. - S_low) + */ + __pyx_t_13 = __pyx_v_i_low_bin; + __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_hist_data, __pyx_t_13, int, 1, __Pyx_PyInt_From_int, 0, 0, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_14 = __pyx_v_i; + __pyx_t_3 = PyFloat_FromDouble(((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_w.diminfo[0].strides)) * __pyx_v_S_low)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PyNumber_InPlaceAdd(__pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(__Pyx_SetItemInt(__pyx_v_hist_data, __pyx_t_13, __pyx_t_5, int, 1, __Pyx_PyInt_From_int, 0, 0, 0) < 0)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":79 + * # Calculate corresponding CIC shape and deposit the weight + * S_low = 1. - (q1_cell - i_low_bin) + * if (i_low_bin >= 0) and (i_low_bin < nbins): # <<<<<<<<<<<<<< + * hist_data[ i_low_bin ] += w[i] * S_low + * if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): + */ + } + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":81 + * if (i_low_bin >= 0) and (i_low_bin < nbins): + * hist_data[ i_low_bin ] += w[i] * S_low + * if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): # <<<<<<<<<<<<<< + * hist_data[ i_low_bin + 1 ] += w[i] * (1. - S_low) + * + */ + __pyx_t_12 = (((__pyx_v_i_low_bin + 1) >= 0) != 0); + if (__pyx_t_12) { + } else { + __pyx_t_11 = __pyx_t_12; + goto __pyx_L9_bool_binop_done; + } + __pyx_t_12 = (((__pyx_v_i_low_bin + 1) < __pyx_v_nbins) != 0); + __pyx_t_11 = __pyx_t_12; + __pyx_L9_bool_binop_done:; + if (__pyx_t_11) { + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":82 + * hist_data[ i_low_bin ] += w[i] * S_low + * if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): + * hist_data[ i_low_bin + 1 ] += w[i] * (1. - S_low) # <<<<<<<<<<<<<< + * + * return( hist_data ) + */ + __pyx_t_15 = (__pyx_v_i_low_bin + 1); + __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_hist_data, __pyx_t_15, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_16 = __pyx_v_i; + __pyx_t_3 = PyFloat_FromDouble(((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_w.diminfo[0].strides)) * (1. - __pyx_v_S_low))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = PyNumber_InPlaceAdd(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(__Pyx_SetItemInt(__pyx_v_hist_data, __pyx_t_15, __pyx_t_7, long, 1, __Pyx_PyInt_From_long, 0, 0, 0) < 0)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":81 + * if (i_low_bin >= 0) and (i_low_bin < nbins): + * hist_data[ i_low_bin ] += w[i] * S_low + * if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): # <<<<<<<<<<<<<< + * hist_data[ i_low_bin + 1 ] += w[i] * (1. - S_low) + * + */ + } + } + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":84 + * hist_data[ i_low_bin + 1 ] += w[i] * (1. - S_low) + * + * return( hist_data ) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_hist_data); + __pyx_r = __pyx_v_hist_data; + goto __pyx_L0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":51 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * def histogram_cic_1d( # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] q1, + * np.ndarray[np.float64_t, ndim=1] w, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_q1.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_w.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("opmd_viewer.openpmd_timeseries.cython_function.histogram_cic_1d", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_q1.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_w.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XDECREF(__pyx_v_hist_data); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "opmd_viewer/openpmd_timeseries/cython_function.pyx":89 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * def histogram_cic_2d( # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] q1, + * np.ndarray[np.float64_t, ndim=1] q2, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_5histogram_cic_2d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_11opmd_viewer_18openpmd_timeseries_15cython_function_4histogram_cic_2d[] = "\n Return an 2D histogram of the values in `q1` and `q2` weighted by `w`,\n consisting of `nbins_1` bins in the first dimension and `nbins_2` bins\n in the second dimension.\n Contribution to each bins is determined by the\n CIC weighting scheme (i.e. linear weights).\n "; +static PyMethodDef __pyx_mdef_11opmd_viewer_18openpmd_timeseries_15cython_function_5histogram_cic_2d = {"histogram_cic_2d", (PyCFunction)__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_5histogram_cic_2d, METH_VARARGS|METH_KEYWORDS, __pyx_doc_11opmd_viewer_18openpmd_timeseries_15cython_function_4histogram_cic_2d}; +static PyObject *__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_5histogram_cic_2d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyArrayObject *__pyx_v_q1 = 0; + PyArrayObject *__pyx_v_q2 = 0; + PyArrayObject *__pyx_v_w = 0; + int __pyx_v_nbins_1; + double __pyx_v_bins_start_1; + double __pyx_v_bins_end_1; + int __pyx_v_nbins_2; + double __pyx_v_bins_start_2; + double __pyx_v_bins_end_2; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("histogram_cic_2d (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_q1,&__pyx_n_s_q2,&__pyx_n_s_w,&__pyx_n_s_nbins_1,&__pyx_n_s_bins_start_1,&__pyx_n_s_bins_end_1,&__pyx_n_s_nbins_2,&__pyx_n_s_bins_start_2,&__pyx_n_s_bins_end_2,0}; + PyObject* values[9] = {0,0,0,0,0,0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_q1)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_q2)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 1); __PYX_ERR(0, 89, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_w)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 2); __PYX_ERR(0, 89, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_nbins_1)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 3); __PYX_ERR(0, 89, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bins_start_1)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 4); __PYX_ERR(0, 89, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 5: + if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bins_end_1)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 5); __PYX_ERR(0, 89, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 6: + if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_nbins_2)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 6); __PYX_ERR(0, 89, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 7: + if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bins_start_2)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 7); __PYX_ERR(0, 89, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 8: + if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bins_end_2)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 8); __PYX_ERR(0, 89, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "histogram_cic_2d") < 0)) __PYX_ERR(0, 89, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 9) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + } + __pyx_v_q1 = ((PyArrayObject *)values[0]); + __pyx_v_q2 = ((PyArrayObject *)values[1]); + __pyx_v_w = ((PyArrayObject *)values[2]); + __pyx_v_nbins_1 = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_nbins_1 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 93, __pyx_L3_error) + __pyx_v_bins_start_1 = __pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_bins_start_1 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 93, __pyx_L3_error) + __pyx_v_bins_end_1 = __pyx_PyFloat_AsDouble(values[5]); if (unlikely((__pyx_v_bins_end_1 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 93, __pyx_L3_error) + __pyx_v_nbins_2 = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_nbins_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 94, __pyx_L3_error) + __pyx_v_bins_start_2 = __pyx_PyFloat_AsDouble(values[7]); if (unlikely((__pyx_v_bins_start_2 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 94, __pyx_L3_error) + __pyx_v_bins_end_2 = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_bins_end_2 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 94, __pyx_L3_error) + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 89, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("opmd_viewer.openpmd_timeseries.cython_function.histogram_cic_2d", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_q1), __pyx_ptype_5numpy_ndarray, 1, "q1", 0))) __PYX_ERR(0, 90, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_q2), __pyx_ptype_5numpy_ndarray, 1, "q2", 0))) __PYX_ERR(0, 91, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w), __pyx_ptype_5numpy_ndarray, 1, "w", 0))) __PYX_ERR(0, 92, __pyx_L1_error) + __pyx_r = __pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_4histogram_cic_2d(__pyx_self, __pyx_v_q1, __pyx_v_q2, __pyx_v_w, __pyx_v_nbins_1, __pyx_v_bins_start_1, __pyx_v_bins_end_1, __pyx_v_nbins_2, __pyx_v_bins_start_2, __pyx_v_bins_end_2); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_4histogram_cic_2d(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_q1, PyArrayObject *__pyx_v_q2, PyArrayObject *__pyx_v_w, int __pyx_v_nbins_1, double __pyx_v_bins_start_1, double __pyx_v_bins_end_1, int __pyx_v_nbins_2, double __pyx_v_bins_start_2, double __pyx_v_bins_end_2) { + double __pyx_v_bin_spacing_1; + double __pyx_v_inv_spacing_1; + double __pyx_v_bin_spacing_2; + double __pyx_v_inv_spacing_2; + int __pyx_v_n_ptcl; + int __pyx_v_i1_low_bin; + int __pyx_v_i2_low_bin; + double __pyx_v_q1_cell; + double __pyx_v_q2_cell; + double __pyx_v_S1_low; + double __pyx_v_S2_low; + PyObject *__pyx_v_hist_data = NULL; + int __pyx_v_i; + __Pyx_LocalBuf_ND __pyx_pybuffernd_q1; + __Pyx_Buffer __pyx_pybuffer_q1; + __Pyx_LocalBuf_ND __pyx_pybuffernd_q2; + __Pyx_Buffer __pyx_pybuffer_q2; + __Pyx_LocalBuf_ND __pyx_pybuffernd_w; + __Pyx_Buffer __pyx_pybuffer_w; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + double __pyx_t_1; + Py_ssize_t __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + int __pyx_t_9; + Py_ssize_t __pyx_t_10; + Py_ssize_t __pyx_t_11; + int __pyx_t_12; + int __pyx_t_13; + Py_ssize_t __pyx_t_14; + Py_ssize_t __pyx_t_15; + Py_ssize_t __pyx_t_16; + Py_ssize_t __pyx_t_17; + __Pyx_RefNannySetupContext("histogram_cic_2d", 0); + __pyx_pybuffer_q1.pybuffer.buf = NULL; + __pyx_pybuffer_q1.refcount = 0; + __pyx_pybuffernd_q1.data = NULL; + __pyx_pybuffernd_q1.rcbuffer = &__pyx_pybuffer_q1; + __pyx_pybuffer_q2.pybuffer.buf = NULL; + __pyx_pybuffer_q2.refcount = 0; + __pyx_pybuffernd_q2.data = NULL; + __pyx_pybuffernd_q2.rcbuffer = &__pyx_pybuffer_q2; + __pyx_pybuffer_w.pybuffer.buf = NULL; + __pyx_pybuffer_w.refcount = 0; + __pyx_pybuffernd_w.data = NULL; + __pyx_pybuffernd_w.rcbuffer = &__pyx_pybuffer_w; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_q1.rcbuffer->pybuffer, (PyObject*)__pyx_v_q1, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 89, __pyx_L1_error) + } + __pyx_pybuffernd_q1.diminfo[0].strides = __pyx_pybuffernd_q1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_q1.diminfo[0].shape = __pyx_pybuffernd_q1.rcbuffer->pybuffer.shape[0]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_q2.rcbuffer->pybuffer, (PyObject*)__pyx_v_q2, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 89, __pyx_L1_error) + } + __pyx_pybuffernd_q2.diminfo[0].strides = __pyx_pybuffernd_q2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_q2.diminfo[0].shape = __pyx_pybuffernd_q2.rcbuffer->pybuffer.shape[0]; + { + __Pyx_BufFmt_StackElem __pyx_stack[1]; + if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_w.rcbuffer->pybuffer, (PyObject*)__pyx_v_w, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 89, __pyx_L1_error) + } + __pyx_pybuffernd_w.diminfo[0].strides = __pyx_pybuffernd_w.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_w.diminfo[0].shape = __pyx_pybuffernd_w.rcbuffer->pybuffer.shape[0]; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":103 + * """ + * # Define various scalars + * cdef double bin_spacing_1 = (bins_end_1-bins_start_1)/nbins_1 # <<<<<<<<<<<<<< + * cdef double inv_spacing_1 = 1./bin_spacing_1 + * cdef double bin_spacing_2 = (bins_end_2-bins_start_2)/nbins_2 + */ + __pyx_t_1 = (__pyx_v_bins_end_1 - __pyx_v_bins_start_1); + if (unlikely(__pyx_v_nbins_1 == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 103, __pyx_L1_error) + } + __pyx_v_bin_spacing_1 = (__pyx_t_1 / __pyx_v_nbins_1); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":104 + * # Define various scalars + * cdef double bin_spacing_1 = (bins_end_1-bins_start_1)/nbins_1 + * cdef double inv_spacing_1 = 1./bin_spacing_1 # <<<<<<<<<<<<<< + * cdef double bin_spacing_2 = (bins_end_2-bins_start_2)/nbins_2 + * cdef double inv_spacing_2 = 1./bin_spacing_2 + */ + if (unlikely(__pyx_v_bin_spacing_1 == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 104, __pyx_L1_error) + } + __pyx_v_inv_spacing_1 = (1. / __pyx_v_bin_spacing_1); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":105 + * cdef double bin_spacing_1 = (bins_end_1-bins_start_1)/nbins_1 + * cdef double inv_spacing_1 = 1./bin_spacing_1 + * cdef double bin_spacing_2 = (bins_end_2-bins_start_2)/nbins_2 # <<<<<<<<<<<<<< + * cdef double inv_spacing_2 = 1./bin_spacing_2 + * cdef int n_ptcl = len(w) + */ + __pyx_t_1 = (__pyx_v_bins_end_2 - __pyx_v_bins_start_2); + if (unlikely(__pyx_v_nbins_2 == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 105, __pyx_L1_error) + } + __pyx_v_bin_spacing_2 = (__pyx_t_1 / __pyx_v_nbins_2); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":106 + * cdef double inv_spacing_1 = 1./bin_spacing_1 + * cdef double bin_spacing_2 = (bins_end_2-bins_start_2)/nbins_2 + * cdef double inv_spacing_2 = 1./bin_spacing_2 # <<<<<<<<<<<<<< + * cdef int n_ptcl = len(w) + * cdef int i1_low_bin, i2_low_bin + */ + if (unlikely(__pyx_v_bin_spacing_2 == 0)) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + __PYX_ERR(0, 106, __pyx_L1_error) + } + __pyx_v_inv_spacing_2 = (1. / __pyx_v_bin_spacing_2); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":107 + * cdef double bin_spacing_2 = (bins_end_2-bins_start_2)/nbins_2 + * cdef double inv_spacing_2 = 1./bin_spacing_2 + * cdef int n_ptcl = len(w) # <<<<<<<<<<<<<< + * cdef int i1_low_bin, i2_low_bin + * cdef double q1_cell, q2_cell + */ + __pyx_t_2 = PyObject_Length(((PyObject *)__pyx_v_w)); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 107, __pyx_L1_error) + __pyx_v_n_ptcl = __pyx_t_2; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":113 + * + * # Allocate array for histogrammed data + * hist_data = np.zeros( (nbins_1, nbins_2), dtype=np.float64 ) # <<<<<<<<<<<<<< + * + * # Go through particle array and bin the data + */ + __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_zeros); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_nbins_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_nbins_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_3); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_5); + __pyx_t_3 = 0; + __pyx_t_5 = 0; + __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_6); + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 113, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_v_hist_data = __pyx_t_7; + __pyx_t_7 = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":116 + * + * # Go through particle array and bin the data + * for i in xrange(n_ptcl): # <<<<<<<<<<<<<< + * + * # Calculate the index of lower bin to which this particle contributes + */ + __pyx_t_8 = __pyx_v_n_ptcl; + for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { + __pyx_v_i = __pyx_t_9; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":119 + * + * # Calculate the index of lower bin to which this particle contributes + * q1_cell = (q1[i] - bins_start_1) * inv_spacing_1 # <<<<<<<<<<<<<< + * q2_cell = (q2[i] - bins_start_2) * inv_spacing_2 + * i1_low_bin = floor( q1_cell ) + */ + __pyx_t_10 = __pyx_v_i; + __pyx_v_q1_cell = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_q1.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_q1.diminfo[0].strides)) - __pyx_v_bins_start_1) * __pyx_v_inv_spacing_1); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":120 + * # Calculate the index of lower bin to which this particle contributes + * q1_cell = (q1[i] - bins_start_1) * inv_spacing_1 + * q2_cell = (q2[i] - bins_start_2) * inv_spacing_2 # <<<<<<<<<<<<<< + * i1_low_bin = floor( q1_cell ) + * i2_low_bin = floor( q2_cell ) + */ + __pyx_t_11 = __pyx_v_i; + __pyx_v_q2_cell = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_q2.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_q2.diminfo[0].strides)) - __pyx_v_bins_start_2) * __pyx_v_inv_spacing_2); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":121 + * q1_cell = (q1[i] - bins_start_1) * inv_spacing_1 + * q2_cell = (q2[i] - bins_start_2) * inv_spacing_2 + * i1_low_bin = floor( q1_cell ) # <<<<<<<<<<<<<< + * i2_low_bin = floor( q2_cell ) + * + */ + __pyx_v_i1_low_bin = ((int)floor(__pyx_v_q1_cell)); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":122 + * q2_cell = (q2[i] - bins_start_2) * inv_spacing_2 + * i1_low_bin = floor( q1_cell ) + * i2_low_bin = floor( q2_cell ) # <<<<<<<<<<<<<< + * + * # Calculate corresponding CIC shape and deposit the weight + */ + __pyx_v_i2_low_bin = ((int)floor(__pyx_v_q2_cell)); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":125 + * + * # Calculate corresponding CIC shape and deposit the weight + * S1_low = 1. - (q1_cell - i1_low_bin) # <<<<<<<<<<<<<< + * S2_low = 1. - (q2_cell - i2_low_bin) + * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): + */ + __pyx_v_S1_low = (1. - (__pyx_v_q1_cell - __pyx_v_i1_low_bin)); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":126 + * # Calculate corresponding CIC shape and deposit the weight + * S1_low = 1. - (q1_cell - i1_low_bin) + * S2_low = 1. - (q2_cell - i2_low_bin) # <<<<<<<<<<<<<< + * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + */ + __pyx_v_S2_low = (1. - (__pyx_v_q2_cell - __pyx_v_i2_low_bin)); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":127 + * S1_low = 1. - (q1_cell - i1_low_bin) + * S2_low = 1. - (q2_cell - i2_low_bin) + * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): # <<<<<<<<<<<<<< + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low + */ + __pyx_t_13 = ((__pyx_v_i1_low_bin >= 0) != 0); + if (__pyx_t_13) { + } else { + __pyx_t_12 = __pyx_t_13; + goto __pyx_L6_bool_binop_done; + } + __pyx_t_13 = ((__pyx_v_i1_low_bin < __pyx_v_nbins_1) != 0); + __pyx_t_12 = __pyx_t_13; + __pyx_L6_bool_binop_done:; + if (__pyx_t_12) { + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":128 + * S2_low = 1. - (q2_cell - i2_low_bin) + * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): # <<<<<<<<<<<<<< + * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): + */ + __pyx_t_13 = ((__pyx_v_i2_low_bin >= 0) != 0); + if (__pyx_t_13) { + } else { + __pyx_t_12 = __pyx_t_13; + goto __pyx_L9_bool_binop_done; + } + __pyx_t_13 = ((__pyx_v_i2_low_bin < __pyx_v_nbins_2) != 0); + __pyx_t_12 = __pyx_t_13; + __pyx_L9_bool_binop_done:; + if (__pyx_t_12) { + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":129 + * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low # <<<<<<<<<<<<<< + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): + * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) + */ + __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_i1_low_bin); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 129, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_i2_low_bin); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 129, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 129, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_6); + __pyx_t_7 = 0; + __pyx_t_6 = 0; + __pyx_t_6 = PyObject_GetItem(__pyx_v_hist_data, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 129, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_14 = __pyx_v_i; + __pyx_t_7 = PyFloat_FromDouble((((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_w.diminfo[0].strides)) * __pyx_v_S1_low) * __pyx_v_S2_low)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 129, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 129, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(PyObject_SetItem(__pyx_v_hist_data, __pyx_t_5, __pyx_t_4) < 0)) __PYX_ERR(0, 129, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":128 + * S2_low = 1. - (q2_cell - i2_low_bin) + * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): # <<<<<<<<<<<<<< + * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): + */ + } + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":130 + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): # <<<<<<<<<<<<<< + * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) + * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): + */ + __pyx_t_13 = (((__pyx_v_i2_low_bin + 1) >= 0) != 0); + if (__pyx_t_13) { + } else { + __pyx_t_12 = __pyx_t_13; + goto __pyx_L12_bool_binop_done; + } + __pyx_t_13 = (((__pyx_v_i2_low_bin + 1) < __pyx_v_nbins_2) != 0); + __pyx_t_12 = __pyx_t_13; + __pyx_L12_bool_binop_done:; + if (__pyx_t_12) { + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":131 + * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): + * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) # <<<<<<<<<<<<<< + * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + */ + __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_i1_low_bin); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = __Pyx_PyInt_From_long((__pyx_v_i2_low_bin + 1)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4); + __pyx_t_5 = 0; + __pyx_t_4 = 0; + __pyx_t_4 = PyObject_GetItem(__pyx_v_hist_data, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_15 = __pyx_v_i; + __pyx_t_5 = PyFloat_FromDouble((((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_w.diminfo[0].strides)) * __pyx_v_S1_low) * (1. - __pyx_v_S2_low))); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(PyObject_SetItem(__pyx_v_hist_data, __pyx_t_7, __pyx_t_6) < 0)) __PYX_ERR(0, 131, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":130 + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): # <<<<<<<<<<<<<< + * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) + * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): + */ + } + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":127 + * S1_low = 1. - (q1_cell - i1_low_bin) + * S2_low = 1. - (q2_cell - i2_low_bin) + * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): # <<<<<<<<<<<<<< + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low + */ + } + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":132 + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): + * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) + * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): # <<<<<<<<<<<<<< + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low + */ + __pyx_t_13 = (((__pyx_v_i1_low_bin + 1) >= 0) != 0); + if (__pyx_t_13) { + } else { + __pyx_t_12 = __pyx_t_13; + goto __pyx_L15_bool_binop_done; + } + __pyx_t_13 = (((__pyx_v_i1_low_bin + 1) < __pyx_v_nbins_1) != 0); + __pyx_t_12 = __pyx_t_13; + __pyx_L15_bool_binop_done:; + if (__pyx_t_12) { + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":133 + * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) + * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): # <<<<<<<<<<<<<< + * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): + */ + __pyx_t_13 = ((__pyx_v_i2_low_bin >= 0) != 0); + if (__pyx_t_13) { + } else { + __pyx_t_12 = __pyx_t_13; + goto __pyx_L18_bool_binop_done; + } + __pyx_t_13 = ((__pyx_v_i2_low_bin < __pyx_v_nbins_2) != 0); + __pyx_t_12 = __pyx_t_13; + __pyx_L18_bool_binop_done:; + if (__pyx_t_12) { + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":134 + * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low # <<<<<<<<<<<<<< + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): + * hist_data[ i1_low_bin+1, i2_low_bin+1 ] += w[i]*(1.-S1_low)*(1.-S2_low) + */ + __pyx_t_7 = __Pyx_PyInt_From_long((__pyx_v_i1_low_bin + 1)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_i2_low_bin); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_6); + __pyx_t_7 = 0; + __pyx_t_6 = 0; + __pyx_t_6 = PyObject_GetItem(__pyx_v_hist_data, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_16 = __pyx_v_i; + __pyx_t_7 = PyFloat_FromDouble((((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_w.diminfo[0].strides)) * (1. - __pyx_v_S1_low)) * __pyx_v_S2_low)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(PyObject_SetItem(__pyx_v_hist_data, __pyx_t_5, __pyx_t_4) < 0)) __PYX_ERR(0, 134, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":133 + * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) + * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): # <<<<<<<<<<<<<< + * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): + */ + } + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":135 + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): # <<<<<<<<<<<<<< + * hist_data[ i1_low_bin+1, i2_low_bin+1 ] += w[i]*(1.-S1_low)*(1.-S2_low) + * + */ + __pyx_t_13 = (((__pyx_v_i2_low_bin + 1) >= 0) != 0); + if (__pyx_t_13) { + } else { + __pyx_t_12 = __pyx_t_13; + goto __pyx_L21_bool_binop_done; + } + __pyx_t_13 = (((__pyx_v_i2_low_bin + 1) < __pyx_v_nbins_2) != 0); + __pyx_t_12 = __pyx_t_13; + __pyx_L21_bool_binop_done:; + if (__pyx_t_12) { + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":136 + * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): + * hist_data[ i1_low_bin+1, i2_low_bin+1 ] += w[i]*(1.-S1_low)*(1.-S2_low) # <<<<<<<<<<<<<< + * + * return( hist_data ) + */ + __pyx_t_5 = __Pyx_PyInt_From_long((__pyx_v_i1_low_bin + 1)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = __Pyx_PyInt_From_long((__pyx_v_i2_low_bin + 1)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4); + __pyx_t_5 = 0; + __pyx_t_4 = 0; + __pyx_t_4 = PyObject_GetItem(__pyx_v_hist_data, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_17 = __pyx_v_i; + __pyx_t_5 = PyFloat_FromDouble((((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_w.diminfo[0].strides)) * (1. - __pyx_v_S1_low)) * (1. - __pyx_v_S2_low))); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(PyObject_SetItem(__pyx_v_hist_data, __pyx_t_7, __pyx_t_6) < 0)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":135 + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): # <<<<<<<<<<<<<< + * hist_data[ i1_low_bin+1, i2_low_bin+1 ] += w[i]*(1.-S1_low)*(1.-S2_low) + * + */ + } + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":132 + * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): + * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) + * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): # <<<<<<<<<<<<<< + * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low + */ + } + } + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":138 + * hist_data[ i1_low_bin+1, i2_low_bin+1 ] += w[i]*(1.-S1_low)*(1.-S2_low) + * + * return( hist_data ) # <<<<<<<<<<<<<< + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_hist_data); + __pyx_r = __pyx_v_hist_data; + goto __pyx_L0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":89 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * def histogram_cic_2d( # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] q1, + * np.ndarray[np.float64_t, ndim=1] q2, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_q1.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_q2.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_w.rcbuffer->pybuffer); + __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} + __Pyx_AddTraceback("opmd_viewer.openpmd_timeseries.cython_function.histogram_cic_2d", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + goto __pyx_L2; + __pyx_L0:; + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_q1.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_q2.rcbuffer->pybuffer); + __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_w.rcbuffer->pybuffer); + __pyx_L2:; + __Pyx_XDECREF(__pyx_v_hist_data); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":214 + * # experimental exception made for __getbuffer__ and __releasebuffer__ + * # -- the details of this may change. + * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< + * # This implementation of getbuffer is geared towards Cython + * # requirements, and does not yet fullfill the PEP. + */ + +/* Python wrapper */ +static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ +static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); + __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { + int __pyx_v_copy_shape; + int __pyx_v_i; + int __pyx_v_ndim; + int __pyx_v_endian_detector; + int __pyx_v_little_endian; + int __pyx_v_t; + char *__pyx_v_f; + PyArray_Descr *__pyx_v_descr = 0; + int __pyx_v_offset; + int __pyx_v_hasfields; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + char *__pyx_t_7; + __Pyx_RefNannySetupContext("__getbuffer__", 0); + if (__pyx_v_info != NULL) { + __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(__pyx_v_info->obj); + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":220 + * # of flags + * + * if info == NULL: return # <<<<<<<<<<<<<< + * + * cdef int copy_shape, i, ndim + */ + __pyx_t_1 = ((__pyx_v_info == NULL) != 0); + if (__pyx_t_1) { + __pyx_r = 0; + goto __pyx_L0; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":223 + * + * cdef int copy_shape, i, ndim + * cdef int endian_detector = 1 # <<<<<<<<<<<<<< + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * + */ + __pyx_v_endian_detector = 1; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":224 + * cdef int copy_shape, i, ndim + * cdef int endian_detector = 1 + * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< + * + * ndim = PyArray_NDIM(self) + */ + __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":226 + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * + * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<< + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + */ + __pyx_v_ndim = PyArray_NDIM(__pyx_v_self); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":228 + * ndim = PyArray_NDIM(self) + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * copy_shape = 1 + * else: + */ + __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); + if (__pyx_t_1) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":229 + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + * copy_shape = 1 # <<<<<<<<<<<<<< + * else: + * copy_shape = 0 + */ + __pyx_v_copy_shape = 1; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":228 + * ndim = PyArray_NDIM(self) + * + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * copy_shape = 1 + * else: + */ + goto __pyx_L4; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":231 + * copy_shape = 1 + * else: + * copy_shape = 0 # <<<<<<<<<<<<<< + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + */ + /*else*/ { + __pyx_v_copy_shape = 0; + } + __pyx_L4:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":233 + * copy_shape = 0 + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") + */ + __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L6_bool_binop_done; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":234 + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): # <<<<<<<<<<<<<< + * raise ValueError(u"ndarray is not C contiguous") + * + */ + __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L6_bool_binop_done:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":233 + * copy_shape = 0 + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") + */ + if (__pyx_t_1) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":235 + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 235, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 235, __pyx_L1_error) + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":233 + * copy_shape = 0 + * + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") + */ + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":237 + * raise ValueError(u"ndarray is not C contiguous") + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") + */ + __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L9_bool_binop_done; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":238 + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): # <<<<<<<<<<<<<< + * raise ValueError(u"ndarray is not Fortran contiguous") + * + */ + __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L9_bool_binop_done:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":237 + * raise ValueError(u"ndarray is not C contiguous") + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") + */ + if (__pyx_t_1) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":239 + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< + * + * info.buf = PyArray_DATA(self) + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 239, __pyx_L1_error) + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":237 + * raise ValueError(u"ndarray is not C contiguous") + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") + */ + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":241 + * raise ValueError(u"ndarray is not Fortran contiguous") + * + * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<< + * info.ndim = ndim + * if copy_shape: + */ + __pyx_v_info->buf = PyArray_DATA(__pyx_v_self); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":242 + * + * info.buf = PyArray_DATA(self) + * info.ndim = ndim # <<<<<<<<<<<<<< + * if copy_shape: + * # Allocate new buffer for strides and shape info. + */ + __pyx_v_info->ndim = __pyx_v_ndim; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":243 + * info.buf = PyArray_DATA(self) + * info.ndim = ndim + * if copy_shape: # <<<<<<<<<<<<<< + * # Allocate new buffer for strides and shape info. + * # This is allocated as one block, strides first. + */ + __pyx_t_1 = (__pyx_v_copy_shape != 0); + if (__pyx_t_1) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":246 + * # Allocate new buffer for strides and shape info. + * # This is allocated as one block, strides first. + * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) # <<<<<<<<<<<<<< + * info.shape = info.strides + ndim + * for i in range(ndim): + */ + __pyx_v_info->strides = ((Py_ssize_t *)PyObject_Malloc((((sizeof(Py_ssize_t)) * 2) * ((size_t)__pyx_v_ndim)))); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":247 + * # This is allocated as one block, strides first. + * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) + * info.shape = info.strides + ndim # <<<<<<<<<<<<<< + * for i in range(ndim): + * info.strides[i] = PyArray_STRIDES(self)[i] + */ + __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":248 + * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) + * info.shape = info.strides + ndim + * for i in range(ndim): # <<<<<<<<<<<<<< + * info.strides[i] = PyArray_STRIDES(self)[i] + * info.shape[i] = PyArray_DIMS(self)[i] + */ + __pyx_t_4 = __pyx_v_ndim; + for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { + __pyx_v_i = __pyx_t_5; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":249 + * info.shape = info.strides + ndim + * for i in range(ndim): + * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<< + * info.shape[i] = PyArray_DIMS(self)[i] + * else: + */ + (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":250 + * for i in range(ndim): + * info.strides[i] = PyArray_STRIDES(self)[i] + * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<< + * else: + * info.strides = PyArray_STRIDES(self) + */ + (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]); + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":243 + * info.buf = PyArray_DATA(self) + * info.ndim = ndim + * if copy_shape: # <<<<<<<<<<<<<< + * # Allocate new buffer for strides and shape info. + * # This is allocated as one block, strides first. + */ + goto __pyx_L11; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":252 + * info.shape[i] = PyArray_DIMS(self)[i] + * else: + * info.strides = PyArray_STRIDES(self) # <<<<<<<<<<<<<< + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL + */ + /*else*/ { + __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self)); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":253 + * else: + * info.strides = PyArray_STRIDES(self) + * info.shape = PyArray_DIMS(self) # <<<<<<<<<<<<<< + * info.suboffsets = NULL + * info.itemsize = PyArray_ITEMSIZE(self) + */ + __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self)); + } + __pyx_L11:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":254 + * info.strides = PyArray_STRIDES(self) + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL # <<<<<<<<<<<<<< + * info.itemsize = PyArray_ITEMSIZE(self) + * info.readonly = not PyArray_ISWRITEABLE(self) + */ + __pyx_v_info->suboffsets = NULL; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":255 + * info.shape = PyArray_DIMS(self) + * info.suboffsets = NULL + * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<< + * info.readonly = not PyArray_ISWRITEABLE(self) + * + */ + __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":256 + * info.suboffsets = NULL + * info.itemsize = PyArray_ITEMSIZE(self) + * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<< + * + * cdef int t + */ + __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0)); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":259 + * + * cdef int t + * cdef char* f = NULL # <<<<<<<<<<<<<< + * cdef dtype descr = self.descr + * cdef int offset + */ + __pyx_v_f = NULL; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":260 + * cdef int t + * cdef char* f = NULL + * cdef dtype descr = self.descr # <<<<<<<<<<<<<< + * cdef int offset + * + */ + __pyx_t_3 = ((PyObject *)__pyx_v_self->descr); + __Pyx_INCREF(__pyx_t_3); + __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3); + __pyx_t_3 = 0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":263 + * cdef int offset + * + * cdef bint hasfields = PyDataType_HASFIELDS(descr) # <<<<<<<<<<<<<< + * + * if not hasfields and not copy_shape: + */ + __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":265 + * cdef bint hasfields = PyDataType_HASFIELDS(descr) + * + * if not hasfields and not copy_shape: # <<<<<<<<<<<<<< + * # do not call releasebuffer + * info.obj = None + */ + __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L15_bool_binop_done; + } + __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L15_bool_binop_done:; + if (__pyx_t_1) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":267 + * if not hasfields and not copy_shape: + * # do not call releasebuffer + * info.obj = None # <<<<<<<<<<<<<< + * else: + * # need to call releasebuffer + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); + __pyx_v_info->obj = Py_None; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":265 + * cdef bint hasfields = PyDataType_HASFIELDS(descr) + * + * if not hasfields and not copy_shape: # <<<<<<<<<<<<<< + * # do not call releasebuffer + * info.obj = None + */ + goto __pyx_L14; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":270 + * else: + * # need to call releasebuffer + * info.obj = self # <<<<<<<<<<<<<< + * + * if not hasfields: + */ + /*else*/ { + __Pyx_INCREF(((PyObject *)__pyx_v_self)); + __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); + __pyx_v_info->obj = ((PyObject *)__pyx_v_self); + } + __pyx_L14:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":272 + * info.obj = self + * + * if not hasfields: # <<<<<<<<<<<<<< + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or + */ + __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0); + if (__pyx_t_1) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":273 + * + * if not hasfields: + * t = descr.type_num # <<<<<<<<<<<<<< + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): + */ + __pyx_t_4 = __pyx_v_descr->type_num; + __pyx_v_t = __pyx_t_4; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":274 + * if not hasfields: + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0); + if (!__pyx_t_2) { + goto __pyx_L20_next_or; + } else { + } + __pyx_t_2 = (__pyx_v_little_endian != 0); + if (!__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L19_bool_binop_done; + } + __pyx_L20_next_or:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":275 + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< + * raise ValueError(u"Non-native byte order not supported") + * if t == NPY_BYTE: f = "b" + */ + __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0); + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L19_bool_binop_done; + } + __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0); + __pyx_t_1 = __pyx_t_2; + __pyx_L19_bool_binop_done:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":274 + * if not hasfields: + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + if (__pyx_t_1) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":276 + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 276, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 276, __pyx_L1_error) + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":274 + * if not hasfields: + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":277 + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<< + * elif t == NPY_UBYTE: f = "B" + * elif t == NPY_SHORT: f = "h" + */ + switch (__pyx_v_t) { + case NPY_BYTE: + __pyx_v_f = ((char *)"b"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":278 + * raise ValueError(u"Non-native byte order not supported") + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<< + * elif t == NPY_SHORT: f = "h" + * elif t == NPY_USHORT: f = "H" + */ + case NPY_UBYTE: + __pyx_v_f = ((char *)"B"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":279 + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" + * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<< + * elif t == NPY_USHORT: f = "H" + * elif t == NPY_INT: f = "i" + */ + case NPY_SHORT: + __pyx_v_f = ((char *)"h"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":280 + * elif t == NPY_UBYTE: f = "B" + * elif t == NPY_SHORT: f = "h" + * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<< + * elif t == NPY_INT: f = "i" + * elif t == NPY_UINT: f = "I" + */ + case NPY_USHORT: + __pyx_v_f = ((char *)"H"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":281 + * elif t == NPY_SHORT: f = "h" + * elif t == NPY_USHORT: f = "H" + * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<< + * elif t == NPY_UINT: f = "I" + * elif t == NPY_LONG: f = "l" + */ + case NPY_INT: + __pyx_v_f = ((char *)"i"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":282 + * elif t == NPY_USHORT: f = "H" + * elif t == NPY_INT: f = "i" + * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<< + * elif t == NPY_LONG: f = "l" + * elif t == NPY_ULONG: f = "L" + */ + case NPY_UINT: + __pyx_v_f = ((char *)"I"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":283 + * elif t == NPY_INT: f = "i" + * elif t == NPY_UINT: f = "I" + * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<< + * elif t == NPY_ULONG: f = "L" + * elif t == NPY_LONGLONG: f = "q" + */ + case NPY_LONG: + __pyx_v_f = ((char *)"l"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":284 + * elif t == NPY_UINT: f = "I" + * elif t == NPY_LONG: f = "l" + * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<< + * elif t == NPY_LONGLONG: f = "q" + * elif t == NPY_ULONGLONG: f = "Q" + */ + case NPY_ULONG: + __pyx_v_f = ((char *)"L"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":285 + * elif t == NPY_LONG: f = "l" + * elif t == NPY_ULONG: f = "L" + * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<< + * elif t == NPY_ULONGLONG: f = "Q" + * elif t == NPY_FLOAT: f = "f" + */ + case NPY_LONGLONG: + __pyx_v_f = ((char *)"q"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":286 + * elif t == NPY_ULONG: f = "L" + * elif t == NPY_LONGLONG: f = "q" + * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<< + * elif t == NPY_FLOAT: f = "f" + * elif t == NPY_DOUBLE: f = "d" + */ + case NPY_ULONGLONG: + __pyx_v_f = ((char *)"Q"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":287 + * elif t == NPY_LONGLONG: f = "q" + * elif t == NPY_ULONGLONG: f = "Q" + * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<< + * elif t == NPY_DOUBLE: f = "d" + * elif t == NPY_LONGDOUBLE: f = "g" + */ + case NPY_FLOAT: + __pyx_v_f = ((char *)"f"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":288 + * elif t == NPY_ULONGLONG: f = "Q" + * elif t == NPY_FLOAT: f = "f" + * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<< + * elif t == NPY_LONGDOUBLE: f = "g" + * elif t == NPY_CFLOAT: f = "Zf" + */ + case NPY_DOUBLE: + __pyx_v_f = ((char *)"d"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":289 + * elif t == NPY_FLOAT: f = "f" + * elif t == NPY_DOUBLE: f = "d" + * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<< + * elif t == NPY_CFLOAT: f = "Zf" + * elif t == NPY_CDOUBLE: f = "Zd" + */ + case NPY_LONGDOUBLE: + __pyx_v_f = ((char *)"g"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":290 + * elif t == NPY_DOUBLE: f = "d" + * elif t == NPY_LONGDOUBLE: f = "g" + * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<< + * elif t == NPY_CDOUBLE: f = "Zd" + * elif t == NPY_CLONGDOUBLE: f = "Zg" + */ + case NPY_CFLOAT: + __pyx_v_f = ((char *)"Zf"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":291 + * elif t == NPY_LONGDOUBLE: f = "g" + * elif t == NPY_CFLOAT: f = "Zf" + * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<< + * elif t == NPY_CLONGDOUBLE: f = "Zg" + * elif t == NPY_OBJECT: f = "O" + */ + case NPY_CDOUBLE: + __pyx_v_f = ((char *)"Zd"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":292 + * elif t == NPY_CFLOAT: f = "Zf" + * elif t == NPY_CDOUBLE: f = "Zd" + * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<< + * elif t == NPY_OBJECT: f = "O" + * else: + */ + case NPY_CLONGDOUBLE: + __pyx_v_f = ((char *)"Zg"); + break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":293 + * elif t == NPY_CDOUBLE: f = "Zd" + * elif t == NPY_CLONGDOUBLE: f = "Zg" + * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<< + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + */ + case NPY_OBJECT: + __pyx_v_f = ((char *)"O"); + break; + default: + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":295 + * elif t == NPY_OBJECT: f = "O" + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< + * info.format = f + * return + */ + __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 295, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 295, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 295, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6); + __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 295, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_Raise(__pyx_t_6, 0, 0, 0); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __PYX_ERR(1, 295, __pyx_L1_error) + break; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":296 + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * info.format = f # <<<<<<<<<<<<<< + * return + * else: + */ + __pyx_v_info->format = __pyx_v_f; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":297 + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * info.format = f + * return # <<<<<<<<<<<<<< + * else: + * info.format = PyObject_Malloc(_buffer_format_string_len) + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":272 + * info.obj = self + * + * if not hasfields: # <<<<<<<<<<<<<< + * t = descr.type_num + * if ((descr.byteorder == c'>' and little_endian) or + */ + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":299 + * return + * else: + * info.format = PyObject_Malloc(_buffer_format_string_len) # <<<<<<<<<<<<<< + * info.format[0] = c'^' # Native data types, manual alignment + * offset = 0 + */ + /*else*/ { + __pyx_v_info->format = ((char *)PyObject_Malloc(0xFF)); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":300 + * else: + * info.format = PyObject_Malloc(_buffer_format_string_len) + * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<< + * offset = 0 + * f = _util_dtypestring(descr, info.format + 1, + */ + (__pyx_v_info->format[0]) = '^'; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":301 + * info.format = PyObject_Malloc(_buffer_format_string_len) + * info.format[0] = c'^' # Native data types, manual alignment + * offset = 0 # <<<<<<<<<<<<<< + * f = _util_dtypestring(descr, info.format + 1, + * info.format + _buffer_format_string_len, + */ + __pyx_v_offset = 0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":302 + * info.format[0] = c'^' # Native data types, manual alignment + * offset = 0 + * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<< + * info.format + _buffer_format_string_len, + * &offset) + */ + __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 0xFF), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == ((char *)NULL))) __PYX_ERR(1, 302, __pyx_L1_error) + __pyx_v_f = __pyx_t_7; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":305 + * info.format + _buffer_format_string_len, + * &offset) + * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<< + * + * def __releasebuffer__(ndarray self, Py_buffer* info): + */ + (__pyx_v_f[0]) = '\x00'; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":214 + * # experimental exception made for __getbuffer__ and __releasebuffer__ + * # -- the details of this may change. + * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< + * # This implementation of getbuffer is geared towards Cython + * # requirements, and does not yet fullfill the PEP. + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) { + __Pyx_GOTREF(__pyx_v_info->obj); + __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL; + } + goto __pyx_L2; + __pyx_L0:; + if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) { + __Pyx_GOTREF(Py_None); + __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL; + } + __pyx_L2:; + __Pyx_XDECREF((PyObject *)__pyx_v_descr); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":307 + * f[0] = c'\0' # Terminate format string + * + * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< + * if PyArray_HASFIELDS(self): + * PyObject_Free(info.format) + */ + +/* Python wrapper */ +static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/ +static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0); + __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) { + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("__releasebuffer__", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":308 + * + * def __releasebuffer__(ndarray self, Py_buffer* info): + * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< + * PyObject_Free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + */ + __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0); + if (__pyx_t_1) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":309 + * def __releasebuffer__(ndarray self, Py_buffer* info): + * if PyArray_HASFIELDS(self): + * PyObject_Free(info.format) # <<<<<<<<<<<<<< + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + * PyObject_Free(info.strides) + */ + PyObject_Free(__pyx_v_info->format); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":308 + * + * def __releasebuffer__(ndarray self, Py_buffer* info): + * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< + * PyObject_Free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + */ + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":310 + * if PyArray_HASFIELDS(self): + * PyObject_Free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * PyObject_Free(info.strides) + * # info.shape was stored after info.strides in the same block + */ + __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); + if (__pyx_t_1) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":311 + * PyObject_Free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): + * PyObject_Free(info.strides) # <<<<<<<<<<<<<< + * # info.shape was stored after info.strides in the same block + * + */ + PyObject_Free(__pyx_v_info->strides); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":310 + * if PyArray_HASFIELDS(self): + * PyObject_Free(info.format) + * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< + * PyObject_Free(info.strides) + * # info.shape was stored after info.strides in the same block + */ + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":307 + * f[0] = c'\0' # Terminate format string + * + * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< + * if PyArray_HASFIELDS(self): + * PyObject_Free(info.format) + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":788 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":789 + * + * cdef inline object PyArray_MultiIterNew1(a): + * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew2(a, b): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 789, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":788 + * ctypedef npy_cdouble complex_t + * + * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(1, a) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":791 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":792 + * + * cdef inline object PyArray_MultiIterNew2(a, b): + * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 792, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":791 + * return PyArray_MultiIterNew(1, a) + * + * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(2, a, b) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":794 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":795 + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): + * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 795, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":794 + * return PyArray_MultiIterNew(2, a, b) + * + * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(3, a, b, c) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":797 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, d) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":798 + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): + * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 798, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":797 + * return PyArray_MultiIterNew(3, a, b, c) + * + * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(4, a, b, c, d) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":800 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":801 + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): + * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< + * + * cdef inline tuple PyDataType_SHAPE(dtype d): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 801, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":800 + * return PyArray_MultiIterNew(4, a, b, c, d) + * + * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":803 + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< + * if PyDataType_HASSUBARRAY(d): + * return d.subarray.shape + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__pyx_v_d) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("PyDataType_SHAPE", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":804 + * + * cdef inline tuple PyDataType_SHAPE(dtype d): + * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< + * return d.subarray.shape + * else: + */ + __pyx_t_1 = (PyDataType_HASSUBARRAY(__pyx_v_d) != 0); + if (__pyx_t_1) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":805 + * cdef inline tuple PyDataType_SHAPE(dtype d): + * if PyDataType_HASSUBARRAY(d): + * return d.subarray.shape # <<<<<<<<<<<<<< + * else: + * return () + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject*)__pyx_v_d->subarray->shape)); + __pyx_r = ((PyObject*)__pyx_v_d->subarray->shape); + goto __pyx_L0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":804 + * + * cdef inline tuple PyDataType_SHAPE(dtype d): + * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< + * return d.subarray.shape + * else: + */ + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":807 + * return d.subarray.shape + * else: + * return () # <<<<<<<<<<<<<< + * + * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_empty_tuple); + __pyx_r = __pyx_empty_tuple; + goto __pyx_L0; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":803 + * return PyArray_MultiIterNew(5, a, b, c, d, e) + * + * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< + * if PyDataType_HASSUBARRAY(d): + * return d.subarray.shape + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":809 + * return () + * + * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< + * # Recursive utility function used in __getbuffer__ to get format + * # string. The new location in the format string is returned. + */ + +static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) { + PyArray_Descr *__pyx_v_child = 0; + int __pyx_v_endian_detector; + int __pyx_v_little_endian; + PyObject *__pyx_v_fields = 0; + PyObject *__pyx_v_childname = NULL; + PyObject *__pyx_v_new_offset = NULL; + PyObject *__pyx_v_t = NULL; + char *__pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_t_6; + int __pyx_t_7; + long __pyx_t_8; + char *__pyx_t_9; + __Pyx_RefNannySetupContext("_util_dtypestring", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":814 + * + * cdef dtype child + * cdef int endian_detector = 1 # <<<<<<<<<<<<<< + * cdef bint little_endian = ((&endian_detector)[0] != 0) + * cdef tuple fields + */ + __pyx_v_endian_detector = 1; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":815 + * cdef dtype child + * cdef int endian_detector = 1 + * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< + * cdef tuple fields + * + */ + __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":818 + * cdef tuple fields + * + * for childname in descr.names: # <<<<<<<<<<<<<< + * fields = descr.fields[childname] + * child, new_offset = fields + */ + if (unlikely(__pyx_v_descr->names == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); + __PYX_ERR(1, 818, __pyx_L1_error) + } + __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; + for (;;) { + if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(1, 818, __pyx_L1_error) + #else + __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 818, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3); + __pyx_t_3 = 0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":819 + * + * for childname in descr.names: + * fields = descr.fields[childname] # <<<<<<<<<<<<<< + * child, new_offset = fields + * + */ + if (unlikely(__pyx_v_descr->fields == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 819, __pyx_L1_error) + } + __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 819, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) __PYX_ERR(1, 819, __pyx_L1_error) + __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":820 + * for childname in descr.names: + * fields = descr.fields[childname] + * child, new_offset = fields # <<<<<<<<<<<<<< + * + * if (end - f) - (new_offset - offset[0]) < 15: + */ + if (likely(__pyx_v_fields != Py_None)) { + PyObject* sequence = __pyx_v_fields; + #if !CYTHON_COMPILING_IN_PYPY + Py_ssize_t size = Py_SIZE(sequence); + #else + Py_ssize_t size = PySequence_Size(sequence); + #endif + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(1, 820, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + #else + __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 820, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 820, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #endif + } else { + __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(1, 820, __pyx_L1_error) + } + if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) __PYX_ERR(1, 820, __pyx_L1_error) + __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3)); + __pyx_t_3 = 0; + __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4); + __pyx_t_4 = 0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":822 + * child, new_offset = fields + * + * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + */ + __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 822, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 822, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 822, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0); + if (__pyx_t_6) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":823 + * + * if (end - f) - (new_offset - offset[0]) < 15: + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< + * + * if ((child.byteorder == c'>' and little_endian) or + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 823, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 823, __pyx_L1_error) + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":822 + * child, new_offset = fields + * + * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + */ + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":825 + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0); + if (!__pyx_t_7) { + goto __pyx_L8_next_or; + } else { + } + __pyx_t_7 = (__pyx_v_little_endian != 0); + if (!__pyx_t_7) { + } else { + __pyx_t_6 = __pyx_t_7; + goto __pyx_L7_bool_binop_done; + } + __pyx_L8_next_or:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":826 + * + * if ((child.byteorder == c'>' and little_endian) or + * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< + * raise ValueError(u"Non-native byte order not supported") + * # One could encode it in the format string and have Cython + */ + __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0); + if (__pyx_t_7) { + } else { + __pyx_t_6 = __pyx_t_7; + goto __pyx_L7_bool_binop_done; + } + __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0); + __pyx_t_6 = __pyx_t_7; + __pyx_L7_bool_binop_done:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":825 + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + if (__pyx_t_6) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":827 + * if ((child.byteorder == c'>' and little_endian) or + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * # One could encode it in the format string and have Cython + * # complain instead, BUT: < and > in format strings also imply + */ + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 827, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 827, __pyx_L1_error) + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":825 + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") + * + * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") + */ + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":837 + * + * # Output padding bytes + * while offset[0] < new_offset: # <<<<<<<<<<<<<< + * f[0] = 120 # "x"; pad byte + * f += 1 + */ + while (1) { + __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 837, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 837, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 837, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (!__pyx_t_6) break; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":838 + * # Output padding bytes + * while offset[0] < new_offset: + * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<< + * f += 1 + * offset[0] += 1 + */ + (__pyx_v_f[0]) = 0x78; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":839 + * while offset[0] < new_offset: + * f[0] = 120 # "x"; pad byte + * f += 1 # <<<<<<<<<<<<<< + * offset[0] += 1 + * + */ + __pyx_v_f = (__pyx_v_f + 1); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":840 + * f[0] = 120 # "x"; pad byte + * f += 1 + * offset[0] += 1 # <<<<<<<<<<<<<< + * + * offset[0] += child.itemsize + */ + __pyx_t_8 = 0; + (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1); + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":842 + * offset[0] += 1 + * + * offset[0] += child.itemsize # <<<<<<<<<<<<<< + * + * if not PyDataType_HASFIELDS(child): + */ + __pyx_t_8 = 0; + (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":844 + * offset[0] += child.itemsize + * + * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< + * t = child.type_num + * if end - f < 5: + */ + __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0); + if (__pyx_t_6) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":845 + * + * if not PyDataType_HASFIELDS(child): + * t = child.type_num # <<<<<<<<<<<<<< + * if end - f < 5: + * raise RuntimeError(u"Format string allocated too short.") + */ + __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 845, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4); + __pyx_t_4 = 0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":846 + * if not PyDataType_HASFIELDS(child): + * t = child.type_num + * if end - f < 5: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short.") + * + */ + __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0); + if (__pyx_t_6) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":847 + * t = child.type_num + * if end - f < 5: + * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< + * + * # Until ticket #99 is fixed, use integers to avoid warnings + */ + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 847, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_Raise(__pyx_t_4, 0, 0, 0); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __PYX_ERR(1, 847, __pyx_L1_error) + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":846 + * if not PyDataType_HASFIELDS(child): + * t = child.type_num + * if end - f < 5: # <<<<<<<<<<<<<< + * raise RuntimeError(u"Format string allocated too short.") + * + */ + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":850 + * + * # Until ticket #99 is fixed, use integers to avoid warnings + * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<< + * elif t == NPY_UBYTE: f[0] = 66 #"B" + * elif t == NPY_SHORT: f[0] = 104 #"h" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_BYTE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 850, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 850, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 850, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 98; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":851 + * # Until ticket #99 is fixed, use integers to avoid warnings + * if t == NPY_BYTE: f[0] = 98 #"b" + * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<< + * elif t == NPY_SHORT: f[0] = 104 #"h" + * elif t == NPY_USHORT: f[0] = 72 #"H" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UBYTE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 851, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 851, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 851, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 66; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":852 + * if t == NPY_BYTE: f[0] = 98 #"b" + * elif t == NPY_UBYTE: f[0] = 66 #"B" + * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<< + * elif t == NPY_USHORT: f[0] = 72 #"H" + * elif t == NPY_INT: f[0] = 105 #"i" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_SHORT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 852, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 852, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 852, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x68; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":853 + * elif t == NPY_UBYTE: f[0] = 66 #"B" + * elif t == NPY_SHORT: f[0] = 104 #"h" + * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<< + * elif t == NPY_INT: f[0] = 105 #"i" + * elif t == NPY_UINT: f[0] = 73 #"I" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_USHORT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 853, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 853, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 853, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 72; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":854 + * elif t == NPY_SHORT: f[0] = 104 #"h" + * elif t == NPY_USHORT: f[0] = 72 #"H" + * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<< + * elif t == NPY_UINT: f[0] = 73 #"I" + * elif t == NPY_LONG: f[0] = 108 #"l" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_INT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 854, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 854, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 854, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x69; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":855 + * elif t == NPY_USHORT: f[0] = 72 #"H" + * elif t == NPY_INT: f[0] = 105 #"i" + * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<< + * elif t == NPY_LONG: f[0] = 108 #"l" + * elif t == NPY_ULONG: f[0] = 76 #"L" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UINT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 855, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 855, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 855, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 73; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":856 + * elif t == NPY_INT: f[0] = 105 #"i" + * elif t == NPY_UINT: f[0] = 73 #"I" + * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<< + * elif t == NPY_ULONG: f[0] = 76 #"L" + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 856, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 856, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 856, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x6C; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":857 + * elif t == NPY_UINT: f[0] = 73 #"I" + * elif t == NPY_LONG: f[0] = 108 #"l" + * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<< + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 857, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 857, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 857, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 76; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":858 + * elif t == NPY_LONG: f[0] = 108 #"l" + * elif t == NPY_ULONG: f[0] = 76 #"L" + * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<< + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + * elif t == NPY_FLOAT: f[0] = 102 #"f" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 858, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 858, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 858, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x71; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":859 + * elif t == NPY_ULONG: f[0] = 76 #"L" + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<< + * elif t == NPY_FLOAT: f[0] = 102 #"f" + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 859, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 859, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 859, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 81; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":860 + * elif t == NPY_LONGLONG: f[0] = 113 #"q" + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<< + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_FLOAT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 860, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 860, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 860, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x66; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":861 + * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + * elif t == NPY_FLOAT: f[0] = 102 #"f" + * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<< + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 861, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 861, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 861, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x64; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":862 + * elif t == NPY_FLOAT: f[0] = 102 #"f" + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<< + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 862, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 862, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 862, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 0x67; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":863 + * elif t == NPY_DOUBLE: f[0] = 100 #"d" + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<< + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 863, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 863, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 863, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 90; + (__pyx_v_f[1]) = 0x66; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":864 + * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<< + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg + * elif t == NPY_OBJECT: f[0] = 79 #"O" + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 864, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 864, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 864, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 90; + (__pyx_v_f[1]) = 0x64; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":865 + * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<< + * elif t == NPY_OBJECT: f[0] = 79 #"O" + * else: + */ + __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 865, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 865, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 865, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 90; + (__pyx_v_f[1]) = 0x67; + __pyx_v_f = (__pyx_v_f + 1); + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":866 + * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg + * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<< + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + */ + __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_OBJECT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 866, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 866, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 866, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_6) { + (__pyx_v_f[0]) = 79; + goto __pyx_L15; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":868 + * elif t == NPY_OBJECT: f[0] = 79 #"O" + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< + * f += 1 + * else: + */ + /*else*/ { + __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 868, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 868, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); + __pyx_t_3 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 868, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 868, __pyx_L1_error) + } + __pyx_L15:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":869 + * else: + * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) + * f += 1 # <<<<<<<<<<<<<< + * else: + * # Cython ignores struct boundary information ("T{...}"), + */ + __pyx_v_f = (__pyx_v_f + 1); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":844 + * offset[0] += child.itemsize + * + * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< + * t = child.type_num + * if end - f < 5: + */ + goto __pyx_L13; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":873 + * # Cython ignores struct boundary information ("T{...}"), + * # so don't output it + * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<< + * return f + * + */ + /*else*/ { + __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == ((char *)NULL))) __PYX_ERR(1, 873, __pyx_L1_error) + __pyx_v_f = __pyx_t_9; + } + __pyx_L13:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":818 + * cdef tuple fields + * + * for childname in descr.names: # <<<<<<<<<<<<<< + * fields = descr.fields[childname] + * child, new_offset = fields + */ + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":874 + * # so don't output it + * f = _util_dtypestring(child, f, end, offset) + * return f # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __pyx_v_f; + goto __pyx_L0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":809 + * return () + * + * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< + * # Recursive utility function used in __getbuffer__ to get format + * # string. The new location in the format string is returned. + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_child); + __Pyx_XDECREF(__pyx_v_fields); + __Pyx_XDECREF(__pyx_v_childname); + __Pyx_XDECREF(__pyx_v_new_offset); + __Pyx_XDECREF(__pyx_v_t); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":990 + * + * + * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * cdef PyObject* baseptr + * if base is None: + */ + +static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) { + PyObject *__pyx_v_baseptr; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + __Pyx_RefNannySetupContext("set_array_base", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":992 + * cdef inline void set_array_base(ndarray arr, object base): + * cdef PyObject* baseptr + * if base is None: # <<<<<<<<<<<<<< + * baseptr = NULL + * else: + */ + __pyx_t_1 = (__pyx_v_base == Py_None); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":993 + * cdef PyObject* baseptr + * if base is None: + * baseptr = NULL # <<<<<<<<<<<<<< + * else: + * Py_INCREF(base) # important to do this before decref below! + */ + __pyx_v_baseptr = NULL; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":992 + * cdef inline void set_array_base(ndarray arr, object base): + * cdef PyObject* baseptr + * if base is None: # <<<<<<<<<<<<<< + * baseptr = NULL + * else: + */ + goto __pyx_L3; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":995 + * baseptr = NULL + * else: + * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<< + * baseptr = base + * Py_XDECREF(arr.base) + */ + /*else*/ { + Py_INCREF(__pyx_v_base); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":996 + * else: + * Py_INCREF(base) # important to do this before decref below! + * baseptr = base # <<<<<<<<<<<<<< + * Py_XDECREF(arr.base) + * arr.base = baseptr + */ + __pyx_v_baseptr = ((PyObject *)__pyx_v_base); + } + __pyx_L3:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":997 + * Py_INCREF(base) # important to do this before decref below! + * baseptr = base + * Py_XDECREF(arr.base) # <<<<<<<<<<<<<< + * arr.base = baseptr + * + */ + Py_XDECREF(__pyx_v_arr->base); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":998 + * baseptr = base + * Py_XDECREF(arr.base) + * arr.base = baseptr # <<<<<<<<<<<<<< + * + * cdef inline object get_array_base(ndarray arr): + */ + __pyx_v_arr->base = __pyx_v_baseptr; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":990 + * + * + * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< + * cdef PyObject* baseptr + * if base is None: + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1000 + * arr.base = baseptr + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * if arr.base is NULL: + * return None + */ + +static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("get_array_base", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1001 + * + * cdef inline object get_array_base(ndarray arr): + * if arr.base is NULL: # <<<<<<<<<<<<<< + * return None + * else: + */ + __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0); + if (__pyx_t_1) { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1002 + * cdef inline object get_array_base(ndarray arr): + * if arr.base is NULL: + * return None # <<<<<<<<<<<<<< + * else: + * return arr.base + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(Py_None); + __pyx_r = Py_None; + goto __pyx_L0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1001 + * + * cdef inline object get_array_base(ndarray arr): + * if arr.base is NULL: # <<<<<<<<<<<<<< + * return None + * else: + */ + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1004 + * return None + * else: + * return arr.base # <<<<<<<<<<<<<< + * + * + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)__pyx_v_arr->base)); + __pyx_r = ((PyObject *)__pyx_v_arr->base); + goto __pyx_L0; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1000 + * arr.base = baseptr + * + * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< + * if arr.base is NULL: + * return None + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1009 + * # Versions of the import_* functions which are more suitable for + * # Cython code. + * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< + * try: + * _import_array() + */ + +static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + __Pyx_RefNannySetupContext("import_array", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1010 + * # Cython code. + * cdef inline int import_array() except -1: + * try: # <<<<<<<<<<<<<< + * _import_array() + * except Exception: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1011 + * cdef inline int import_array() except -1: + * try: + * _import_array() # <<<<<<<<<<<<<< + * except Exception: + * raise ImportError("numpy.core.multiarray failed to import") + */ + __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 1011, __pyx_L3_error) + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1010 + * # Cython code. + * cdef inline int import_array() except -1: + * try: # <<<<<<<<<<<<<< + * _import_array() + * except Exception: + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1012 + * try: + * _import_array() + * except Exception: # <<<<<<<<<<<<<< + * raise ImportError("numpy.core.multiarray failed to import") + * + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + if (__pyx_t_4) { + __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 1012, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_7); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1013 + * _import_array() + * except Exception: + * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_umath() except -1: + */ + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 1013, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(1, 1013, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1010 + * # Cython code. + * cdef inline int import_array() except -1: + * try: # <<<<<<<<<<<<<< + * _import_array() + * except Exception: + */ + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L8_try_end:; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1009 + * # Versions of the import_* functions which are more suitable for + * # Cython code. + * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< + * try: + * _import_array() + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1015 + * raise ImportError("numpy.core.multiarray failed to import") + * + * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ + +static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + __Pyx_RefNannySetupContext("import_umath", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1016 + * + * cdef inline int import_umath() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1017 + * cdef inline int import_umath() except -1: + * try: + * _import_umath() # <<<<<<<<<<<<<< + * except Exception: + * raise ImportError("numpy.core.umath failed to import") + */ + __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 1017, __pyx_L3_error) + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1016 + * + * cdef inline int import_umath() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1018 + * try: + * _import_umath() + * except Exception: # <<<<<<<<<<<<<< + * raise ImportError("numpy.core.umath failed to import") + * + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + if (__pyx_t_4) { + __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 1018, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_7); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1019 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_ufunc() except -1: + */ + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 1019, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(1, 1019, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1016 + * + * cdef inline int import_umath() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L8_try_end:; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1015 + * raise ImportError("numpy.core.multiarray failed to import") + * + * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1021 + * raise ImportError("numpy.core.umath failed to import") + * + * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ + +static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + __Pyx_RefNannySetupContext("import_ufunc", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1022 + * + * cdef inline int import_ufunc() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1023 + * cdef inline int import_ufunc() except -1: + * try: + * _import_umath() # <<<<<<<<<<<<<< + * except Exception: + * raise ImportError("numpy.core.umath failed to import") + */ + __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 1023, __pyx_L3_error) + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1022 + * + * cdef inline int import_ufunc() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + } + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L8_try_end; + __pyx_L3_error:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1024 + * try: + * _import_umath() + * except Exception: # <<<<<<<<<<<<<< + * raise ImportError("numpy.core.umath failed to import") + */ + __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); + if (__pyx_t_4) { + __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 1024, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_7); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1025 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + */ + __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 1025, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_Raise(__pyx_t_8, 0, 0, 0); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __PYX_ERR(1, 1025, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1022 + * + * cdef inline int import_ufunc() except -1: + * try: # <<<<<<<<<<<<<< + * _import_umath() + * except Exception: + */ + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L8_try_end:; + } + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1021 + * raise ImportError("numpy.core.umath failed to import") + * + * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_cython_function(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_cython_function}, + {0, NULL} +}; +#endif + +static struct PyModuleDef __pyx_moduledef = { + PyModuleDef_HEAD_INIT, + "cython_function", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; +#endif + +static __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0}, + {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0}, + {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, + {&__pyx_n_s_N, __pyx_k_N, sizeof(__pyx_k_N), 0, 0, 1, 1}, + {&__pyx_n_s_N_selected, __pyx_k_N_selected, sizeof(__pyx_k_N_selected), 0, 0, 1, 1}, + {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0}, + {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, + {&__pyx_n_s_S1_low, __pyx_k_S1_low, sizeof(__pyx_k_S1_low), 0, 0, 1, 1}, + {&__pyx_n_s_S2_low, __pyx_k_S2_low, sizeof(__pyx_k_S2_low), 0, 0, 1, 1}, + {&__pyx_n_s_S_low, __pyx_k_S_low, sizeof(__pyx_k_S_low), 0, 0, 1, 1}, + {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, + {&__pyx_n_s_bin_spacing, __pyx_k_bin_spacing, sizeof(__pyx_k_bin_spacing), 0, 0, 1, 1}, + {&__pyx_n_s_bin_spacing_1, __pyx_k_bin_spacing_1, sizeof(__pyx_k_bin_spacing_1), 0, 0, 1, 1}, + {&__pyx_n_s_bin_spacing_2, __pyx_k_bin_spacing_2, sizeof(__pyx_k_bin_spacing_2), 0, 0, 1, 1}, + {&__pyx_n_s_bins_end, __pyx_k_bins_end, sizeof(__pyx_k_bins_end), 0, 0, 1, 1}, + {&__pyx_n_s_bins_end_1, __pyx_k_bins_end_1, sizeof(__pyx_k_bins_end_1), 0, 0, 1, 1}, + {&__pyx_n_s_bins_end_2, __pyx_k_bins_end_2, sizeof(__pyx_k_bins_end_2), 0, 0, 1, 1}, + {&__pyx_n_s_bins_start, __pyx_k_bins_start, sizeof(__pyx_k_bins_start), 0, 0, 1, 1}, + {&__pyx_n_s_bins_start_1, __pyx_k_bins_start_1, sizeof(__pyx_k_bins_start_1), 0, 0, 1, 1}, + {&__pyx_n_s_bins_start_2, __pyx_k_bins_start_2, sizeof(__pyx_k_bins_start_2), 0, 0, 1, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1}, + {&__pyx_n_s_extract_indices_cython, __pyx_k_extract_indices_cython, sizeof(__pyx_k_extract_indices_cython), 0, 0, 1, 1}, + {&__pyx_n_s_float64, __pyx_k_float64, sizeof(__pyx_k_float64), 0, 0, 1, 1}, + {&__pyx_n_s_hist_data, __pyx_k_hist_data, sizeof(__pyx_k_hist_data), 0, 0, 1, 1}, + {&__pyx_n_s_histogram_cic_1d, __pyx_k_histogram_cic_1d, sizeof(__pyx_k_histogram_cic_1d), 0, 0, 1, 1}, + {&__pyx_n_s_histogram_cic_2d, __pyx_k_histogram_cic_2d, sizeof(__pyx_k_histogram_cic_2d), 0, 0, 1, 1}, + {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, + {&__pyx_n_s_i1_low_bin, __pyx_k_i1_low_bin, sizeof(__pyx_k_i1_low_bin), 0, 0, 1, 1}, + {&__pyx_n_s_i2_low_bin, __pyx_k_i2_low_bin, sizeof(__pyx_k_i2_low_bin), 0, 0, 1, 1}, + {&__pyx_n_s_i_fill, __pyx_k_i_fill, sizeof(__pyx_k_i_fill), 0, 0, 1, 1}, + {&__pyx_n_s_i_low_bin, __pyx_k_i_low_bin, sizeof(__pyx_k_i_low_bin), 0, 0, 1, 1}, + {&__pyx_n_s_i_select, __pyx_k_i_select, sizeof(__pyx_k_i_select), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_inv_spacing, __pyx_k_inv_spacing, sizeof(__pyx_k_inv_spacing), 0, 0, 1, 1}, + {&__pyx_n_s_inv_spacing_1, __pyx_k_inv_spacing_1, sizeof(__pyx_k_inv_spacing_1), 0, 0, 1, 1}, + {&__pyx_n_s_inv_spacing_2, __pyx_k_inv_spacing_2, sizeof(__pyx_k_inv_spacing_2), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_n_ptcl, __pyx_k_n_ptcl, sizeof(__pyx_k_n_ptcl), 0, 0, 1, 1}, + {&__pyx_n_s_nbins, __pyx_k_nbins, sizeof(__pyx_k_nbins), 0, 0, 1, 1}, + {&__pyx_n_s_nbins_1, __pyx_k_nbins_1, sizeof(__pyx_k_nbins_1), 0, 0, 1, 1}, + {&__pyx_n_s_nbins_2, __pyx_k_nbins_2, sizeof(__pyx_k_nbins_2), 0, 0, 1, 1}, + {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0}, + {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0}, + {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, + {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, + {&__pyx_kp_s_numpy_core_multiarray_failed_to, __pyx_k_numpy_core_multiarray_failed_to, sizeof(__pyx_k_numpy_core_multiarray_failed_to), 0, 0, 1, 0}, + {&__pyx_kp_s_numpy_core_umath_failed_to_impor, __pyx_k_numpy_core_umath_failed_to_impor, sizeof(__pyx_k_numpy_core_umath_failed_to_impor), 0, 0, 1, 0}, + {&__pyx_kp_s_opmd_viewer_openpmd_timeseries_c, __pyx_k_opmd_viewer_openpmd_timeseries_c, sizeof(__pyx_k_opmd_viewer_openpmd_timeseries_c), 0, 0, 1, 0}, + {&__pyx_n_s_opmd_viewer_openpmd_timeseries_c_2, __pyx_k_opmd_viewer_openpmd_timeseries_c_2, sizeof(__pyx_k_opmd_viewer_openpmd_timeseries_c_2), 0, 0, 1, 1}, + {&__pyx_n_s_original_indices, __pyx_k_original_indices, sizeof(__pyx_k_original_indices), 0, 0, 1, 1}, + {&__pyx_n_s_pid, __pyx_k_pid, sizeof(__pyx_k_pid), 0, 0, 1, 1}, + {&__pyx_n_s_preserve_particle_index, __pyx_k_preserve_particle_index, sizeof(__pyx_k_preserve_particle_index), 0, 0, 1, 1}, + {&__pyx_n_s_q1, __pyx_k_q1, sizeof(__pyx_k_q1), 0, 0, 1, 1}, + {&__pyx_n_s_q1_cell, __pyx_k_q1_cell, sizeof(__pyx_k_q1_cell), 0, 0, 1, 1}, + {&__pyx_n_s_q2, __pyx_k_q2, sizeof(__pyx_k_q2), 0, 0, 1, 1}, + {&__pyx_n_s_q2_cell, __pyx_k_q2_cell, sizeof(__pyx_k_q2_cell), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_selected_indices, __pyx_k_selected_indices, sizeof(__pyx_k_selected_indices), 0, 0, 1, 1}, + {&__pyx_n_s_selected_pid, __pyx_k_selected_pid, sizeof(__pyx_k_selected_pid), 0, 0, 1, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0}, + {&__pyx_n_s_w, __pyx_k_w, sizeof(__pyx_k_w), 0, 0, 1, 1}, + {&__pyx_n_s_xrange, __pyx_k_xrange, sizeof(__pyx_k_xrange), 0, 0, 1, 1}, + {&__pyx_n_s_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} +}; +static int __Pyx_InitCachedBuiltins(void) { + #if PY_MAJOR_VERSION >= 3 + __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_xrange) __PYX_ERR(0, 73, __pyx_L1_error) + #else + __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_xrange); if (!__pyx_builtin_xrange) __PYX_ERR(0, 73, __pyx_L1_error) + #endif + __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(1, 235, __pyx_L1_error) + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(1, 248, __pyx_L1_error) + __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(1, 823, __pyx_L1_error) + __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(1, 1013, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":235 + * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): + * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< + * + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + */ + __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple_)) __PYX_ERR(1, 235, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple_); + __Pyx_GIVEREF(__pyx_tuple_); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":239 + * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) + * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): + * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< + * + * info.buf = PyArray_DATA(self) + */ + __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__2); + __Pyx_GIVEREF(__pyx_tuple__2); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":276 + * if ((descr.byteorder == c'>' and little_endian) or + * (descr.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * if t == NPY_BYTE: f = "b" + * elif t == NPY_UBYTE: f = "B" + */ + __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(1, 276, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__3); + __Pyx_GIVEREF(__pyx_tuple__3); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":823 + * + * if (end - f) - (new_offset - offset[0]) < 15: + * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< + * + * if ((child.byteorder == c'>' and little_endian) or + */ + __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 823, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__4); + __Pyx_GIVEREF(__pyx_tuple__4); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":827 + * if ((child.byteorder == c'>' and little_endian) or + * (child.byteorder == c'<' and not little_endian)): + * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< + * # One could encode it in the format string and have Cython + * # complain instead, BUT: < and > in format strings also imply + */ + __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 827, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__5); + __Pyx_GIVEREF(__pyx_tuple__5); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":847 + * t = child.type_num + * if end - f < 5: + * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< + * + * # Until ticket #99 is fixed, use integers to avoid warnings + */ + __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 847, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__6); + __Pyx_GIVEREF(__pyx_tuple__6); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1013 + * _import_array() + * except Exception: + * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_umath() except -1: + */ + __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_multiarray_failed_to); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(1, 1013, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__7); + __Pyx_GIVEREF(__pyx_tuple__7); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1019 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + * + * cdef inline int import_ufunc() except -1: + */ + __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_umath_failed_to_impor); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(1, 1019, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__8); + __Pyx_GIVEREF(__pyx_tuple__8); + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1025 + * _import_umath() + * except Exception: + * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< + */ + __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_umath_failed_to_impor); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(1, 1025, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__9); + __Pyx_GIVEREF(__pyx_tuple__9); + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":9 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * def extract_indices_cython( # <<<<<<<<<<<<<< + * np.ndarray[np.int64_t, ndim=1] original_indices, + * np.ndarray[np.int64_t, ndim=1] selected_indices, + */ + __pyx_tuple__10 = PyTuple_Pack(10, __pyx_n_s_original_indices, __pyx_n_s_selected_indices, __pyx_n_s_pid, __pyx_n_s_selected_pid, __pyx_n_s_preserve_particle_index, __pyx_n_s_i, __pyx_n_s_i_select, __pyx_n_s_i_fill, __pyx_n_s_N, __pyx_n_s_N_selected); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__10); + __Pyx_GIVEREF(__pyx_tuple__10); + __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(5, 0, 10, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_opmd_viewer_openpmd_timeseries_c, __pyx_n_s_extract_indices_cython, 9, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) __PYX_ERR(0, 9, __pyx_L1_error) + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":51 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * def histogram_cic_1d( # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] q1, + * np.ndarray[np.float64_t, ndim=1] w, + */ + __pyx_tuple__12 = PyTuple_Pack(13, __pyx_n_s_q1, __pyx_n_s_w, __pyx_n_s_nbins, __pyx_n_s_bins_start, __pyx_n_s_bins_end, __pyx_n_s_bin_spacing, __pyx_n_s_inv_spacing, __pyx_n_s_n_ptcl, __pyx_n_s_i_low_bin, __pyx_n_s_q1_cell, __pyx_n_s_S_low, __pyx_n_s_hist_data, __pyx_n_s_i); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__12); + __Pyx_GIVEREF(__pyx_tuple__12); + __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(5, 0, 13, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_opmd_viewer_openpmd_timeseries_c, __pyx_n_s_histogram_cic_1d, 51, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) __PYX_ERR(0, 51, __pyx_L1_error) + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":89 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * def histogram_cic_2d( # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] q1, + * np.ndarray[np.float64_t, ndim=1] q2, + */ + __pyx_tuple__14 = PyTuple_Pack(22, __pyx_n_s_q1, __pyx_n_s_q2, __pyx_n_s_w, __pyx_n_s_nbins_1, __pyx_n_s_bins_start_1, __pyx_n_s_bins_end_1, __pyx_n_s_nbins_2, __pyx_n_s_bins_start_2, __pyx_n_s_bins_end_2, __pyx_n_s_bin_spacing_1, __pyx_n_s_inv_spacing_1, __pyx_n_s_bin_spacing_2, __pyx_n_s_inv_spacing_2, __pyx_n_s_n_ptcl, __pyx_n_s_i1_low_bin, __pyx_n_s_i2_low_bin, __pyx_n_s_q1_cell, __pyx_n_s_q2_cell, __pyx_n_s_S1_low, __pyx_n_s_S2_low, __pyx_n_s_hist_data, __pyx_n_s_i); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(0, 89, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__14); + __Pyx_GIVEREF(__pyx_tuple__14); + __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(9, 0, 22, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_opmd_viewer_openpmd_timeseries_c, __pyx_n_s_histogram_cic_2d, 89, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) __PYX_ERR(0, 89, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_InitGlobals(void) { + if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + return 0; + __pyx_L1_error:; + return -1; +} + +#if PY_MAJOR_VERSION < 3 +PyMODINIT_FUNC initcython_function(void); /*proto*/ +PyMODINIT_FUNC initcython_function(void) +#else +PyMODINIT_FUNC PyInit_cython_function(void); /*proto*/ +PyMODINIT_FUNC PyInit_cython_function(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name) { + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + result = PyDict_SetItemString(moddict, to_name, value); + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__") < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__") < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__") < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__") < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static int __pyx_pymod_exec_cython_function(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + PyObject *__pyx_t_1 = NULL; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m && __pyx_m == __pyx_pyinit_module) return 0; + #endif + #if CYTHON_REFNANNY + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); + if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); + } + #endif + __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_cython_function(void)", 0); + if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + #ifdef WITH_THREAD /* Python build with threading support? */ + PyEval_InitThreads(); + #endif + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("cython_function", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + #endif + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + #if CYTHON_COMPILING_IN_PYPY + Py_INCREF(__pyx_b); + #endif + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_opmd_viewer__openpmd_timeseries__cython_function) { + if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "opmd_viewer.openpmd_timeseries.cython_function")) { + if (unlikely(PyDict_SetItemString(modules, "opmd_viewer.openpmd_timeseries.cython_function", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global init code ---*/ + /*--- Variable export code ---*/ + /*--- Function export code ---*/ + /*--- Type init code ---*/ + /*--- Type import code ---*/ + __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", + #if CYTHON_COMPILING_IN_PYPY + sizeof(PyTypeObject), + #else + sizeof(PyHeapTypeObject), + #endif + 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) __PYX_ERR(2, 9, __pyx_L1_error) + __pyx_ptype_7cpython_4bool_bool = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "bool", sizeof(PyBoolObject), 0); if (unlikely(!__pyx_ptype_7cpython_4bool_bool)) __PYX_ERR(3, 8, __pyx_L1_error) + __pyx_ptype_7cpython_7complex_complex = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "complex", sizeof(PyComplexObject), 0); if (unlikely(!__pyx_ptype_7cpython_7complex_complex)) __PYX_ERR(4, 15, __pyx_L1_error) + __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) __PYX_ERR(1, 163, __pyx_L1_error) + __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) __PYX_ERR(1, 185, __pyx_L1_error) + __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) __PYX_ERR(1, 189, __pyx_L1_error) + __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) __PYX_ERR(1, 198, __pyx_L1_error) + __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) __PYX_ERR(1, 885, __pyx_L1_error) + /*--- Variable import code ---*/ + /*--- Function import code ---*/ + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":1 + * import numpy as np # <<<<<<<<<<<<<< + * cimport numpy as np + * from cpython cimport bool + */ + __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":9 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * def extract_indices_cython( # <<<<<<<<<<<<<< + * np.ndarray[np.int64_t, ndim=1] original_indices, + * np.ndarray[np.int64_t, ndim=1] selected_indices, + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11opmd_viewer_18openpmd_timeseries_15cython_function_1extract_indices_cython, NULL, __pyx_n_s_opmd_viewer_openpmd_timeseries_c_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_extract_indices_cython, __pyx_t_1) < 0) __PYX_ERR(0, 9, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":51 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * def histogram_cic_1d( # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] q1, + * np.ndarray[np.float64_t, ndim=1] w, + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11opmd_viewer_18openpmd_timeseries_15cython_function_3histogram_cic_1d, NULL, __pyx_n_s_opmd_viewer_openpmd_timeseries_c_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_histogram_cic_1d, __pyx_t_1) < 0) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":89 + * @cython.boundscheck(False) + * @cython.wraparound(False) + * def histogram_cic_2d( # <<<<<<<<<<<<<< + * np.ndarray[np.float64_t, ndim=1] q1, + * np.ndarray[np.float64_t, ndim=1] q2, + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11opmd_viewer_18openpmd_timeseries_15cython_function_5histogram_cic_2d, NULL, __pyx_n_s_opmd_viewer_openpmd_timeseries_c_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_histogram_cic_2d, __pyx_t_1) < 0) __PYX_ERR(0, 89, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":1 + * import numpy as np # <<<<<<<<<<<<<< + * cimport numpy as np + * from cpython cimport bool + */ + __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1021 + * raise ImportError("numpy.core.umath failed to import") + * + * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< + * try: + * _import_umath() + */ + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + if (__pyx_m) { + if (__pyx_d) { + __Pyx_AddTraceback("init opmd_viewer.openpmd_timeseries.cython_function", 0, __pyx_lineno, __pyx_filename); + } + Py_DECREF(__pyx_m); __pyx_m = 0; + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init opmd_viewer.openpmd_timeseries.cython_function"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule((char *)modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); + if (unlikely(!result)) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* RaiseDoubleKeywords */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION >= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + while (PyDict_Next(kwds, &pos, &key, &value)) { + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; + continue; + } + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = (**name == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION < 3 + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + return -1; +} + +/* ArgTypeTest */ +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) +{ + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + else if (exact) { + #if PY_MAJOR_VERSION == 2 + if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; + #endif + } + else { + if (likely(__Pyx_TypeCheck(obj, type))) return 1; + } + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", + name, type->tp_name, Py_TYPE(obj)->tp_name); + return 0; +} + +/* IsLittleEndian */ +static CYTHON_INLINE int __Pyx_Is_Little_Endian(void) +{ + union { + uint32_t u32; + uint8_t u8[4]; + } S; + S.u32 = 0x01020304; + return S.u8[0] == 4; +} + +/* BufferFormatCheck */ +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type) { + stack[0].field = &ctx->root; + stack[0].parent_offset = 0; + ctx->root.type = type; + ctx->root.name = "buffer dtype"; + ctx->root.offset = 0; + ctx->head = stack; + ctx->head->field = &ctx->root; + ctx->fmt_offset = 0; + ctx->head->parent_offset = 0; + ctx->new_packmode = '@'; + ctx->enc_packmode = '@'; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->is_complex = 0; + ctx->is_valid_array = 0; + ctx->struct_alignment = 0; + while (type->typegroup == 'S') { + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = 0; + type = type->fields->type; + } +} +static int __Pyx_BufFmt_ParseNumber(const char** ts) { + int count; + const char* t = *ts; + if (*t < '0' || *t > '9') { + return -1; + } else { + count = *t++ - '0'; + while (*t >= '0' && *t < '9') { + count *= 10; + count += *t++ - '0'; + } + } + *ts = t; + return count; +} +static int __Pyx_BufFmt_ExpectNumber(const char **ts) { + int number = __Pyx_BufFmt_ParseNumber(ts); + if (number == -1) + PyErr_Format(PyExc_ValueError,\ + "Does not understand character buffer dtype format string ('%c')", **ts); + return number; +} +static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { + PyErr_Format(PyExc_ValueError, + "Unexpected format string character: '%c'", ch); +} +static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { + switch (ch) { + case 'c': return "'char'"; + case 'b': return "'signed char'"; + case 'B': return "'unsigned char'"; + case 'h': return "'short'"; + case 'H': return "'unsigned short'"; + case 'i': return "'int'"; + case 'I': return "'unsigned int'"; + case 'l': return "'long'"; + case 'L': return "'unsigned long'"; + case 'q': return "'long long'"; + case 'Q': return "'unsigned long long'"; + case 'f': return (is_complex ? "'complex float'" : "'float'"); + case 'd': return (is_complex ? "'complex double'" : "'double'"); + case 'g': return (is_complex ? "'complex long double'" : "'long double'"); + case 'T': return "a struct"; + case 'O': return "Python object"; + case 'P': return "a pointer"; + case 's': case 'p': return "a string"; + case 0: return "end"; + default: return "unparseable format string"; + } +} +static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return 2; + case 'i': case 'I': case 'l': case 'L': return 4; + case 'q': case 'Q': return 8; + case 'f': return (is_complex ? 8 : 4); + case 'd': return (is_complex ? 16 : 8); + case 'g': { + PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); + return 0; + } + case 'O': case 'P': return sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { + switch (ch) { + case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(short); + case 'i': case 'I': return sizeof(int); + case 'l': case 'L': return sizeof(long); + #ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(PY_LONG_LONG); + #endif + case 'f': return sizeof(float) * (is_complex ? 2 : 1); + case 'd': return sizeof(double) * (is_complex ? 2 : 1); + case 'g': return sizeof(long double) * (is_complex ? 2 : 1); + case 'O': case 'P': return sizeof(void*); + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} +typedef struct { char c; short x; } __Pyx_st_short; +typedef struct { char c; int x; } __Pyx_st_int; +typedef struct { char c; long x; } __Pyx_st_long; +typedef struct { char c; float x; } __Pyx_st_float; +typedef struct { char c; double x; } __Pyx_st_double; +typedef struct { char c; long double x; } __Pyx_st_longdouble; +typedef struct { char c; void *x; } __Pyx_st_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; +#endif +static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_st_float) - sizeof(float); + case 'd': return sizeof(__Pyx_st_double) - sizeof(double); + case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +/* These are for computing the padding at the end of the struct to align + on the first member of the struct. This will probably the same as above, + but we don't have any guarantees. + */ +typedef struct { short x; char c; } __Pyx_pad_short; +typedef struct { int x; char c; } __Pyx_pad_int; +typedef struct { long x; char c; } __Pyx_pad_long; +typedef struct { float x; char c; } __Pyx_pad_float; +typedef struct { double x; char c; } __Pyx_pad_double; +typedef struct { long double x; char c; } __Pyx_pad_longdouble; +typedef struct { void *x; char c; } __Pyx_pad_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; +#endif +static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; + case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); + case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); + case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { + switch (ch) { + case 'c': + return 'H'; + case 'b': case 'h': case 'i': + case 'l': case 'q': case 's': case 'p': + return 'I'; + case 'B': case 'H': case 'I': case 'L': case 'Q': + return 'U'; + case 'f': case 'd': case 'g': + return (is_complex ? 'C' : 'R'); + case 'O': + return 'O'; + case 'P': + return 'P'; + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} +static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { + if (ctx->head == NULL || ctx->head->field == &ctx->root) { + const char* expected; + const char* quote; + if (ctx->head == NULL) { + expected = "end"; + quote = ""; + } else { + expected = ctx->head->field->type->name; + quote = "'"; + } + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected %s%s%s but got %s", + quote, expected, quote, + __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); + } else { + __Pyx_StructField* field = ctx->head->field; + __Pyx_StructField* parent = (ctx->head - 1)->field; + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", + field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), + parent->type->name, field->name); + } +} +static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { + char group; + size_t size, offset, arraysize = 1; + if (ctx->enc_type == 0) return 0; + if (ctx->head->field->type->arraysize[0]) { + int i, ndim = 0; + if (ctx->enc_type == 's' || ctx->enc_type == 'p') { + ctx->is_valid_array = ctx->head->field->type->ndim == 1; + ndim = 1; + if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { + PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %zu", + ctx->head->field->type->arraysize[0], ctx->enc_count); + return -1; + } + } + if (!ctx->is_valid_array) { + PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", + ctx->head->field->type->ndim, ndim); + return -1; + } + for (i = 0; i < ctx->head->field->type->ndim; i++) { + arraysize *= ctx->head->field->type->arraysize[i]; + } + ctx->is_valid_array = 0; + ctx->enc_count = 1; + } + group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); + do { + __Pyx_StructField* field = ctx->head->field; + __Pyx_TypeInfo* type = field->type; + if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { + size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); + } else { + size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); + } + if (ctx->enc_packmode == '@') { + size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); + size_t align_mod_offset; + if (align_at == 0) return -1; + align_mod_offset = ctx->fmt_offset % align_at; + if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; + if (ctx->struct_alignment == 0) + ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, + ctx->is_complex); + } + if (type->size != size || type->typegroup != group) { + if (type->typegroup == 'C' && type->fields != NULL) { + size_t parent_offset = ctx->head->parent_offset + field->offset; + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = parent_offset; + continue; + } + if ((type->typegroup == 'H' || group == 'H') && type->size == size) { + } else { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + } + offset = ctx->head->parent_offset + field->offset; + if (ctx->fmt_offset != offset) { + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", + (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); + return -1; + } + ctx->fmt_offset += size; + if (arraysize) + ctx->fmt_offset += (arraysize - 1) * size; + --ctx->enc_count; + while (1) { + if (field == &ctx->root) { + ctx->head = NULL; + if (ctx->enc_count != 0) { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + break; + } + ctx->head->field = ++field; + if (field->type == NULL) { + --ctx->head; + field = ctx->head->field; + continue; + } else if (field->type->typegroup == 'S') { + size_t parent_offset = ctx->head->parent_offset + field->offset; + if (field->type->fields->type == NULL) continue; + field = field->type->fields; + ++ctx->head; + ctx->head->field = field; + ctx->head->parent_offset = parent_offset; + break; + } else { + break; + } + } + } while (ctx->enc_count); + ctx->enc_type = 0; + ctx->is_complex = 0; + return 0; +} +static PyObject * +__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) +{ + const char *ts = *tsp; + int i = 0, number; + int ndim = ctx->head->field->type->ndim; +; + ++ts; + if (ctx->new_count != 1) { + PyErr_SetString(PyExc_ValueError, + "Cannot handle repeated arrays in format string"); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + while (*ts && *ts != ')') { + switch (*ts) { + case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; + default: break; + } + number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return NULL; + if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) + return PyErr_Format(PyExc_ValueError, + "Expected a dimension of size %zu, got %d", + ctx->head->field->type->arraysize[i], number); + if (*ts != ',' && *ts != ')') + return PyErr_Format(PyExc_ValueError, + "Expected a comma in format string, got '%c'", *ts); + if (*ts == ',') ts++; + i++; + } + if (i != ndim) + return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", + ctx->head->field->type->ndim, i); + if (!*ts) { + PyErr_SetString(PyExc_ValueError, + "Unexpected end of format string, expected ')'"); + return NULL; + } + ctx->is_valid_array = 1; + ctx->new_count = 1; + *tsp = ++ts; + return Py_None; +} +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { + int got_Z = 0; + while (1) { + switch(*ts) { + case 0: + if (ctx->enc_type != 0 && ctx->head == NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + if (ctx->head != NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + return ts; + case ' ': + case '\r': + case '\n': + ++ts; + break; + case '<': + if (!__Pyx_Is_Little_Endian()) { + PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '>': + case '!': + if (__Pyx_Is_Little_Endian()) { + PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); + return NULL; + } + ctx->new_packmode = '='; + ++ts; + break; + case '=': + case '@': + case '^': + ctx->new_packmode = *ts++; + break; + case 'T': + { + const char* ts_after_sub; + size_t i, struct_count = ctx->new_count; + size_t struct_alignment = ctx->struct_alignment; + ctx->new_count = 1; + ++ts; + if (*ts != '{') { + PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + ctx->enc_count = 0; + ctx->struct_alignment = 0; + ++ts; + ts_after_sub = ts; + for (i = 0; i != struct_count; ++i) { + ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); + if (!ts_after_sub) return NULL; + } + ts = ts_after_sub; + if (struct_alignment) ctx->struct_alignment = struct_alignment; + } + break; + case '}': + { + size_t alignment = ctx->struct_alignment; + ++ts; + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_type = 0; + if (alignment && ctx->fmt_offset % alignment) { + ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); + } + } + return ts; + case 'x': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->fmt_offset += ctx->new_count; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->enc_packmode = ctx->new_packmode; + ++ts; + break; + case 'Z': + got_Z = 1; + ++ts; + if (*ts != 'f' && *ts != 'd' && *ts != 'g') { + __Pyx_BufFmt_RaiseUnexpectedChar('Z'); + return NULL; + } + case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': + case 'l': case 'L': case 'q': case 'Q': + case 'f': case 'd': case 'g': + case 'O': case 'p': + if (ctx->enc_type == *ts && got_Z == ctx->is_complex && + ctx->enc_packmode == ctx->new_packmode) { + ctx->enc_count += ctx->new_count; + ctx->new_count = 1; + got_Z = 0; + ++ts; + break; + } + case 's': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_count = ctx->new_count; + ctx->enc_packmode = ctx->new_packmode; + ctx->enc_type = *ts; + ctx->is_complex = got_Z; + ++ts; + ctx->new_count = 1; + got_Z = 0; + break; + case ':': + ++ts; + while(*ts != ':') ++ts; + ++ts; + break; + case '(': + if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL; + break; + default: + { + int number = __Pyx_BufFmt_ExpectNumber(&ts); + if (number == -1) return NULL; + ctx->new_count = (size_t)number; + } + } + } +} + +/* BufferGetAndValidate */ + static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { + if (unlikely(info->buf == NULL)) return; + if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; + __Pyx_ReleaseBuffer(info); +} +static void __Pyx_ZeroBuffer(Py_buffer* buf) { + buf->buf = NULL; + buf->obj = NULL; + buf->strides = __Pyx_zeros; + buf->shape = __Pyx_zeros; + buf->suboffsets = __Pyx_minusones; +} +static int __Pyx__GetBufferAndValidate( + Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, + int nd, int cast, __Pyx_BufFmt_StackElem* stack) +{ + buf->buf = NULL; + if (unlikely(__Pyx_GetBuffer(obj, buf, flags) == -1)) { + __Pyx_ZeroBuffer(buf); + return -1; + } + if (unlikely(buf->ndim != nd)) { + PyErr_Format(PyExc_ValueError, + "Buffer has wrong number of dimensions (expected %d, got %d)", + nd, buf->ndim); + goto fail; + } + if (!cast) { + __Pyx_BufFmt_Context ctx; + __Pyx_BufFmt_Init(&ctx, stack, dtype); + if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; + } + if (unlikely((unsigned)buf->itemsize != dtype->size)) { + PyErr_Format(PyExc_ValueError, + "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", + buf->itemsize, (buf->itemsize > 1) ? "s" : "", + dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); + goto fail; + } + if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; + return 0; +fail:; + __Pyx_SafeReleaseBuffer(buf); + return -1; +} + +/* PyErrFetchRestore */ + #if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +} +#endif + +/* GetModuleGlobalName */ + static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) { + PyObject *result; +#if !CYTHON_AVOID_BORROWED_REFS + result = PyDict_GetItem(__pyx_d, name); + if (likely(result)) { + Py_INCREF(result); + } else { +#else + result = PyObject_GetItem(__pyx_d, name); + if (!result) { + PyErr_Clear(); +#endif + result = __Pyx_GetBuiltinName(name); + } + return result; +} + +/* PyObjectCall */ + #if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = func->ob_type->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* GetItemInt */ + static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (!j) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyList_GET_SIZE(o); + } + if ((!boundscheck) || likely((0 <= wrapped_i) & (wrapped_i < PyList_GET_SIZE(o)))) { + PyObject *r = PyList_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyTuple_GET_SIZE(o); + } + if ((!boundscheck) || likely((0 <= wrapped_i) & (wrapped_i < PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) { + PyObject *r = PyList_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } + else if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } else { + PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; + if (likely(m && m->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { + Py_ssize_t l = m->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + } + return m->sq_item(o, i); + } + } +#else + if (is_list || PySequence_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +} + +/* SetItemInt */ + static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) { + int r; + if (!j) return -1; + r = PyObject_SetItem(o, j, v); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int is_list, + CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o)); + if ((!boundscheck) || likely((n >= 0) & (n < PyList_GET_SIZE(o)))) { + PyObject* old = PyList_GET_ITEM(o, n); + Py_INCREF(v); + PyList_SET_ITEM(o, n, v); + Py_DECREF(old); + return 1; + } + } else { + PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; + if (likely(m && m->sq_ass_item)) { + if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { + Py_ssize_t l = m->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return -1; + PyErr_Clear(); + } + } + return m->sq_ass_item(o, i, v); + } + } +#else +#if CYTHON_COMPILING_IN_PYPY + if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) { +#else + if (is_list || PySequence_Check(o)) { +#endif + return PySequence_SetItem(o, i, v); + } +#endif + return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v); +} + +/* RaiseException */ + #if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, + CYTHON_UNUSED PyObject *cause) { + __Pyx_PyThreadState_declare + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { +#if CYTHON_COMPILING_IN_PYPY + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#else + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* RaiseTooManyValuesToUnpack */ + static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* RaiseNeedMoreValuesToUnpack */ + static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* RaiseNoneIterError */ + static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); +} + +/* ExtTypeTest */ + static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + if (likely(__Pyx_TypeCheck(obj, type))) + return 1; + PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", + Py_TYPE(obj)->tp_name, type->tp_name); + return 0; +} + +/* SaveResetException */ + #if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if PY_VERSION_HEX >= 0x030700A2 + *type = tstate->exc_state.exc_type; + *value = tstate->exc_state.exc_value; + *tb = tstate->exc_state.exc_traceback; + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + #endif + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if PY_VERSION_HEX >= 0x030700A2 + tmp_type = tstate->exc_state.exc_type; + tmp_value = tstate->exc_state.exc_value; + tmp_tb = tstate->exc_state.exc_traceback; + tstate->exc_state.exc_type = type; + tstate->exc_state.exc_value = value; + tstate->exc_state.exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +#endif + +/* PyErrExceptionMatches */ + #if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; icurexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; + if (unlikely(PyTuple_Check(err))) + return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); +} +#endif + +/* GetException */ + #if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { +#endif + PyObject *local_type, *local_value, *local_tb; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if PY_VERSION_HEX >= 0x030700A2 + tmp_type = tstate->exc_state.exc_type; + tmp_value = tstate->exc_state.exc_value; + tmp_tb = tstate->exc_state.exc_traceback; + tstate->exc_state.exc_type = local_type; + tstate->exc_state.exc_value = local_value; + tstate->exc_state.exc_traceback = local_tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + +/* Import */ + static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *empty_list = 0; + PyObject *module = 0; + PyObject *global_dict = 0; + PyObject *empty_dict = 0; + PyObject *list; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (!py_import) + goto bad; + #endif + if (from_list) + list = from_list; + else { + empty_list = PyList_New(0); + if (!empty_list) + goto bad; + list = empty_list; + } + global_dict = PyModule_GetDict(__pyx_m); + if (!global_dict) + goto bad; + empty_dict = PyDict_New(); + if (!empty_dict) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if (strchr(__Pyx_MODULE_NAME, '.')) { + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, 1); + if (!module) { + if (!PyErr_ExceptionMatches(PyExc_ImportError)) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (!py_level) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, global_dict, empty_dict, list, py_level, NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, level); + #endif + } + } +bad: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + Py_XDECREF(empty_list); + Py_XDECREF(empty_dict); + return module; +} + +/* CLineInTraceback */ + #ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + use_cline = PyDict_GetItem(*cython_runtime_dict, __pyx_n_s_cline_in_traceback); + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (PyObject_Not(use_cline) != 0) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ + static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} + +/* AddTraceback */ + #include "compile.h" +#include "frameobject.h" +#include "traceback.h" +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyObject *py_srcfile = 0; + PyObject *py_funcname = 0; + #if PY_MAJOR_VERSION < 3 + py_srcfile = PyString_FromString(filename); + #else + py_srcfile = PyUnicode_FromString(filename); + #endif + if (!py_srcfile) goto bad; + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + #else + py_funcname = PyUnicode_FromString(funcname); + #endif + } + if (!py_funcname) goto bad; + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + Py_DECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_srcfile); + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) goto bad; + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} + +#if PY_MAJOR_VERSION < 3 +static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { + if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); + if (__Pyx_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags); + PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name); + return -1; +} +static void __Pyx_ReleaseBuffer(Py_buffer *view) { + PyObject *obj = view->obj; + if (!obj) return; + if (PyObject_CheckBuffer(obj)) { + PyBuffer_Release(view); + return; + } + if ((0)) {} + else if (__Pyx_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); + view->obj = NULL; + Py_DECREF(obj); +} +#endif + + + /* CIntFromPyVerify */ + #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value) { + const unsigned int neg_one = (unsigned int) -1, const_zero = (unsigned int) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(unsigned int) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(unsigned int) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(unsigned int) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(unsigned int) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(unsigned int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(unsigned int), + little, !is_unsigned); + } +} + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { + const int neg_one = (int) -1, const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(int) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(int) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(int), + little, !is_unsigned); + } +} + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) -1, const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); + } +} + +/* Declarations */ + #if CYTHON_CCOMPLEX + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + return ::std::complex< float >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + return x + y*(__pyx_t_float_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { + __pyx_t_float_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +/* Arithmetic */ + #if CYTHON_CCOMPLEX +#else + static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + #if 1 + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + if (b.imag == 0) { + return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); + } else if (fabsf(b.real) >= fabsf(b.imag)) { + if (b.real == 0 && b.imag == 0) { + return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.imag); + } else { + float r = b.imag / b.real; + float s = 1.0 / (b.real + b.imag * r); + return __pyx_t_float_complex_from_parts( + (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); + } + } else { + float r = b.real / b.imag; + float s = 1.0 / (b.imag + b.real * r); + return __pyx_t_float_complex_from_parts( + (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); + } + } + #else + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + if (b.imag == 0) { + return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); + } else { + float denom = b.real * b.real + b.imag * b.imag; + return __pyx_t_float_complex_from_parts( + (a.real * b.real + a.imag * b.imag) / denom, + (a.imag * b.real - a.real * b.imag) / denom); + } + } + #endif + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex a) { + __pyx_t_float_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex a) { + __pyx_t_float_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrtf(z.real*z.real + z.imag*z.imag); + #else + return hypotf(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { + __pyx_t_float_complex z; + float r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + float denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + z = __Pyx_c_prod_float(a, a); + return __Pyx_c_prod_float(a, a); + case 3: + z = __Pyx_c_prod_float(a, a); + return __Pyx_c_prod_float(z, a); + case 4: + z = __Pyx_c_prod_float(a, a); + return __Pyx_c_prod_float(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } else if (b.imag == 0) { + z.real = powf(a.real, b.real); + z.imag = 0; + return z; + } else if (a.real > 0) { + r = a.real; + theta = 0; + } else { + r = -a.real; + theta = atan2f(0, -1); + } + } else { + r = __Pyx_c_abs_float(a); + theta = atan2f(a.imag, a.real); + } + lnr = logf(r); + z_r = expf(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cosf(z_theta); + z.imag = z_r * sinf(z_theta); + return z; + } + #endif +#endif + +/* Declarations */ + #if CYTHON_CCOMPLEX + #ifdef __cplusplus + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return ::std::complex< double >(x, y); + } + #else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + return x + y*(__pyx_t_double_complex)_Complex_I; + } + #endif +#else + static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { + __pyx_t_double_complex z; + z.real = x; + z.imag = y; + return z; + } +#endif + +/* Arithmetic */ + #if CYTHON_CCOMPLEX +#else + static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + return (a.real == b.real) && (a.imag == b.imag); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + #if 1 + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else if (fabs(b.real) >= fabs(b.imag)) { + if (b.real == 0 && b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.imag); + } else { + double r = b.imag / b.real; + double s = 1.0 / (b.real + b.imag * r); + return __pyx_t_double_complex_from_parts( + (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); + } + } else { + double r = b.real / b.imag; + double s = 1.0 / (b.imag + b.real * r); + return __pyx_t_double_complex_from_parts( + (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); + } + } + #else + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + if (b.imag == 0) { + return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); + } else { + double denom = b.real * b.real + b.imag * b.imag; + return __pyx_t_double_complex_from_parts( + (a.real * b.real + a.imag * b.imag) / denom, + (a.imag * b.real - a.real * b.imag) / denom); + } + } + #endif + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex a) { + return (a.real == 0) && (a.imag == 0); + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex a) { + __pyx_t_double_complex z; + z.real = a.real; + z.imag = -a.imag; + return z; + } + #if 1 + static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex z) { + #if !defined(HAVE_HYPOT) || defined(_MSC_VER) + return sqrt(z.real*z.real + z.imag*z.imag); + #else + return hypot(z.real, z.imag); + #endif + } + static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { + __pyx_t_double_complex z; + double r, lnr, theta, z_r, z_theta; + if (b.imag == 0 && b.real == (int)b.real) { + if (b.real < 0) { + double denom = a.real * a.real + a.imag * a.imag; + a.real = a.real / denom; + a.imag = -a.imag / denom; + b.real = -b.real; + } + switch ((int)b.real) { + case 0: + z.real = 1; + z.imag = 0; + return z; + case 1: + return a; + case 2: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(a, a); + case 3: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, a); + case 4: + z = __Pyx_c_prod_double(a, a); + return __Pyx_c_prod_double(z, z); + } + } + if (a.imag == 0) { + if (a.real == 0) { + return a; + } else if (b.imag == 0) { + z.real = pow(a.real, b.real); + z.imag = 0; + return z; + } else if (a.real > 0) { + r = a.real; + theta = 0; + } else { + r = -a.real; + theta = atan2(0, -1); + } + } else { + r = __Pyx_c_abs_double(a); + theta = atan2(a.imag, a.real); + } + lnr = log(r); + z_r = exp(lnr * b.real - theta * b.imag); + z_theta = theta * b.real + lnr * b.imag; + z.real = z_r * cos(z_theta); + z.imag = z_r * sin(z_theta); + return z; + } + #endif +#endif + +/* CIntToPy */ + static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value) { + const enum NPY_TYPES neg_one = (enum NPY_TYPES) -1, const_zero = (enum NPY_TYPES) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(enum NPY_TYPES) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(enum NPY_TYPES) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(enum NPY_TYPES) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(enum NPY_TYPES), + little, !is_unsigned); + } +} + +/* CIntFromPy */ + static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) -1, const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(int) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) + case -2: + if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } +#endif + if (sizeof(int) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* CIntFromPy */ + static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) -1, const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(long) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(long) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) + case -2: + if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } +#endif + if (sizeof(long) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* FastTypeChecks */ + #if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = a->tp_base; + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; + if (!res) { + res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } + return res; +} +#endif +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject* exc_type) { + if (likely(err == exc_type)) return 1; + if (likely(PyExceptionClass_Check(err))) { + return __Pyx_inner_PyErr_GivenExceptionMatches2(err, NULL, exc_type); + } + return PyErr_GivenExceptionMatches(err, exc_type); +} +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *exc_type1, PyObject *exc_type2) { + if (likely(err == exc_type1 || err == exc_type2)) return 1; + if (likely(PyExceptionClass_Check(err))) { + return __Pyx_inner_PyErr_GivenExceptionMatches2(err, exc_type1, exc_type2); + } + return (PyErr_GivenExceptionMatches(err, exc_type1) || PyErr_GivenExceptionMatches(err, exc_type2)); +} +#endif + +/* CheckBinaryVersion */ + static int __Pyx_check_binary_version(void) { + char ctversion[4], rtversion[4]; + PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); + PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); + if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compiletime version %s of module '%.100s' " + "does not match runtime version %s", + ctversion, __Pyx_MODULE_NAME, rtversion); + return PyErr_WarnEx(NULL, message, 1); + } + return 0; +} + +/* ModuleImport */ + #ifndef __PYX_HAVE_RT_ImportModule +#define __PYX_HAVE_RT_ImportModule +static PyObject *__Pyx_ImportModule(const char *name) { + PyObject *py_name = 0; + PyObject *py_module = 0; + py_name = __Pyx_PyIdentifier_FromString(name); + if (!py_name) + goto bad; + py_module = PyImport_Import(py_name); + Py_DECREF(py_name); + return py_module; +bad: + Py_XDECREF(py_name); + return 0; +} +#endif + +/* TypeImport */ + #ifndef __PYX_HAVE_RT_ImportType +#define __PYX_HAVE_RT_ImportType +static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, + size_t size, int strict) +{ + PyObject *py_module = 0; + PyObject *result = 0; + PyObject *py_name = 0; + char warning[200]; + Py_ssize_t basicsize; +#ifdef Py_LIMITED_API + PyObject *py_basicsize; +#endif + py_module = __Pyx_ImportModule(module_name); + if (!py_module) + goto bad; + py_name = __Pyx_PyIdentifier_FromString(class_name); + if (!py_name) + goto bad; + result = PyObject_GetAttr(py_module, py_name); + Py_DECREF(py_name); + py_name = 0; + Py_DECREF(py_module); + py_module = 0; + if (!result) + goto bad; + if (!PyType_Check(result)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s is not a type object", + module_name, class_name); + goto bad; + } +#ifndef Py_LIMITED_API + basicsize = ((PyTypeObject *)result)->tp_basicsize; +#else + py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); + if (!py_basicsize) + goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; +#endif + if (!strict && (size_t)basicsize > size) { + PyOS_snprintf(warning, sizeof(warning), + "%s.%s size changed, may indicate binary incompatibility. Expected %zd, got %zd", + module_name, class_name, basicsize, size); + if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; + } + else if ((size_t)basicsize != size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s has the wrong size, try recompiling. Expected %zd, got %zd", + module_name, class_name, basicsize, size); + goto bad; + } + return (PyTypeObject *)result; +bad: + Py_XDECREF(py_module); + Py_XDECREF(result); + return NULL; +} +#endif + +/* InitStrings */ + static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + #if PY_MAJOR_VERSION < 3 + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + #else + if (t->is_unicode | t->is_str) { + if (t->intern) { + *t->p = PyUnicode_InternFromString(t->s); + } else if (t->encoding) { + *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); + } else { + *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); + } + } else { + *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); + } + #endif + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + PyErr_Clear(); + ++t; + } + return 0; +} + +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + Py_TYPE(result)->tp_name)) { + Py_DECREF(result); + return NULL; + } + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type %.200s)", + type_name, type_name, Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(x); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)b)->ob_digit; + const Py_ssize_t size = Py_SIZE(b); + if (likely(__Pyx_sst_abs(size) <= 1)) { + ival = likely(size) ? digits[0] : 0; + if (size == -1) ival = -ival; + return ival; + } else { + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +#endif /* Py_PYTHON_H */ diff --git a/opmd_viewer/openpmd_timeseries/cython_function.cpython-36m-x86_64-linux-gnu.so b/opmd_viewer/openpmd_timeseries/cython_function.cpython-36m-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..b46737a9a7f763c6c64476ffe2b80145e13101d8 GIT binary patch literal 301032 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 ByNc@TIva;JXSk;4PU9@Jk8R1)Te)BnRL_ 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ລ@hQ4TsimeUO=ry*5tTA#&r>Yu2g-;OwT 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 _x%{&hf&rsX0*J2l;X zd9=5ikpWToexfICMk!eizcwh3K(iZUG2HwWz>_W@>lW-VZD!e9YE}ZdJdm!L%gR|e zGoW@bq+0O2hGK8VtUNUoO9hK59?2q6(6BDs-LSSh-IY8?R!qaQlxa>4$=4i4jb0V2-Q$Bjj6%>0YpT(aFlKcWOXK-LQ+X_ z!ZT}X|Mp=mczkt2WRgrglTJuLxsq`&j9DaUkjCxFUokQn`OAuM!P;(Fg9`6+gtw<@ zSy$(AeC^sou%2gTQJlw8Iy{sWEFQvBmA_^kIAy+n&iOzuOIFCy+Pu37?^Y?$q()2&u8IhzWg@6Y0vK$ z5^v`}?uBaW1BW5B$nQ5J@n4U>j}reDV#d#Oh?mLrHzM}@z9O*^_BwvhUQ!OsHTvWC z8j0Hx57XEA&%%Bo9P;~*#J%$U2=g)a@~7`{<<}#eDOVN~zb8r5-_SF$Mn6S4iQ4n~ zl*BM|5d;2Bn0URmHw{WYjX>%wTaKUSH^@OWeSSZa__fVcTGak-R`&cJCz1dEM=v`6 zpMyQ?Z|wV?Ke85${D)6Chye+A$bpHU_Wb`g;-@GC>h!;^?D_ps;^VAX*t7l6?RVs0 zs{F8h@q4CiFIa`v^PKntk;%V&j@k43sB0!@{}Zt_`Dgn4-fDXddoc+=Bl6p1k@l$< zVj-V`{ity+AC?>AW;^(VT#Kg9@4>db7@B$8EsXu9J@F}JKlXjueb%Io6$=lvBR;F_ z`MuiM%hsR;{U7FDj0eEIg2or~--rL>NlmsHkMRQZF(APdlTkL30MdT0;;mO}V=lca zKjfm)FCu;IS8ERwLUYE?Pho%G^HHzkwdQ-K)$BLDVA(fW@o=NHr#S34zHF5nPI>F} z&xXCu=kKT4ia+|o>h_Fdo+JGuS6KVTzoXLnsXX(%1rGc3kG2`#x3qftWQ{-7M8ivs zS6KUge6{*CVa>ldv)yw3HRGddVxj%^lC}RCg&{k>u1xc;W`Enw)_#S`usZer7ZLu_ AB>(^b literal 0 HcmV?d00001 diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 51bdc651..5c1efe2c 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -14,54 +14,11 @@ from .field_metainfo import FieldMetaInformation -def read_field_1d( filename, field_path, axis_labels ): - """ - Extract a given field from an HDF5 file in the openPMD format, - when the geometry is 1d cartesian. - - Parameters - ---------- - filename : string - The absolute path to the HDF5 file - - field_path : string - The relative path to the requested field, from the openPMD meshes path - (e.g. 'rho', 'E/r', 'B/x') - - axis_labels: list of strings - The name of the dimensions of the array (e.g. ['x', 'y', 'z']) - - Returns - ------- - A tuple with - F : a 1darray containing the required field - info : a FieldMetaInformation object - (contains information about the grid; see the corresponding docstring) - """ - # Open the HDF5 file - dfile = h5py.File( filename, 'r' ) - # Extract the dataset and and corresponding group - group, dset = find_dataset( dfile, field_path ) - - # Extract the data in 1D Cartesian - F = get_data( dset ) - - # Extract the metainformation - axes = { 0: axis_labels[0]} - info = FieldMetaInformation( axes, F.shape, - group.attrs['gridSpacing'], group.attrs['gridGlobalOffset'], - group.attrs['gridUnitSI'], dset.attrs['position'] ) - - # Close the file - dfile.close() - return( F, info ) - - -def read_field_2d( filename, field_path, axis_labels, +def read_field_cartesian( filename, field_path, axis_labels, slicing=None, slicing_dir=None ): """ Extract a given field from an HDF5 file in the openPMD format, - when the geometry is 2d cartesian. + when the geometry is cartesian (1d, 2d or 3d). Parameters ---------- @@ -70,7 +27,7 @@ def read_field_2d( filename, field_path, axis_labels, field_path : string The relative path to the requested field, from the openPMD meshes path - (e.g. 'rho', 'E/r', 'B/x') + (e.g. 'rho', 'E/z', 'B/x') axis_labels: list of strings The name of the dimensions of the array (e.g. ['x', 'y', 'z']) @@ -90,10 +47,11 @@ def read_field_2d( filename, field_path, axis_labels, Returns ------- A tuple with - F : a 2darray containing the required field + F : a ndarray containing the required field info : a FieldMetaInformation object (contains information about the grid; see the corresponding docstring) """ + print(slicing, slicing_dir) # Convert slicing and slicing_dir to lists if slicing is not None and not isinstance(slicing, list): slicing = [slicing] @@ -106,7 +64,7 @@ def read_field_2d( filename, field_path, axis_labels, for ind in ind_to_pop: slicing_dir.pop(ind) slicing.pop(ind) - + print(slicing, slicing_dir) # Open the HDF5 file dfile = h5py.File( filename, 'r' ) # Extract the dataset and and corresponding group @@ -123,6 +81,7 @@ def read_field_2d( filename, field_path, axis_labels, list_slicing_index = [] list_i_cell = [] new_labels = axis_labels + print(new_labels) for count, slicing_dir_item in enumerate(slicing_dir): slicing_index = axis_labels.index(slicing_dir_item) list_slicing_index.append(slicing_index) @@ -240,111 +199,6 @@ def read_field_circ( filename, field_path, m=0, theta=0. ): return( F_total, info ) -def read_field_3d( filename, field_path, axis_labels, - slicing=[0.], slicing_dir=['y']): - """ - Extract a given field from an HDF5 file in the openPMD format, - when the geometry is 3d cartesian. - - Parameters - ---------- - filename : string - The absolute path to the HDF5 file - - field_path : string - The relative path to the requested field, from the openPMD meshes path - (e.g. 'rho', 'E/r', 'B/x') - - axis_labels: list of strings - The name of the dimensions of the array (e.g. ['x', 'y', 'z']) - - slicing : float or list of float, optional - number(s) between -1 and 1 that indicates where to slice the data, - along directions given in `slicing_dir` - -1 : lower edge of the simulation box - 0 : middle of the simulation box - 1 : upper edge of the simulation box - If slicing is None, the full 3D grid is returned. - - slicing_dir : str or list of str, optional - Direction(s) along which to slice the data - Elements can be 'x', 'y' and/or 'z' - - Returns - ------- - A tuple with - F : a 2darray containing the required field - info : a FieldMetaInformation object - (contains information about the grid; see the corresponding docstring) - """ - # Convert slicing and slicing_dir to lists - if slicing is not None and not isinstance(slicing, list): - slicing = [slicing] - if slicing_dir is not None and not isinstance(slicing_dir, list): - slicing_dir = [slicing_dir] - # Pop slicing directions in arguments that are not in axis_label - if slicing_dir is not None: - ind_to_pop = [slicing_dir.index(val) for val in slicing_dir if - val not in axis_labels ] - for ind in ind_to_pop: - slicing_dir.pop(ind) - slicing.pop(ind) - - # Open the HDF5 file - dfile = h5py.File( filename, 'r' ) - # Extract the dataset and and corresponding group - group, dset = find_dataset( dfile, field_path ) - - # Dimensions of the grid - shape = list( get_shape( dset ) ) - grid_spacing = list( group.attrs['gridSpacing'] ) - global_offset = list( group.attrs['gridGlobalOffset'] ) - - # Slice selection - if slicing_dir: - # Get the integer that correspond to the slicing direction - list_slicing_index = [] - list_i_cell = [] - new_labels = axis_labels - for count, slicing_dir_item in enumerate(slicing_dir): - slicing_index = axis_labels.index(slicing_dir_item) - list_slicing_index.append(slicing_index) - # Number of cells along the slicing direction - n_cells = shape[ slicing_index ] - # Index of the slice (prevent stepping out of the array) - i_cell = int( 0.5 * (slicing[count] + 1.) * n_cells ) - i_cell = max( i_cell, 0 ) - i_cell = min( i_cell, n_cells - 1) - list_i_cell.append(i_cell) - - # Remove metainformation relative to the slicing index - # Successive pops starting from last coordinate to slice - list_indices_to_clean = list_slicing_index[:] - list_indices_to_clean.sort(reverse=True) - for index_to_clean in list_indices_to_clean: - shape.pop( index_to_clean ) - grid_spacing.pop( index_to_clean ) - global_offset.pop( index_to_clean ) - new_labels = new_labels[:index_to_clean] + \ - new_labels[index_to_clean + 1:] - - axes = { i: new_labels[i] for i in range(len(new_labels)) } - # Extraction of the data - F = get_data( dset, list_i_cell, list_slicing_index ) - info = FieldMetaInformation( axes, shape, grid_spacing, global_offset, - group.attrs['gridUnitSI'], dset.attrs['position'] ) - else: - F = get_data( dset ) - axes = { i: axis_labels[i] for i in range(len(axis_labels)) } - info = FieldMetaInformation( axes, F.shape, - group.attrs['gridSpacing'], group.attrs['gridGlobalOffset'], - group.attrs['gridUnitSI'], dset.attrs['position'] ) - - # Close the file - dfile.close() - return( F, info ) - - def find_dataset( dfile, field_path ): """ Extract the dataset that corresponds to field_path, diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 50fd809f..3331493b 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -471,16 +471,9 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, # Get the field data geometry = self.fields_metadata[field]['geometry'] axis_labels = self.fields_metadata[field]['axis_labels'] - # - For 1D - if geometry == "1dcartesian": - F, info = read_field_1d(filename, field_path, axis_labels) - # - For 2D - elif geometry == "2dcartesian": - F, info = read_field_2d( - filename, field_path, axis_labels, slicing, slicing_dir) - # - For 3D - elif geometry == "3dcartesian": - F, info = read_field_3d( + # - For cartesian + if geometry in ["1dcartesian", "2dcartesian", "3dcartesian"]: + F, info = read_field_cartesian( filename, field_path, axis_labels, slicing, slicing_dir) # - For thetaMode elif geometry == "thetaMode": From 5754f4c2fd449f31ea5f73f488c5fdbe8d372a97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxence=20Th=C3=A9venet?= Date: Tue, 8 May 2018 11:14:14 -0700 Subject: [PATCH 15/90] minor change in docstring --- opmd_viewer/openpmd_timeseries/main.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 3331493b..3f0ee881 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -390,16 +390,17 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, 0 : middle of the simulation box 1 : upper edge of the simulation box If slicing is None, the full grid is returned. - Default is None for 2D and [0.] for 3d Cartesian + Default is None for 1D and 2D and 0. for 3d Cartesian slicing_dir : str or list of str, optional Direction(s) along which to slice the data Elements can be: + - 1d: 'z' - 2d: 'x' and/or 'z' - - 3d: 'x', 'y' and/or 'z' + - 3d: 'x' and/or 'y' and/or 'z' - 1d/circ: not implemented Returned array is reduced by 1 dimension per slicing. - Default is None for 2D and ['y'] for 3d Cartesian + Default is None for 1D and 2D and 'y' for 3d Cartesian output : bool, optional Whether to return the requested quantity From 1ab88148ba23dada237209b2d8fc53cdaa7811dd Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Wed, 9 May 2018 08:00:13 -0700 Subject: [PATCH 16/90] Fix docstring. Slicing in cartesian ready for review. --- .../data_reader/field_reader.py | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 5c1efe2c..2e43b636 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -33,16 +33,23 @@ def read_field_cartesian( filename, field_path, axis_labels, The name of the dimensions of the array (e.g. ['x', 'y', 'z']) slicing : float or list of float, optional - Number(s) between -1 and 1 that indicates where to slice the data, - along directions given in `slicing_dir` - -1 : lower edge of the simulation box - 0 : middle of the simulation box - 1 : upper edge of the simulation box - If slicing is None, the full 3D grid is returned. + Number(s) between -1 and 1 that indicate where to slice the data, + along the directions in `slicing_dir` + -1 : lower edge of the simulation box + 0 : middle of the simulation box + 1 : upper edge of the simulation box + If slicing is None, the full grid is returned. + Default is None for 1D and 2D and 0. for 3d Cartesian slicing_dir : str or list of str, optional - Direction(s) along which to slice the data - Elements can be 'x' and/or 'z' + Direction(s) along which to slice the data + Elements can be: + - 1d: 'z' + - 2d: 'x' and/or 'z' + - 3d: 'x' and/or 'y' and/or 'z' + - 1d/circ: not implemented + Returned array is reduced by 1 dimension per slicing. + Default is None for 1D and 2D and 'y' for 3d Cartesian Returns ------- @@ -51,7 +58,6 @@ def read_field_cartesian( filename, field_path, axis_labels, info : a FieldMetaInformation object (contains information about the grid; see the corresponding docstring) """ - print(slicing, slicing_dir) # Convert slicing and slicing_dir to lists if slicing is not None and not isinstance(slicing, list): slicing = [slicing] @@ -64,7 +70,6 @@ def read_field_cartesian( filename, field_path, axis_labels, for ind in ind_to_pop: slicing_dir.pop(ind) slicing.pop(ind) - print(slicing, slicing_dir) # Open the HDF5 file dfile = h5py.File( filename, 'r' ) # Extract the dataset and and corresponding group @@ -81,7 +86,6 @@ def read_field_cartesian( filename, field_path, axis_labels, list_slicing_index = [] list_i_cell = [] new_labels = axis_labels - print(new_labels) for count, slicing_dir_item in enumerate(slicing_dir): slicing_index = axis_labels.index(slicing_dir_item) list_slicing_index.append(slicing_index) From 33f14c15462ba6ee640a42205120a1a9988487ae Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Wed, 9 May 2018 08:39:27 -0700 Subject: [PATCH 17/90] WIP slicing in cylindrical symmetry --- .../data_reader/field_reader.py | 128 +++++++++++++++++- opmd_viewer/openpmd_timeseries/main.py | 7 +- 2 files changed, 128 insertions(+), 7 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 2e43b636..cc47275f 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -125,7 +125,8 @@ def read_field_cartesian( filename, field_path, axis_labels, return( F, info ) -def read_field_circ( filename, field_path, m=0, theta=0. ): +def read_field_circ( filename, field_path, m=0, theta=0., + slicing=None, slicing_dir=None ): """ Extract a given field from an HDF5 file in the openPMD format, when the geometry is 2d cartesian. @@ -159,9 +160,6 @@ def read_field_circ( filename, field_path, m=0, theta=0. ): # Extract the metainformation Nm, Nr, Nz = get_shape( dset ) - info = FieldMetaInformation( { 0: 'r', 1: 'z' }, (Nr, Nz), - group.attrs['gridSpacing'], group.attrs['gridGlobalOffset'], - group.attrs['gridUnitSI'], dset.attrs['position'], thetaMode=True ) # Extract the modes and recombine them properly F_total = np.zeros( (2 * Nr, Nz ) ) @@ -198,11 +196,133 @@ def read_field_circ( filename, field_path, m=0, theta=0. ): F_total[Nr:, :] = F[:, :] F_total[:Nr, :] = (-1) ** m * F[::-1, :] + axis_labels = ['r','z'] + shape = [Nr, Nz] + grid_spacing = list( group.attrs['gridSpacing'] ) + global_offset = list( group.attrs['gridGlobalOffset'] ) + + # Perform slicing if needed + if slicing_dir is not None: +# print(slicing_dir) + if not isinstance(slicing, list): + slicing = [slicing] + if not isinstance(slicing_dir, list): + slicing_dir = [slicing_dir] + if 'z' in slicing_dir: +# print('z in slicing_dir') + ind = slicing_dir.index('z') + n_cells = shape[ 1 ] + i_cell = int( 0.5 * (slicing[ind] + 1.) * n_cells ) + i_cell = max( i_cell, 0 ) + i_cell = min( i_cell, n_cells - 1) + F_total = F_total[:,i_cell] + shape.pop( ind ) + grid_spacing.pop( ind ) + global_offset.pop( ind ) + axis_labels = axis_labels[:-1] + if 'r' in slicing_dir: +# print('r in slicing_dir') + ind = slicing_dir.index('r') + n_cells = shape[ 0 ] + i_cell = int( 0.5 * (slicing[ind] + 1.) * n_cells ) + i_cell = max( i_cell, 0 ) + i_cell = min( i_cell, n_cells - 1) + F_total = F_total[:,i_cell] + shape.pop( ind ) + grid_spacing.pop( ind ) + global_offset.pop( ind ) + axis_labels = axis_labels[1:] + + axes = { i: axis_labels[i] for i in range(len(axis_labels)) } + print(axes) + info = FieldMetaInformation( axes, tuple(shape), + grid_spacing, global_offset, + group.attrs['gridUnitSI'], dset.attrs['position'], thetaMode=True ) + # Close the file dfile.close() + return( F_total, info ) +# def read_field_circ( filename, field_path, m=0, theta=0. ): +# """ +# Extract a given field from an HDF5 file in the openPMD format, +# when the geometry is 2d cartesian. +# +# Parameters +# ---------- +# filename : string +# The absolute path to the HDF5 file +# +# field_path : string +# The relative path to the requested field, from the openPMD meshes path +# (e.g. 'rho', 'E/r', 'B/x') +# +# m : int or string, optional +# The azimuthal mode to be extracted +# +# theta : float, optional +# Angle of the plane of observation with respect to the x axis +# +# Returns +# ------- +# A tuple with +# F : a 2darray containing the required field +# info : a FieldMetaInformation object +# (contains information about the grid; see the corresponding docstring) +# """ +# # Open the HDF5 file +# dfile = h5py.File( filename, 'r' ) +# # Extract the dataset and and corresponding group +# group, dset = find_dataset( dfile, field_path ) +# +# # Extract the metainformation +# Nm, Nr, Nz = get_shape( dset ) +# info = FieldMetaInformation( { 0: 'r', 1: 'z' }, (Nr, Nz), +# group.attrs['gridSpacing'], group.attrs['gridGlobalOffset'], +# group.attrs['gridUnitSI'], dset.attrs['position'], thetaMode=True ) +# +# # Extract the modes and recombine them properly +# F_total = np.zeros( (2 * Nr, Nz ) ) +# if m == 'all': +# # Sum of all the modes +# # - Prepare the multiplier arrays +# mult_above_axis = [1] +# mult_below_axis = [1] +# for mode in range(1, int(Nm / 2) + 1): +# cos = np.cos( mode * theta ) +# sin = np.sin( mode * theta ) +# mult_above_axis += [cos, sin] +# mult_below_axis += [ (-1) ** mode * cos, (-1) ** mode * sin ] +# mult_above_axis = np.array( mult_above_axis ) +# mult_below_axis = np.array( mult_below_axis ) +# # - Sum the modes +# F = get_data( dset ) # (Extracts all modes) +# F_total[Nr:, :] = np.tensordot( mult_above_axis, +# F, axes=(0, 0) )[:, :] +# F_total[:Nr, :] = np.tensordot( mult_below_axis, +# F, axes=(0, 0) )[::-1, :] +# elif m == 0: +# # Extract mode 0 +# F = get_data( dset, 0, 0 ) +# F_total[Nr:, :] = F[:, :] +# F_total[:Nr, :] = F[::-1, :] +# else: +# # Extract higher mode +# cos = np.cos( m * theta ) +# sin = np.sin( m * theta ) +# F_cos = get_data( dset, 2 * m - 1, 0 ) +# F_sin = get_data( dset, 2 * m, 0 ) +# F = cos * F_cos + sin * F_sin +# F_total[Nr:, :] = F[:, :] +# F_total[:Nr, :] = (-1) ** m * F[::-1, :] +# +# # Close the file +# dfile.close() +# return( F_total, info ) + + def find_dataset( dfile, field_path ): """ Extract the dataset that corresponds to field_path, diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 3f0ee881..311b3e81 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -481,8 +481,9 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, if (coord in ['x', 'y']) and \ (self.fields_metadata[field]['type'] == 'vector'): # For Cartesian components, combine r and t components - Fr, info = read_field_circ(filename, field + '/r', m, theta) - Ft, info = read_field_circ(filename, field + '/t', m, theta) +# print(slicing, slicing_dir) + Fr, info = read_field_circ(filename, field + '/r', m, theta, slicing, slicing_dir) + Ft, info = read_field_circ(filename, field + '/t', m, theta, slicing, slicing_dir) if coord == 'x': F = np.cos(theta) * Fr - np.sin(theta) * Ft elif coord == 'y': @@ -491,7 +492,7 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, F[: int(F.shape[0] / 2)] *= -1 else: # For cylindrical or scalar components, no special treatment - F, info = read_field_circ(filename, field_path, m, theta) + F, info = read_field_circ(filename, field_path, m, theta, slicing, slicing_dir) # Plot the resulting field # Deactivate plotting when there is no slice selection From b97a93de5fc41c290767408f0226df2bbd9729f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxence=20Th=C3=A9venet?= Date: Wed, 9 May 2018 17:01:15 -0700 Subject: [PATCH 18/90] slicing in circ geometry --- .../openpmd_timeseries/data_reader/field_metainfo.py | 9 +++++---- .../openpmd_timeseries/data_reader/field_reader.py | 11 +++++------ opmd_viewer/openpmd_timeseries/main.py | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py b/opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py index 6015e00e..d83f2462 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py @@ -91,10 +91,11 @@ def __init__(self, axes, shape, grid_spacing, # Create the points below the axis if thetaMode is true if thetaMode: - self.r = np.concatenate((-self.r[::-1], self.r)) - # The axis now extends from -rmax to rmax - self.rmin = -self.rmax - self.imshow_extent[2] = -self.imshow_extent[3] + if 'r' in axes: + self.r = np.concatenate((-self.r[::-1], self.r)) + # The axis now extends from -rmax to rmax + self.rmin = -self.rmax + self.imshow_extent[2] = -self.imshow_extent[3] # Finalize imshow_extent by converting it from list to array self.imshow_extent = np.array(self.imshow_extent) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index cc47275f..d0c283eb 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -203,13 +203,14 @@ def read_field_circ( filename, field_path, m=0, theta=0., # Perform slicing if needed if slicing_dir is not None: -# print(slicing_dir) + # Convert arguments to lists if not isinstance(slicing, list): slicing = [slicing] if not isinstance(slicing_dir, list): slicing_dir = [slicing_dir] + # Slice field and clear metadata + # First z direction if 'z' in slicing_dir: -# print('z in slicing_dir') ind = slicing_dir.index('z') n_cells = shape[ 1 ] i_cell = int( 0.5 * (slicing[ind] + 1.) * n_cells ) @@ -220,21 +221,19 @@ def read_field_circ( filename, field_path, m=0, theta=0., grid_spacing.pop( ind ) global_offset.pop( ind ) axis_labels = axis_labels[:-1] + # Then r direction if 'r' in slicing_dir: -# print('r in slicing_dir') ind = slicing_dir.index('r') n_cells = shape[ 0 ] i_cell = int( 0.5 * (slicing[ind] + 1.) * n_cells ) i_cell = max( i_cell, 0 ) i_cell = min( i_cell, n_cells - 1) - F_total = F_total[:,i_cell] + F_total = F_total[i_cell,...] shape.pop( ind ) grid_spacing.pop( ind ) global_offset.pop( ind ) axis_labels = axis_labels[1:] - axes = { i: axis_labels[i] for i in range(len(axis_labels)) } - print(axes) info = FieldMetaInformation( axes, tuple(shape), grid_spacing, global_offset, group.attrs['gridUnitSI'], dset.attrs['position'], thetaMode=True ) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 311b3e81..1e1bfc71 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -481,7 +481,6 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, if (coord in ['x', 'y']) and \ (self.fields_metadata[field]['type'] == 'vector'): # For Cartesian components, combine r and t components -# print(slicing, slicing_dir) Fr, info = read_field_circ(filename, field + '/r', m, theta, slicing, slicing_dir) Ft, info = read_field_circ(filename, field + '/t', m, theta, slicing, slicing_dir) if coord == 'x': @@ -489,7 +488,8 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, elif coord == 'y': F = np.sin(theta) * Fr + np.cos(theta) * Ft # Revert the sign below the axis - F[: int(F.shape[0] / 2)] *= -1 + if 'r' in info.axes.values(): + F[: int(F.shape[0] / 2)] *= -1 else: # For cylindrical or scalar components, no special treatment F, info = read_field_circ(filename, field_path, m, theta, slicing, slicing_dir) From a9fcb138af947eaf6fe4ed0775f26ec2d96ca3c7 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Wed, 9 May 2018 17:11:31 -0700 Subject: [PATCH 19/90] clean code to comply with pep8 --- .../data_reader/field_reader.py | 86 +------------------ opmd_viewer/openpmd_timeseries/main.py | 9 +- 2 files changed, 10 insertions(+), 85 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index d0c283eb..f77c2051 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -196,14 +196,14 @@ def read_field_circ( filename, field_path, m=0, theta=0., F_total[Nr:, :] = F[:, :] F_total[:Nr, :] = (-1) ** m * F[::-1, :] - axis_labels = ['r','z'] + axis_labels = ['r', 'z'] shape = [Nr, Nz] grid_spacing = list( group.attrs['gridSpacing'] ) global_offset = list( group.attrs['gridGlobalOffset'] ) # Perform slicing if needed if slicing_dir is not None: - # Convert arguments to lists + # Convert arguments to lists if not isinstance(slicing, list): slicing = [slicing] if not isinstance(slicing_dir, list): @@ -216,7 +216,7 @@ def read_field_circ( filename, field_path, m=0, theta=0., i_cell = int( 0.5 * (slicing[ind] + 1.) * n_cells ) i_cell = max( i_cell, 0 ) i_cell = min( i_cell, n_cells - 1) - F_total = F_total[:,i_cell] + F_total = F_total[:, i_cell] shape.pop( ind ) grid_spacing.pop( ind ) global_offset.pop( ind ) @@ -228,7 +228,7 @@ def read_field_circ( filename, field_path, m=0, theta=0., i_cell = int( 0.5 * (slicing[ind] + 1.) * n_cells ) i_cell = max( i_cell, 0 ) i_cell = min( i_cell, n_cells - 1) - F_total = F_total[i_cell,...] + F_total = F_total[i_cell, ...] shape.pop( ind ) grid_spacing.pop( ind ) global_offset.pop( ind ) @@ -244,84 +244,6 @@ def read_field_circ( filename, field_path, m=0, theta=0., return( F_total, info ) -# def read_field_circ( filename, field_path, m=0, theta=0. ): -# """ -# Extract a given field from an HDF5 file in the openPMD format, -# when the geometry is 2d cartesian. -# -# Parameters -# ---------- -# filename : string -# The absolute path to the HDF5 file -# -# field_path : string -# The relative path to the requested field, from the openPMD meshes path -# (e.g. 'rho', 'E/r', 'B/x') -# -# m : int or string, optional -# The azimuthal mode to be extracted -# -# theta : float, optional -# Angle of the plane of observation with respect to the x axis -# -# Returns -# ------- -# A tuple with -# F : a 2darray containing the required field -# info : a FieldMetaInformation object -# (contains information about the grid; see the corresponding docstring) -# """ -# # Open the HDF5 file -# dfile = h5py.File( filename, 'r' ) -# # Extract the dataset and and corresponding group -# group, dset = find_dataset( dfile, field_path ) -# -# # Extract the metainformation -# Nm, Nr, Nz = get_shape( dset ) -# info = FieldMetaInformation( { 0: 'r', 1: 'z' }, (Nr, Nz), -# group.attrs['gridSpacing'], group.attrs['gridGlobalOffset'], -# group.attrs['gridUnitSI'], dset.attrs['position'], thetaMode=True ) -# -# # Extract the modes and recombine them properly -# F_total = np.zeros( (2 * Nr, Nz ) ) -# if m == 'all': -# # Sum of all the modes -# # - Prepare the multiplier arrays -# mult_above_axis = [1] -# mult_below_axis = [1] -# for mode in range(1, int(Nm / 2) + 1): -# cos = np.cos( mode * theta ) -# sin = np.sin( mode * theta ) -# mult_above_axis += [cos, sin] -# mult_below_axis += [ (-1) ** mode * cos, (-1) ** mode * sin ] -# mult_above_axis = np.array( mult_above_axis ) -# mult_below_axis = np.array( mult_below_axis ) -# # - Sum the modes -# F = get_data( dset ) # (Extracts all modes) -# F_total[Nr:, :] = np.tensordot( mult_above_axis, -# F, axes=(0, 0) )[:, :] -# F_total[:Nr, :] = np.tensordot( mult_below_axis, -# F, axes=(0, 0) )[::-1, :] -# elif m == 0: -# # Extract mode 0 -# F = get_data( dset, 0, 0 ) -# F_total[Nr:, :] = F[:, :] -# F_total[:Nr, :] = F[::-1, :] -# else: -# # Extract higher mode -# cos = np.cos( m * theta ) -# sin = np.sin( m * theta ) -# F_cos = get_data( dset, 2 * m - 1, 0 ) -# F_sin = get_data( dset, 2 * m, 0 ) -# F = cos * F_cos + sin * F_sin -# F_total[Nr:, :] = F[:, :] -# F_total[:Nr, :] = (-1) ** m * F[::-1, :] -# -# # Close the file -# dfile.close() -# return( F_total, info ) - - def find_dataset( dfile, field_path ): """ Extract the dataset that corresponds to field_path, diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 1e1bfc71..ff12c908 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -481,8 +481,10 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, if (coord in ['x', 'y']) and \ (self.fields_metadata[field]['type'] == 'vector'): # For Cartesian components, combine r and t components - Fr, info = read_field_circ(filename, field + '/r', m, theta, slicing, slicing_dir) - Ft, info = read_field_circ(filename, field + '/t', m, theta, slicing, slicing_dir) + Fr, info = read_field_circ(filename, field + '/r', m, theta, + slicing, slicing_dir) + Ft, info = read_field_circ(filename, field + '/t', m, theta, + slicing, slicing_dir) if coord == 'x': F = np.cos(theta) * Fr - np.sin(theta) * Ft elif coord == 'y': @@ -492,7 +494,8 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, F[: int(F.shape[0] / 2)] *= -1 else: # For cylindrical or scalar components, no special treatment - F, info = read_field_circ(filename, field_path, m, theta, slicing, slicing_dir) + F, info = read_field_circ(filename, field_path, m, theta, + slicing, slicing_dir) # Plot the resulting field # Deactivate plotting when there is no slice selection From 1847c2ef24324595ce4d3fe62c6748aa4add16de Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Wed, 9 May 2018 17:41:09 -0700 Subject: [PATCH 20/90] minor. docstring --- .../data_reader/field_reader.py | 17 ++++++++++++++++- opmd_viewer/openpmd_timeseries/main.py | 14 ++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index f77c2051..9e2e81e9 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -146,10 +146,25 @@ def read_field_circ( filename, field_path, m=0, theta=0., theta : float, optional Angle of the plane of observation with respect to the x axis + slicing : float or list of float, optional + Number(s) between -1 and 1 that indicate where to slice the data, + along the directions in `slicing_dir` + -1 : lower edge of the simulation box + 0 : middle of the simulation box + 1 : upper edge of the simulation box + If slicing is None, the full grid is returned. + Default is None. + + slicing_dir : str or list of str, optional + Direction(s) along which to slice the data + Elements can be 'r' and/or 'z' + Returned array is reduced by 1 dimension per slicing. + Default is None. + Returns ------- A tuple with - F : a 2darray containing the required field + F : a ndarray containing the required field info : a FieldMetaInformation object (contains information about the grid; see the corresponding docstring) """ diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index ff12c908..f0639be4 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -394,13 +394,15 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, slicing_dir : str or list of str, optional Direction(s) along which to slice the data - Elements can be: - - 1d: 'z' - - 2d: 'x' and/or 'z' - - 3d: 'x' and/or 'y' and/or 'z' - - 1d/circ: not implemented + + In cartesian geometry, elements can be: + - 1d: 'z' + - 2d: 'x' and/or 'z' + - 3d: 'x' and/or 'y' and/or 'z' + - 1d/circ: not implemented + + In cylindrical geometry, elements can be 'r' and/or 'z' Returned array is reduced by 1 dimension per slicing. - Default is None for 1D and 2D and 'y' for 3d Cartesian + Default is None for cylindrical, 1D cartesian, 2D cartesian, + and 'y' for 3d Cartesian output : bool, optional Whether to return the requested quantity From 658fbba82898e05b96cea98d43d3e4d5c3236a1b Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Wed, 9 May 2018 17:43:48 -0700 Subject: [PATCH 21/90] fix typo --- opmd_viewer/openpmd_timeseries/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index f0639be4..3f26c614 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -401,7 +401,7 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, - 1d/circ: not implemented + In cylindrical geometry, elements can be 'r' and/or 'z' Returned array is reduced by 1 dimension per slicing. - Default is None for cylindrical, 1D cartesian, 2D cartesian, + Default is None for cylindrical, 1D cartesian and 2D cartesian, and 'y' for 3d Cartesian output : bool, optional From f8bf24947bd7c3f8c88cf0552d927b2abfd46bb8 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Tue, 15 May 2018 17:57:35 -0700 Subject: [PATCH 22/90] get_field no longer has 'y' as slicing direction by default --- opmd_viewer/addons/pic/lpa_diagnostics.py | 68 ++++++++++++++++++----- opmd_viewer/openpmd_timeseries/main.py | 8 +-- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/opmd_viewer/addons/pic/lpa_diagnostics.py b/opmd_viewer/addons/pic/lpa_diagnostics.py index d352633e..04ffd863 100644 --- a/opmd_viewer/addons/pic/lpa_diagnostics.py +++ b/opmd_viewer/addons/pic/lpa_diagnostics.py @@ -438,7 +438,7 @@ def get_current( self, t=None, iteration=None, species=None, select=None, def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', freq_filter=40, index='center', theta=0, - slicing_dir='y', plot=False, **kw ): + slicing_dir='y', slicing=0., plot=False, **kw ): """ Calculate a laser field by filtering out high frequencies. Can either return the envelope slice-wise or a full 2D envelope. @@ -476,10 +476,25 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', Only used for thetaMode geometry The angle of the plane of observation, with respect to the x axis - slicing_dir : str, optional - Only used for 3dcartesian geometry - The direction along which to slice the data - Either 'x', 'y' + slicing : float or list of float, optional + Number(s) between -1 and 1 that indicate where to slice the data, + along the directions in `slicing_dir` + -1 : lower edge of the simulation box + 0 : middle of the simulation box + 1 : upper edge of the simulation box + If slicing is None, the full grid is returned. + Default is None + + slicing_dir : str or list of str, optional + Direction(s) along which to slice the data + + In cartesian geometry, elements can be: + - 1d: 'z' + - 2d: 'x' and/or 'z' + - 3d: 'x' and/or 'y' and/or 'z' + - 1d/circ: not implemented + + In cylindrical geometry, elements can be 'r' and/or 'z' + Returned array is reduced by 1 dimension per slicing. + Default is None. plot : bool, optional Whether to plot the requested quantity @@ -500,7 +515,7 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', # Get field data field = self.get_field( t=t, iteration=iteration, field='E', coord=pol, theta=theta, m=m, - slicing_dir=slicing_dir ) + slicing=slicing, slicing_dir=slicing_dir ) info = field[1] if index == 'all': # Filter the full 2D array @@ -699,17 +714,19 @@ def get_spectrum( self, t=None, iteration=None, pol=None, else: theta = np.pi / 2. if "3dcartesian" in self.avail_geom: + slicing=0. if pol == 'x': slicing_dir = 'y' else: slicing_dir = 'x' else: slicing_dir = None + slicing = None # Get field data field, info = self.get_field( t=t, iteration=iteration, field='E', coord=pol, theta=theta, m=m, - slicing_dir=slicing_dir ) + slicing=slicing, slicing_dir=slicing_dir ) # Get central field lineout field1d = field[ int( field.shape[0] / 2 ), :] # FFT of 1d data @@ -765,16 +782,19 @@ def get_a0( self, t=None, iteration=None, pol=None ): else: theta = np.pi / 2. if "3dcartesian" in self.avail_geom: + slicing = 0. if pol == 'x': slicing_dir = 'y' else: slicing_dir = 'x' else: + slicing = None slicing_dir = None # Get the peak field from field envelope Emax = np.amax(self.get_laser_envelope(t=t, iteration=iteration, pol=pol, theta=theta, + slicing=slicing, slicing_dir=slicing_dir)[0]) # Get mean frequency omega = self.get_main_frequency(t=t, iteration=iteration, pol=pol) @@ -818,15 +838,18 @@ def get_ctau( self, t=None, iteration=None, pol=None, method='fit' ): else: theta = np.pi / 2. if "3dcartesian" in self.avail_geom: + slicing = 0. if pol == 'x': slicing_dir = 'y' else: slicing_dir = 'x' else: + slicing = None slicing_dir = None # Get the field envelope E, info = self.get_laser_envelope(t=t, iteration=iteration, pol=pol, theta=theta, + slicing=slicing, slicing_dir=slicing_dir) # Calculate ctau with RMS value ctau = np.sqrt(2) * w_std(info.z, E) @@ -847,7 +870,7 @@ def get_ctau( self, t=None, iteration=None, pol=None, method='fit' ): raise ValueError('Unknown method: {:s}'.format(method)) def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, - slicing_dir='y', method='fit' ): + slicing=0., slicing_dir='y', method='fit' ): """ Calculate the waist of a (gaussian) laser pulse. ( sqrt(2) * sigma_r) @@ -869,10 +892,25 @@ def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, Only used for thetaMode geometry The angle of the plane of observation, with respect to the x axis - slicing_dir : str, optional - Only used for 3dcartesian geometry - The direction along which to slice the data - Either 'x', 'y' + slicing : float or list of float, optional + Number(s) between -1 and 1 that indicate where to slice the data, + along the directions in `slicing_dir` + -1 : lower edge of the simulation box + 0 : middle of the simulation box + 1 : upper edge of the simulation box + If slicing is None, the full grid is returned. + Default is None + + slicing_dir : str or list of str, optional + Direction(s) along which to slice the data + + In cartesian geometry, elements can be: + - 1d: 'z' + - 2d: 'x' and/or 'z' + - 3d: 'x' and/or 'y' and/or 'z' + - 1d/circ: not implemented + + In cylindrical geometry, elements can be 'r' and/or 'z' + Returned array is reduced by 1 dimension per slicing. + Default is None. method : str, optional The method which is used to compute the waist @@ -887,6 +925,7 @@ def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, # Get the field envelope field, info = self.get_laser_envelope(t=t, iteration=iteration, pol=pol, index='all', + slicing=slicing, slicing_dir=slicing_dir, theta=theta) # Find the indices of the maximum field, and @@ -918,7 +957,7 @@ def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, raise ValueError('Unknown method: {:s}'.format(method)) def get_spectrogram( self, t=None, iteration=None, pol=None, theta=0, - slicing_dir='y', plot=False, **kw ): + slicing_dir='y', slicing=0., plot=False, **kw ): """ Calculates the spectrogram of a laserpulse, by the FROG method. @@ -961,7 +1000,8 @@ def get_spectrogram( self, t=None, iteration=None, pol=None, theta=0, # Get the field E, info = self.get_field( t=t, iteration=iteration, field='E', coord=pol, theta=theta, - slicing_dir=slicing_dir ) + slicing_dir=slicing_dir, + slicing=slicing) # Get central slice E = E[ int(E.shape[0] / 2), :] Nz = len(E) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 3f26c614..fc4be747 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -348,7 +348,7 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, return(data_list) def get_field(self, field=None, coord=None, t=None, iteration=None, - m='all', theta=0., slicing=0., slicing_dir='y', + m='all', theta=0., slicing=None, slicing_dir=None, output=True, plot=False, plot_range=[[None, None], [None, None]], **kw): """ @@ -390,7 +390,7 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, 0 : middle of the simulation box 1 : upper edge of the simulation box If slicing is None, the full grid is returned. - Default is None for 1D and 2D and 0. for 3d Cartesian + Default is None slicing_dir : str or list of str, optional Direction(s) along which to slice the data @@ -401,8 +401,7 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, - 1d/circ: not implemented + In cylindrical geometry, elements can be 'r' and/or 'z' Returned array is reduced by 1 dimension per slicing. - Default is None for cylindrical, 1D cartesian and 2D cartesian, - and 'y' for 3d Cartesian + Default is None. output : bool, optional Whether to return the requested quantity @@ -475,6 +474,7 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, geometry = self.fields_metadata[field]['geometry'] axis_labels = self.fields_metadata[field]['axis_labels'] # - For cartesian + print(slicing, slicing_dir) if geometry in ["1dcartesian", "2dcartesian", "3dcartesian"]: F, info = read_field_cartesian( filename, field_path, axis_labels, slicing, slicing_dir) From fe50eaf384a49de538572fe473b7c334cc6da3a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxence=20Th=C3=A9venet?= Date: Tue, 15 May 2018 21:42:35 -0700 Subject: [PATCH 23/90] slicing=0 as default and minor fixes --- opmd_viewer/addons/pic/lpa_diagnostics.py | 2 +- opmd_viewer/openpmd_timeseries/main.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/opmd_viewer/addons/pic/lpa_diagnostics.py b/opmd_viewer/addons/pic/lpa_diagnostics.py index 04ffd863..1efd53e0 100644 --- a/opmd_viewer/addons/pic/lpa_diagnostics.py +++ b/opmd_viewer/addons/pic/lpa_diagnostics.py @@ -714,7 +714,7 @@ def get_spectrum( self, t=None, iteration=None, pol=None, else: theta = np.pi / 2. if "3dcartesian" in self.avail_geom: - slicing=0. + slicing = 0. if pol == 'x': slicing_dir = 'y' else: diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index fc4be747..9bdbd3bb 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -348,7 +348,7 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, return(data_list) def get_field(self, field=None, coord=None, t=None, iteration=None, - m='all', theta=0., slicing=None, slicing_dir=None, + m='all', theta=0., slicing=0., slicing_dir=None, output=True, plot=False, plot_range=[[None, None], [None, None]], **kw): """ From bc36bc51582fd1c48cf7fad715512a5e26482767 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Wed, 16 May 2018 08:17:44 -0700 Subject: [PATCH 24/90] update version number and add description --- CHANGELOG.md | 9 +++++++++ conda_recipe/meta.yaml | 3 ++- opmd_viewer/__version__.py | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6da30cd..0473c75d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log / Release Log for openPMD-viewer +## 1.0 + +This version introduces a capability to do slicing along several directions, +and for 1d, 2d, 3d and circ geometries. +It breaks backward compatibility: for a 3d field, +`get_field(field=field, coord=coord, iteration=iteration) +used to return the central slice along `y` while it returns the full 3d field +now. + ## 0.8.1 This version includes minor improvements to the viewer: diff --git a/conda_recipe/meta.yaml b/conda_recipe/meta.yaml index f112780c..da1cd0c8 100644 --- a/conda_recipe/meta.yaml +++ b/conda_recipe/meta.yaml @@ -1,4 +1,5 @@ -{% set version = "0.8.1" %} + +{% set version = "1.0.0" %} package: name: openpmd_viewer diff --git a/opmd_viewer/__version__.py b/opmd_viewer/__version__.py index 8088f751..5becc17c 100644 --- a/opmd_viewer/__version__.py +++ b/opmd_viewer/__version__.py @@ -1 +1 @@ -__version__ = "0.8.1" +__version__ = "1.0.0" From 5f0dfaa4f59eaa27f0ce6f8103f1aabf070d0791 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Fri, 18 May 2018 15:24:19 -0700 Subject: [PATCH 25/90] Added most correction suggested by Remi --- CHANGELOG.md | 2 +- opmd_viewer/addons/pic/lpa_diagnostics.py | 15 +- .../data_reader/field_reader.py | 137 ++++++++++-------- .../data_reader/utilities.py | 4 +- opmd_viewer/openpmd_timeseries/main.py | 12 +- 5 files changed, 94 insertions(+), 76 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0473c75d..e340ffb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ This version introduces a capability to do slicing along several directions, and for 1d, 2d, 3d and circ geometries. It breaks backward compatibility: for a 3d field, -`get_field(field=field, coord=coord, iteration=iteration) +```get_field(field=field, coord=coord, iteration=iteration)``` used to return the central slice along `y` while it returns the full 3d field now. diff --git a/opmd_viewer/addons/pic/lpa_diagnostics.py b/opmd_viewer/addons/pic/lpa_diagnostics.py index 1efd53e0..e26ac85c 100644 --- a/opmd_viewer/addons/pic/lpa_diagnostics.py +++ b/opmd_viewer/addons/pic/lpa_diagnostics.py @@ -438,7 +438,7 @@ def get_current( self, t=None, iteration=None, species=None, select=None, def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', freq_filter=40, index='center', theta=0, - slicing_dir='y', slicing=0., plot=False, **kw ): + slicing_dir=None, slicing=None, plot=False, **kw ): """ Calculate a laser field by filtering out high frequencies. Can either return the envelope slice-wise or a full 2D envelope. @@ -482,7 +482,6 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box - If slicing is None, the full grid is returned. Default is None slicing_dir : str or list of str, optional @@ -494,6 +493,7 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', - 1d/circ: not implemented + In cylindrical geometry, elements can be 'r' and/or 'z' Returned array is reduced by 1 dimension per slicing. + If slicing_dir is None, the full grid is returned. Default is None. plot : bool, optional @@ -714,7 +714,6 @@ def get_spectrum( self, t=None, iteration=None, pol=None, else: theta = np.pi / 2. if "3dcartesian" in self.avail_geom: - slicing = 0. if pol == 'x': slicing_dir = 'y' else: @@ -781,14 +780,13 @@ def get_a0( self, t=None, iteration=None, pol=None ): theta = 0 else: theta = np.pi / 2. + slicing = 0. if "3dcartesian" in self.avail_geom: - slicing = 0. if pol == 'x': slicing_dir = 'y' else: slicing_dir = 'x' else: - slicing = None slicing_dir = None # Get the peak field from field envelope @@ -837,14 +835,13 @@ def get_ctau( self, t=None, iteration=None, pol=None, method='fit' ): theta = 0 else: theta = np.pi / 2. + slicing = 0. if "3dcartesian" in self.avail_geom: - slicing = 0. if pol == 'x': slicing_dir = 'y' else: slicing_dir = 'x' else: - slicing = None slicing_dir = None # Get the field envelope E, info = self.get_laser_envelope(t=t, iteration=iteration, @@ -870,7 +867,7 @@ def get_ctau( self, t=None, iteration=None, pol=None, method='fit' ): raise ValueError('Unknown method: {:s}'.format(method)) def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, - slicing=0., slicing_dir='y', method='fit' ): + slicing=None, slicing_dir=None, method='fit' ): """ Calculate the waist of a (gaussian) laser pulse. ( sqrt(2) * sigma_r) @@ -957,7 +954,7 @@ def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, raise ValueError('Unknown method: {:s}'.format(method)) def get_spectrogram( self, t=None, iteration=None, pol=None, theta=0, - slicing_dir='y', slicing=0., plot=False, **kw ): + slicing_dir=None, slicing=None, plot=False, **kw ): """ Calculates the spectrogram of a laserpulse, by the FROG method. diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 9e2e81e9..66c7273c 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -15,7 +15,7 @@ def read_field_cartesian( filename, field_path, axis_labels, - slicing=None, slicing_dir=None ): + slicing, slicing_dir ): """ Extract a given field from an HDF5 file in the openPMD format, when the geometry is cartesian (1d, 2d or 3d). @@ -38,8 +38,6 @@ def read_field_cartesian( filename, field_path, axis_labels, -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box - If slicing is None, the full grid is returned. - Default is None for 1D and 2D and 0. for 3d Cartesian slicing_dir : str or list of str, optional Direction(s) along which to slice the data @@ -47,9 +45,7 @@ def read_field_cartesian( filename, field_path, axis_labels, - 1d: 'z' - 2d: 'x' and/or 'z' - 3d: 'x' and/or 'y' and/or 'z' - - 1d/circ: not implemented Returned array is reduced by 1 dimension per slicing. - Default is None for 1D and 2D and 'y' for 3d Cartesian Returns ------- @@ -58,18 +54,19 @@ def read_field_cartesian( filename, field_path, axis_labels, info : a FieldMetaInformation object (contains information about the grid; see the corresponding docstring) """ - # Convert slicing and slicing_dir to lists - if slicing is not None and not isinstance(slicing, list): - slicing = [slicing] - if slicing_dir is not None and not isinstance(slicing_dir, list): - slicing_dir = [slicing_dir] - # Pop slicing directions in arguments that are not in axis_label if slicing_dir is not None: - ind_to_pop = [slicing_dir.index(val) for val in slicing_dir if - val not in axis_labels ] - for ind in ind_to_pop: - slicing_dir.pop(ind) - slicing.pop(ind) + if not isinstance(slicing_dir, list): + slicing_dir = [slicing_dir] + if slicing is not None and not isinstance(slicing, list): + slicing = [slicing] + print(slicing_dir, axis_labels) + if any(elem not in axis_labels for elem in slicing_dir): + raise ValueError('Found elements in slicing_dir not in ' + 'axis_labels') + if len(slicing_dir) != len(slicing): + raise ValueError('Slicing and slicing_dir must have the ' + 'same length') + # Open the HDF5 file dfile = h5py.File( filename, 'r' ) # Extract the dataset and and corresponding group @@ -81,7 +78,7 @@ def read_field_cartesian( filename, field_path, axis_labels, global_offset = list( group.attrs['gridGlobalOffset'] ) # Slice selection - if slicing_dir: + if slicing_dir is not None: # Get the integer that correspond to the slicing direction list_slicing_index = [] list_i_cell = [] @@ -99,17 +96,17 @@ def read_field_cartesian( filename, field_path, axis_labels, # Remove metainformation relative to the slicing index # Successive pops starting from last coordinate to slice - list_indices_to_clean = list_slicing_index[:] - list_indices_to_clean.sort(reverse=True) - for index_to_clean in list_indices_to_clean: - shape.pop( index_to_clean ) - grid_spacing.pop( index_to_clean ) - global_offset.pop( index_to_clean ) - new_labels = new_labels[:index_to_clean] + \ - new_labels[index_to_clean + 1:] - - axes = { i: new_labels[i] for i in range(len(new_labels)) } - # Extraction of the data + shape = [ x for index, x in enumerate(shape) + if index not in list_slicing_index ] + grid_spacing = [ x for index, x in enumerate(grid_spacing) + if index not in list_slicing_index ] + global_offset = [ x for index, x in enumerate(global_offset) + if index not in list_slicing_index ] + axis_labels = [ x for index, x in enumerate(axis_labels) + if index not in list_slicing_index ] + + axes = { i: axis_labels[i] for i in range(len(axis_labels)) } + # Extract data F = get_data( dset, list_i_cell, list_slicing_index ) info = FieldMetaInformation( axes, shape, grid_spacing, global_offset, group.attrs['gridUnitSI'], dset.attrs['position'] ) @@ -125,11 +122,11 @@ def read_field_cartesian( filename, field_path, axis_labels, return( F, info ) -def read_field_circ( filename, field_path, m=0, theta=0., - slicing=None, slicing_dir=None ): +def read_field_circ( filename, field_path, slicing, slicing_dir, m=0, + theta=0. ): """ Extract a given field from an HDF5 file in the openPMD format, - when the geometry is 2d cartesian. + when the geometry is circ. Parameters ---------- @@ -152,14 +149,11 @@ def read_field_circ( filename, field_path, m=0, theta=0., -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box - If slicing is None, the full grid is returned. - Default is None. slicing_dir : str or list of str, optional Direction(s) along which to slice the data Elements can be 'r' and/or 'z' Returned array is reduced by 1 dimension per slicing. - Default is None. Returns ------- @@ -218,36 +212,63 @@ def read_field_circ( filename, field_path, m=0, theta=0., # Perform slicing if needed if slicing_dir is not None: - # Convert arguments to lists - if not isinstance(slicing, list): - slicing = [slicing] if not isinstance(slicing_dir, list): slicing_dir = [slicing_dir] + if slicing is not None and not isinstance(slicing, list): + slicing = [slicing] + print(slicing_dir, axis_labels) + if any(elem not in axis_labels for elem in slicing_dir): + raise ValueError('Found elements in slicing_dir not in ' + 'axis_labels') + if len(slicing_dir) != len(slicing): + raise ValueError('Slicing and slicing_dir must have the ' + 'same length') + # Slice field and clear metadata - # First z direction - if 'z' in slicing_dir: - ind = slicing_dir.index('z') - n_cells = shape[ 1 ] - i_cell = int( 0.5 * (slicing[ind] + 1.) * n_cells ) + list_slicing_index = [] + list_i_cell = [] + for count, slicing_dir_item in enumerate(slicing_dir): + slicing_index = axis_labels.index(slicing_dir_item) + list_slicing_index.append(slicing_index) + # Number of cells along the slicing direction + n_cells = shape[ slicing_index ] + # Index of the slice (prevent stepping out of the array) + i_cell = int( 0.5 * (slicing[count] + 1.) * n_cells ) i_cell = max( i_cell, 0 ) i_cell = min( i_cell, n_cells - 1) - F_total = F_total[:, i_cell] - shape.pop( ind ) - grid_spacing.pop( ind ) - global_offset.pop( ind ) - axis_labels = axis_labels[:-1] + list_i_cell.append(i_cell) + shape = [ x for index, x in enumerate(shape) + if index not in list_slicing_index ] + grid_spacing = [ x for index, x in enumerate(grid_spacing) + if index not in list_slicing_index ] + global_offset = [ x for index, x in enumerate(global_offset) + if index not in list_slicing_index ] + axis_labels = [ x for index, x in enumerate(axis_labels) + if index not in list_slicing_index ] + # First z direction +# if 'z' in slicing_dir: +# ind = slicing_dir.index('z') +# n_cells = shape[ 1 ] +# i_cell = int( 0.5 * (slicing[ind] + 1.) * n_cells ) +# i_cell = max( i_cell, 0 ) +# i_cell = min( i_cell, n_cells - 1) +# F_total = F_total[:, i_cell] +# shape.pop( ind ) +# grid_spacing.pop( ind ) +# global_offset.pop( ind ) +# axis_labels = axis_labels[:-1] # Then r direction - if 'r' in slicing_dir: - ind = slicing_dir.index('r') - n_cells = shape[ 0 ] - i_cell = int( 0.5 * (slicing[ind] + 1.) * n_cells ) - i_cell = max( i_cell, 0 ) - i_cell = min( i_cell, n_cells - 1) - F_total = F_total[i_cell, ...] - shape.pop( ind ) - grid_spacing.pop( ind ) - global_offset.pop( ind ) - axis_labels = axis_labels[1:] +# if 'r' in slicing_dir: +# ind = slicing_dir.index('r') +# n_cells = shape[ 0 ] +# i_cell = int( 0.5 * (slicing[ind] + 1.) * n_cells ) +# i_cell = max( i_cell, 0 ) +# i_cell = min( i_cell, n_cells - 1) +# F_total = F_total[i_cell, ...] +# shape.pop( ind ) +# grid_spacing.pop( ind ) +# global_offset.pop( ind ) +# axis_labels = axis_labels[1:] axes = { i: axis_labels[i] for i in range(len(axis_labels)) } info = FieldMetaInformation( axes, tuple(shape), grid_spacing, global_offset, diff --git a/opmd_viewer/openpmd_timeseries/data_reader/utilities.py b/opmd_viewer/openpmd_timeseries/data_reader/utilities.py index 94b12c99..467f734f 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/utilities.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/utilities.py @@ -80,13 +80,13 @@ def get_data(dset, i_slice=None, pos_slice=None, output_type=np.float64): pos_slice = [pos_slice] if i_slice is not None and not isinstance(i_slice, list): i_slice = [i_slice] - # Case of a constant dataset if isinstance(dset, h5py.Group): shape = dset.attrs['shape'] # Restrict the shape if slicing is enabled if pos_slice is not None: - shape = shape[:pos_slice[0]] + shape[pos_slice[0] + 1:] + shape = [ x for index, x in enumerate(shape) if + index not in pos_slice ] # Create the corresponding dataset data = dset.attrs['value'] * np.ones(shape) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 9bdbd3bb..f77b3bb7 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -483,10 +483,10 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, if (coord in ['x', 'y']) and \ (self.fields_metadata[field]['type'] == 'vector'): # For Cartesian components, combine r and t components - Fr, info = read_field_circ(filename, field + '/r', m, theta, - slicing, slicing_dir) - Ft, info = read_field_circ(filename, field + '/t', m, theta, - slicing, slicing_dir) + Fr, info = read_field_circ(filename, field + '/r', slicing, + slicing_dir, m, theta) + Ft, info = read_field_circ(filename, field + '/t', slicing, + slicing_dir, m, theta) if coord == 'x': F = np.cos(theta) * Fr - np.sin(theta) * Ft elif coord == 'y': @@ -496,8 +496,8 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, F[: int(F.shape[0] / 2)] *= -1 else: # For cylindrical or scalar components, no special treatment - F, info = read_field_circ(filename, field_path, m, theta, - slicing, slicing_dir) + F, info = read_field_circ(filename, field_path, slicing, + slicing_dir, m, theta) # Plot the resulting field # Deactivate plotting when there is no slice selection From f8de77d7c153f7c50fb2955e5765aebebb988ff5 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Mon, 21 May 2018 10:49:39 -0700 Subject: [PATCH 26/90] Change default value for slicing and minor corrections --- opmd_viewer/addons/pic/lpa_diagnostics.py | 8 +++--- .../data_reader/field_reader.py | 26 +------------------ 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/opmd_viewer/addons/pic/lpa_diagnostics.py b/opmd_viewer/addons/pic/lpa_diagnostics.py index e26ac85c..c08b737e 100644 --- a/opmd_viewer/addons/pic/lpa_diagnostics.py +++ b/opmd_viewer/addons/pic/lpa_diagnostics.py @@ -438,7 +438,7 @@ def get_current( self, t=None, iteration=None, species=None, select=None, def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', freq_filter=40, index='center', theta=0, - slicing_dir=None, slicing=None, plot=False, **kw ): + slicing_dir=None, slicing=0., plot=False, **kw ): """ Calculate a laser field by filtering out high frequencies. Can either return the envelope slice-wise or a full 2D envelope. @@ -482,7 +482,7 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box - Default is None + Default is 0. slicing_dir : str or list of str, optional Direction(s) along which to slice the data @@ -490,7 +490,6 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', - 1d: 'z' - 2d: 'x' and/or 'z' - 3d: 'x' and/or 'y' and/or 'z' - - 1d/circ: not implemented + In cylindrical geometry, elements can be 'r' and/or 'z' Returned array is reduced by 1 dimension per slicing. If slicing_dir is None, the full grid is returned. @@ -714,6 +713,7 @@ def get_spectrum( self, t=None, iteration=None, pol=None, else: theta = np.pi / 2. if "3dcartesian" in self.avail_geom: + slicing = 0. if pol == 'x': slicing_dir = 'y' else: @@ -954,7 +954,7 @@ def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, raise ValueError('Unknown method: {:s}'.format(method)) def get_spectrogram( self, t=None, iteration=None, pol=None, theta=0, - slicing_dir=None, slicing=None, plot=False, **kw ): + slicing_dir=None, slicing=0., plot=False, **kw ): """ Calculates the spectrogram of a laserpulse, by the FROG method. diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 66c7273c..3ae0ae4f 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -59,7 +59,6 @@ def read_field_cartesian( filename, field_path, axis_labels, slicing_dir = [slicing_dir] if slicing is not None and not isinstance(slicing, list): slicing = [slicing] - print(slicing_dir, axis_labels) if any(elem not in axis_labels for elem in slicing_dir): raise ValueError('Found elements in slicing_dir not in ' 'axis_labels') @@ -245,30 +244,7 @@ def read_field_circ( filename, field_path, slicing, slicing_dir, m=0, if index not in list_slicing_index ] axis_labels = [ x for index, x in enumerate(axis_labels) if index not in list_slicing_index ] - # First z direction -# if 'z' in slicing_dir: -# ind = slicing_dir.index('z') -# n_cells = shape[ 1 ] -# i_cell = int( 0.5 * (slicing[ind] + 1.) * n_cells ) -# i_cell = max( i_cell, 0 ) -# i_cell = min( i_cell, n_cells - 1) -# F_total = F_total[:, i_cell] -# shape.pop( ind ) -# grid_spacing.pop( ind ) -# global_offset.pop( ind ) -# axis_labels = axis_labels[:-1] - # Then r direction -# if 'r' in slicing_dir: -# ind = slicing_dir.index('r') -# n_cells = shape[ 0 ] -# i_cell = int( 0.5 * (slicing[ind] + 1.) * n_cells ) -# i_cell = max( i_cell, 0 ) -# i_cell = min( i_cell, n_cells - 1) -# F_total = F_total[i_cell, ...] -# shape.pop( ind ) -# grid_spacing.pop( ind ) -# global_offset.pop( ind ) -# axis_labels = axis_labels[1:] + axes = { i: axis_labels[i] for i in range(len(axis_labels)) } info = FieldMetaInformation( axes, tuple(shape), grid_spacing, global_offset, From 3c24d0c24c17edcd21b153b9bd2926fdae94f4d5 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Mon, 21 May 2018 10:50:33 -0700 Subject: [PATCH 27/90] cleaning --- opmd_viewer/openpmd_timeseries/data_reader/field_reader.py | 1 - 1 file changed, 1 deletion(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 3ae0ae4f..f2b0c34c 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -81,7 +81,6 @@ def read_field_cartesian( filename, field_path, axis_labels, # Get the integer that correspond to the slicing direction list_slicing_index = [] list_i_cell = [] - new_labels = axis_labels for count, slicing_dir_item in enumerate(slicing_dir): slicing_index = axis_labels.index(slicing_dir_item) list_slicing_index.append(slicing_index) From 16772fe395c64e0a40131b78f234bea4177b77d7 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Mon, 21 May 2018 11:48:37 -0700 Subject: [PATCH 28/90] fix 2 docstrings and remove print statement --- opmd_viewer/addons/pic/lpa_diagnostics.py | 1 - opmd_viewer/openpmd_timeseries/main.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/opmd_viewer/addons/pic/lpa_diagnostics.py b/opmd_viewer/addons/pic/lpa_diagnostics.py index c08b737e..299b9f90 100644 --- a/opmd_viewer/addons/pic/lpa_diagnostics.py +++ b/opmd_viewer/addons/pic/lpa_diagnostics.py @@ -904,7 +904,6 @@ def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, - 1d: 'z' - 2d: 'x' and/or 'z' - 3d: 'x' and/or 'y' and/or 'z' - - 1d/circ: not implemented + In cylindrical geometry, elements can be 'r' and/or 'z' Returned array is reduced by 1 dimension per slicing. Default is None. diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index f77b3bb7..1846ac3b 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -398,7 +398,6 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, - 1d: 'z' - 2d: 'x' and/or 'z' - 3d: 'x' and/or 'y' and/or 'z' - - 1d/circ: not implemented + In cylindrical geometry, elements can be 'r' and/or 'z' Returned array is reduced by 1 dimension per slicing. Default is None. @@ -474,7 +473,6 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, geometry = self.fields_metadata[field]['geometry'] axis_labels = self.fields_metadata[field]['axis_labels'] # - For cartesian - print(slicing, slicing_dir) if geometry in ["1dcartesian", "2dcartesian", "3dcartesian"]: F, info = read_field_cartesian( filename, field_path, axis_labels, slicing, slicing_dir) From 8bf6be312ff556f8f91454666e34581b675a358f Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Tue, 22 May 2018 15:56:33 -0700 Subject: [PATCH 29/90] fix slicing in circ mode --- opmd_viewer/openpmd_timeseries/data_reader/field_reader.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index f2b0c34c..3d226fdf 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -224,7 +224,6 @@ def read_field_circ( filename, field_path, slicing, slicing_dir, m=0, # Slice field and clear metadata list_slicing_index = [] - list_i_cell = [] for count, slicing_dir_item in enumerate(slicing_dir): slicing_index = axis_labels.index(slicing_dir_item) list_slicing_index.append(slicing_index) @@ -234,7 +233,9 @@ def read_field_circ( filename, field_path, slicing, slicing_dir, m=0, i_cell = int( 0.5 * (slicing[count] + 1.) * n_cells ) i_cell = max( i_cell, 0 ) i_cell = min( i_cell, n_cells - 1) - list_i_cell.append(i_cell) + F_total = np.take( F_total, [i_cell], axis=slicing_index ) + F_total = np.squeeze(F_total) + shape = [ x for index, x in enumerate(shape) if index not in list_slicing_index ] grid_spacing = [ x for index, x in enumerate(grid_spacing) From a7e196576d23441819ab49fb2be352a299f7c5b4 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Wed, 23 May 2018 08:28:28 -0700 Subject: [PATCH 30/90] Expand error message --- .../data_reader/field_reader.py | 32 +++---------------- opmd_viewer/openpmd_timeseries/main.py | 23 +++++++++++-- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 3d226fdf..30c60264 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -32,14 +32,14 @@ def read_field_cartesian( filename, field_path, axis_labels, axis_labels: list of strings The name of the dimensions of the array (e.g. ['x', 'y', 'z']) - slicing : float or list of float, optional + slicing : list of float or None Number(s) between -1 and 1 that indicate where to slice the data, along the directions in `slicing_dir` -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box - slicing_dir : str or list of str, optional + slicing_dir : list of str or None Direction(s) along which to slice the data Elements can be: - 1d: 'z' @@ -54,18 +54,6 @@ def read_field_cartesian( filename, field_path, axis_labels, info : a FieldMetaInformation object (contains information about the grid; see the corresponding docstring) """ - if slicing_dir is not None: - if not isinstance(slicing_dir, list): - slicing_dir = [slicing_dir] - if slicing is not None and not isinstance(slicing, list): - slicing = [slicing] - if any(elem not in axis_labels for elem in slicing_dir): - raise ValueError('Found elements in slicing_dir not in ' - 'axis_labels') - if len(slicing_dir) != len(slicing): - raise ValueError('Slicing and slicing_dir must have the ' - 'same length') - # Open the HDF5 file dfile = h5py.File( filename, 'r' ) # Extract the dataset and and corresponding group @@ -141,14 +129,14 @@ def read_field_circ( filename, field_path, slicing, slicing_dir, m=0, theta : float, optional Angle of the plane of observation with respect to the x axis - slicing : float or list of float, optional + slicing : list of float or None Number(s) between -1 and 1 that indicate where to slice the data, along the directions in `slicing_dir` -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box - slicing_dir : str or list of str, optional + slicing_dir : list of str or None Direction(s) along which to slice the data Elements can be 'r' and/or 'z' Returned array is reduced by 1 dimension per slicing. @@ -210,18 +198,6 @@ def read_field_circ( filename, field_path, slicing, slicing_dir, m=0, # Perform slicing if needed if slicing_dir is not None: - if not isinstance(slicing_dir, list): - slicing_dir = [slicing_dir] - if slicing is not None and not isinstance(slicing, list): - slicing = [slicing] - print(slicing_dir, axis_labels) - if any(elem not in axis_labels for elem in slicing_dir): - raise ValueError('Found elements in slicing_dir not in ' - 'axis_labels') - if len(slicing_dir) != len(slicing): - raise ValueError('Slicing and slicing_dir must have the ' - 'same length') - # Slice field and clear metadata list_slicing_index = [] for count, slicing_dir_item in enumerate(slicing_dir): diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 1846ac3b..9dd82cb6 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -389,8 +389,6 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box - If slicing is None, the full grid is returned. - Default is None slicing_dir : str or list of str, optional Direction(s) along which to slice the data @@ -400,7 +398,7 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, - 3d: 'x' and/or 'y' and/or 'z' + In cylindrical geometry, elements can be 'r' and/or 'z' Returned array is reduced by 1 dimension per slicing. - Default is None. + If slicing is None, the full grid is returned. output : bool, optional Whether to return the requested quantity @@ -434,6 +432,25 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, "The `field` argument is missing or erroneous.\n" "The available fields are: \n - %s\nPlease set the `field` " "argument accordingly." % field_list) + # Check slicing + if slicing_dir is not None: + # Convert to lists + if not isinstance(slicing_dir, list): + slicing_dir = [slicing_dir] + if not isinstance(slicing, list): + slicing = [slicing] + # Check that the elements are valid + axis_labels = self.fields_metadata[field]['axis_labels'] + for axis in slicing_dir: + if axis not in axis_labels: + axes_list = '\n - '.join(axis_labels) + raise OpenPMDException( + 'The `slicing_dir` argument is erroneous: contains %s\n' + 'The available axes are: \n - %s' %(axis, axes_list) ) + if len(slicing_dir) != len(slicing): + raise OpenPMDException('Slicing and slicing_dir must have the ' + 'same length') + # Check the coordinate (for vector fields) if self.fields_metadata[field]['type'] == 'vector': available_coord = ['x', 'y', 'z'] From 6ee515b196b3fbfda5eb589332197c2a04993468 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Wed, 23 May 2018 08:46:23 -0700 Subject: [PATCH 31/90] Improve plotting support for sliced data --- opmd_viewer/openpmd_timeseries/main.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 9dd82cb6..b1029b28 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -448,9 +448,9 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, 'The `slicing_dir` argument is erroneous: contains %s\n' 'The available axes are: \n - %s' %(axis, axes_list) ) if len(slicing_dir) != len(slicing): - raise OpenPMDException('Slicing and slicing_dir must have the ' - 'same length') - + raise OpenPMDException( + 'The `slicing_dir` argument is erroneous: \nIt should have' + 'the same number of elements as `slicing_dir`.') # Check the coordinate (for vector fields) if self.fields_metadata[field]['type'] == 'vector': available_coord = ['x', 'y', 'z'] @@ -516,16 +516,17 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, # Plot the resulting field # Deactivate plotting when there is no slice selection - if (geometry == "3dcartesian") and (slicing is None): - plot = False if plot: - if geometry == "1dcartesian": + if F.ndim == 1: self.plotter.show_field_1d(F, info, field_label, self._current_i, plot_range=plot_range, **kw) - else: + elif F.ndim == 2: self.plotter.show_field_2d(F, info, slicing_dir, m, - field_label, geometry, self._current_i, - plot_range=plot_range, **kw) + field_label, geometry, self._current_i, + plot_range=plot_range, **kw) + else: + raise OpenPMDException('Cannot plot %d-dimensional data.\n' + 'Use slicing to reduce dimension, or set `plot=False`'%F.ndim ) # Return the result return(F, info) From c8e8de9c825b675882af7744fe753cdb966b2b67 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Wed, 23 May 2018 09:04:36 -0700 Subject: [PATCH 32/90] Improve support for slicing in the slider --- opmd_viewer/openpmd_timeseries/interactive.py | 47 ++++++++++++++----- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/interactive.py b/opmd_viewer/openpmd_timeseries/interactive.py index 45644332..a87ed651 100644 --- a/opmd_viewer/openpmd_timeseries/interactive.py +++ b/opmd_viewer/openpmd_timeseries/interactive.py @@ -111,13 +111,19 @@ def refresh_field(change=None, force=False): plot_range = [ fld_hrange_button.get_range(), fld_vrange_button.get_range() ] + # Handle slicing direction + if slicing_dir_button.value=='None': + slicing_dir = None + else: + slicing_dir = slicing_dir_button.value + # Call the method get_field self.get_field( iteration=self.current_iteration, output=False, plot=True, field=fieldtype_button.value, coord=coord_button.value, m=convert_to_int(mode_button.value), slicing=slicing_button.value, theta=theta_button.value, - slicing_dir=slicing_dir_button.value, + slicing_dir=slicing_dir, plot_range=plot_range, **kw_fld ) def refresh_ptcl(change=None, force=False): @@ -193,6 +199,11 @@ def refresh_field_type(change): whenever a change of a widget happens (see docstring of ipywidgets.Widget.observe) """ + # Deactivate the field refreshing to avoid callback + # while modifying the widgets + saved_refresh_value = fld_refresh_toggle.value + fld_refresh_toggle.value = False + new_field = change['new'] # Activate/deactivate vector fields if self.fields_metadata[new_field]['type'] == 'vector': @@ -206,13 +217,19 @@ def refresh_field_type(change): else: mode_button.disabled = True theta_button.disabled = True - # Activate/deactivate 3d-specific widgets + # Activate the right slicing options if self.fields_metadata[new_field]['geometry'] == '3dcartesian': - slicing_dir_button.disabled = False - slicing_button.disabled = False + slicing_dir_button.options = \ + self.fields_metadata[new_field]['axis_labels'] + slicing_dir_button.value = 'y' else: - slicing_dir_button.disabled = True - slicing_button.disabled = True + slicing_dir_button.options = ['None'] + \ + self.fields_metadata[new_field]['axis_labels'] + slicing_dir_button.value = 'None' + + # Put back the previous value of the refreshing button + fld_refresh_toggle.value = saved_refresh_value + # Show the fields refresh_field() @@ -337,9 +354,15 @@ def step_bw(b): min=-math.pi / 2, max=math.pi / 2) set_widget_dimensions( theta_button, width=190 ) theta_button.observe( refresh_field, 'value', 'change') - # Slicing buttons (for 3D) - slicing_dir_button = create_toggle_buttons( value='y', - options=['x', 'y', 'z'], description='Slice normal:') + # Slicing buttons + if self.fields_metadata[field]['geometry'] == '3dcartesian': + slicing_dir_button = create_toggle_buttons( value='y', + options=self.fields_metadata[field]['axis_labels'], + description='Slice normal:') + else: + slicing_dir_button = create_toggle_buttons( value='None', + options=['None'] + self.fields_metadata[field]['axis_labels'], + description='Slice normal:') slicing_dir_button.observe( refresh_field, 'value', 'change' ) slicing_button = widgets.FloatSlider( min=-1., max=1., value=0.) set_widget_dimensions( slicing_button, width=180 ) @@ -375,10 +398,8 @@ def step_bw(b): # Add widgets specific to azimuthal modes field_widget_list += [ mode_button, add_description('Theta:', theta_button)] - elif "3dcartesian" in self.avail_geom: - # Add widgets specific to cartesian 3d - field_widget_list += [ slicing_dir_button, - add_description("Slicing:", slicing_button) ] + field_widget_list += [ slicing_dir_button, + add_description("Slicing:", slicing_button) ] container_fields = widgets.VBox( children=field_widget_list ) set_widget_dimensions( container_fields, width=330 ) # Plotting options container From 9292463b8f5fda87835e43270fccc49f2ce4a9ee Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Wed, 23 May 2018 09:41:12 -0700 Subject: [PATCH 33/90] Fix pep8 issues --- opmd_viewer/openpmd_timeseries/interactive.py | 7 ++++--- opmd_viewer/openpmd_timeseries/main.py | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/interactive.py b/opmd_viewer/openpmd_timeseries/interactive.py index a87ed651..2450ce39 100644 --- a/opmd_viewer/openpmd_timeseries/interactive.py +++ b/opmd_viewer/openpmd_timeseries/interactive.py @@ -112,7 +112,7 @@ def refresh_field(change=None, force=False): fld_vrange_button.get_range() ] # Handle slicing direction - if slicing_dir_button.value=='None': + if slicing_dir_button.value == 'None': slicing_dir = None else: slicing_dir = slicing_dir_button.value @@ -355,13 +355,14 @@ def step_bw(b): set_widget_dimensions( theta_button, width=190 ) theta_button.observe( refresh_field, 'value', 'change') # Slicing buttons + axis_labels = self.fields_metadata[field]['axis_labels'] if self.fields_metadata[field]['geometry'] == '3dcartesian': slicing_dir_button = create_toggle_buttons( value='y', - options=self.fields_metadata[field]['axis_labels'], + options=axis_labels, description='Slice normal:') else: slicing_dir_button = create_toggle_buttons( value='None', - options=['None'] + self.fields_metadata[field]['axis_labels'], + options=['None'] + axis_labels, description='Slice normal:') slicing_dir_button.observe( refresh_field, 'value', 'change' ) slicing_button = widgets.FloatSlider( min=-1., max=1., value=0.) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index b1029b28..af92ecee 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -446,7 +446,7 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, axes_list = '\n - '.join(axis_labels) raise OpenPMDException( 'The `slicing_dir` argument is erroneous: contains %s\n' - 'The available axes are: \n - %s' %(axis, axes_list) ) + 'The available axes are: \n - %s' % (axis, axes_list) ) if len(slicing_dir) != len(slicing): raise OpenPMDException( 'The `slicing_dir` argument is erroneous: \nIt should have' @@ -526,7 +526,7 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, plot_range=plot_range, **kw) else: raise OpenPMDException('Cannot plot %d-dimensional data.\n' - 'Use slicing to reduce dimension, or set `plot=False`'%F.ndim ) + 'Use slicing, or set `plot=False`' % F.ndim) # Return the result return(F, info) From c202cb7796a4cc34782cea1aa8e2133e0188915e Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Wed, 23 May 2018 10:05:19 -0700 Subject: [PATCH 34/90] Fix slicing for cylindrical data --- .../data_reader/field_metainfo.py | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py b/opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py index d83f2462..a5023b92 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py @@ -46,6 +46,7 @@ class FieldMetaInformation(object): then these variables will be called x, y. - imshow_extent: 1darray + (Only for 2D data) An array of 4 elements that can be passed as the `extent` in matplotlib's imshow function. Because of the API of the imshow function, the coordinates are @@ -67,7 +68,8 @@ def __init__(self, axes, shape, grid_spacing, """ # Register important initial information self.axes = axes - self.imshow_extent = [] + if len(shape) == 2: + self.imshow_extent = [] # Create the elements for axis in sorted(axes.keys()): @@ -77,6 +79,11 @@ def __init__(self, axes, shape, grid_spacing, start = global_offset[axis] * grid_unitSI + position[axis] * step end = start + (n_points - 1) * step axis_points = np.linspace(start, end, n_points, endpoint=True) + # Create the points below the axis if thetaMode is true + if axes[axis] == 'r' and thetaMode: + axis_points = np.concatenate((-axis_points[::-1], axis_points)) + start = -end + n_points = 2 * n_points # Register the results in the object axis_name = axes[axis] setattr(self, axis_name, axis_points) @@ -86,19 +93,13 @@ def __init__(self, axes, shape, grid_spacing, # Fill the imshow_extent in reverse order, so as to match # the syntax of imshow ; add a half step on each side since # imshow plots a square of finite width for each field value - self.imshow_extent = \ - [start - 0.5 * step, end + 0.5 * step] + self.imshow_extent - - # Create the points below the axis if thetaMode is true - if thetaMode: - if 'r' in axes: - self.r = np.concatenate((-self.r[::-1], self.r)) - # The axis now extends from -rmax to rmax - self.rmin = -self.rmax - self.imshow_extent[2] = -self.imshow_extent[3] + if len(shape) == 2: + self.imshow_extent = \ + [start - 0.5 * step, end + 0.5 * step] + self.imshow_extent # Finalize imshow_extent by converting it from list to array - self.imshow_extent = np.array(self.imshow_extent) + if len(shape) == 2: + self.imshow_extent = np.array(self.imshow_extent) def restrict_to_1Daxis(self, axis): """ From 7e575f4586df19d53408e89e530cd327528d32a9 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 24 May 2018 08:33:02 -0700 Subject: [PATCH 35/90] Stack the result of iterate only when possible --- opmd_viewer/openpmd_timeseries/main.py | 7 ++++--- opmd_viewer/openpmd_timeseries/utilities.py | 13 +++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index af92ecee..2730f771 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -11,7 +11,8 @@ import numpy as np import h5py as h5 from tqdm import tqdm -from .utilities import list_h5_files, apply_selection, fit_bins_to_grid +from .utilities import list_h5_files, apply_selection, \ + fit_bins_to_grid, try_stacking from .plotter import Plotter from .particle_tracker import ParticleTracker from .data_reader.params_reader import read_openPMD_params @@ -561,9 +562,9 @@ def iterate( self, called_method, *args, **kwargs ): # Try to stack the arrays if returns_tuple: for i in range(tuple_length): - accumulated_result[i] = np.stack(accumulated_result[i], axis=0) + accumulated_result[i] = try_stacking( accumulated_result[i] ) else: - accumulated_result = np.stack( accumulated_result, axis=0 ) + accumulated_result = try_stacking( accumulated_result ) return accumulated_result diff --git a/opmd_viewer/openpmd_timeseries/utilities.py b/opmd_viewer/openpmd_timeseries/utilities.py index 5e6c0173..0d31a1c6 100644 --- a/opmd_viewer/openpmd_timeseries/utilities.py +++ b/opmd_viewer/openpmd_timeseries/utilities.py @@ -116,6 +116,19 @@ def apply_selection(file_handle, data_list, select, species, extensions): return(data_list) +def try_stacking( L ): + """ + TODO + """ + # Check that all element are arrays of the same shape + if all( type(x) is np.ndarray for x in L ) \ + and all( x.shape == L[0].shape for x in L ): + # Stack the arrays + return np.stack( L, axis=0 ) + else: + # Do not stack + return L + def fit_bins_to_grid( hist_size, grid_size, grid_range ): """ Given a tentative number of bins `hist_size` for a histogram over From 16a9945b67c718d981165156695c5c144c7c79e6 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Fri, 25 May 2018 06:12:25 -0700 Subject: [PATCH 36/90] Correct style --- opmd_viewer/openpmd_timeseries/main.py | 2 +- opmd_viewer/openpmd_timeseries/utilities.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 2730f771..a6f4ca20 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -12,7 +12,7 @@ import h5py as h5 from tqdm import tqdm from .utilities import list_h5_files, apply_selection, \ - fit_bins_to_grid, try_stacking + fit_bins_to_grid, try_stacking from .plotter import Plotter from .particle_tracker import ParticleTracker from .data_reader.params_reader import read_openPMD_params diff --git a/opmd_viewer/openpmd_timeseries/utilities.py b/opmd_viewer/openpmd_timeseries/utilities.py index 0d31a1c6..375ce41c 100644 --- a/opmd_viewer/openpmd_timeseries/utilities.py +++ b/opmd_viewer/openpmd_timeseries/utilities.py @@ -122,13 +122,14 @@ def try_stacking( L ): """ # Check that all element are arrays of the same shape if all( type(x) is np.ndarray for x in L ) \ - and all( x.shape == L[0].shape for x in L ): - # Stack the arrays - return np.stack( L, axis=0 ) + and all( x.shape == L[0].shape for x in L ): + # Stack the arrays + return np.stack( L, axis=0 ) else: # Do not stack return L + def fit_bins_to_grid( hist_size, grid_size, grid_range ): """ Given a tentative number of bins `hist_size` for a histogram over From f263a34bf5f6f0978512a4401b0613d35f3e639a Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Fri, 25 May 2018 06:22:57 -0700 Subject: [PATCH 37/90] Add documentation --- opmd_viewer/openpmd_timeseries/main.py | 15 ++++++++++++++- opmd_viewer/openpmd_timeseries/utilities.py | 4 +++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index a6f4ca20..1df5046d 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -534,7 +534,20 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, def iterate( self, called_method, *args, **kwargs ): """ - TODO + Repeated calls the method `called_method` for every iteration of this + timeseries, with the arguments `*args` and `*kwargs`. + + The result of these calls is returned as a list, or, whenever possible + as a stacked array, where the first axis corresponds to the iterations. + + If `called_method` returns a tuple, then `iterate` returns a + tuple of lists (or stacked arrays). + + Parameters + ---------- + *args, **kwargs: arguments and keyword arguments + Arguments that would normally be passed to `called_method` for + a single iteration. Do not pass the argument `t` or `iteration`. """ # Add the iteration key in the keyword aguments kwargs['iteration'] = self.iterations[0] diff --git a/opmd_viewer/openpmd_timeseries/utilities.py b/opmd_viewer/openpmd_timeseries/utilities.py index 375ce41c..ff9c4b70 100644 --- a/opmd_viewer/openpmd_timeseries/utilities.py +++ b/opmd_viewer/openpmd_timeseries/utilities.py @@ -118,7 +118,9 @@ def apply_selection(file_handle, data_list, select, species, extensions): def try_stacking( L ): """ - TODO + Attempt to stack the elements of the list L in a single array. + + This is done only if the elements of L are arrays of the same shape. """ # Check that all element are arrays of the same shape if all( type(x) is np.ndarray for x in L ) \ From 8160cdce9f34179c5b64c44a87eef90488b5279f Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Fri, 25 May 2018 06:36:13 -0700 Subject: [PATCH 38/90] Update example --- opmd_viewer/openpmd_timeseries/main.py | 4 +- tutorials/4_Particle_selection.ipynb | 76 +++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 1df5046d..622fb4de 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -554,10 +554,10 @@ def iterate( self, called_method, *args, **kwargs ): # Check the shape of results result = called_method(*args, **kwargs) - if type( result ) == tuple: + if type( result ) in [tuple, list]: returns_tuple = True tuple_length = len(result) - accumulated_result = ( [element] for element in result ) + accumulated_result = list( [element] for element in result ) else: returns_tuple = False accumulated_result = [ result ] diff --git a/tutorials/4_Particle_selection.ipynb b/tutorials/4_Particle_selection.ipynb index 699f380f..17a492f5 100644 --- a/tutorials/4_Particle_selection.ipynb +++ b/tutorials/4_Particle_selection.ipynb @@ -99,7 +99,7 @@ { "data": { "text/plain": [ - "[]" + "[]" ] }, "execution_count": 4, @@ -110,7 +110,7 @@ "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYMAAAEZCAYAAAB1mUk3AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4xLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvAOZPmwAAIABJREFUeJzsnWd4VEUXgN8TOiFAJCC9CEizUFUsWFCaoiBFEFERRT+MWFFQRAQE7IBBJRhARbqKqAhSRDoGIkWqkd5bqCGQkPl+zN3N3i3JJqQsybzPs0/2zp07d/buZs7MOWfOEaUUBoPBYMjbBOV0BwwGg8GQ8xhhYDAYDAYjDAwGg8FghIHBYDAYMMLAYDAYDBhhYDAYDAaMMMgSRGSQiEzK6X4Ysg4RKSIiP4vIKRGZkcltlxaRbSJS2Dr+TUSeyMx7ZKBPZ0XkmpzsQ3oQkRtEZEVO9+NKwgiDAEVE7hKRfTndj4wgIhNFZGg23etpEYm1Bqu5IlLe5VwhEflSRA6LyAlr8K7go507rDZcX0pEOvi4dUfgaqCUUqpTJn+sfsAEpVQCgFKqtVLqa6ufT4rIsky+nw0RWSwiT7uWKaWKKaV2ZMG9JonIQRE5LSLb3e8rIs1FZKuIxIvIHyJSxeVcIREZb117SERecenvBuCkiLTN7D7nVowwuIIRkfw53YecRETuBIYBDwFXATuBKS5VXgSaAjcA5YGTwGfe2lJKLbUGvGJKqWLAA8BZYK6P21cBtiulkjLjszgQkULAE0CWrCwD8DczHKiqlCoOPAgMFZFGACISBvwAvI3+ftcA01yuHQTURH8XdwOvi0grl/PfAc9m9QfINSilzCsDL/Tg8j1wFD0I9XE5NwiY5HJ8C7ACPRitB+5yOXcVMAE4AMQBs4Bg4DyQjB6Qzlr3GwTMRA8Up4GngULASOv6A9b7QlbbdwH7gFeBI8BBoIfLvdsAm4EzwH7gtUx4Lr2AROCi1e+fs/A7+AgY4/adKKC6dfwF8IHL+fuBbX62PQE9O/d27l3r8yVan7EnUAP4EzgFHAOmZfAzNQNi3coWW991HSABuGTd96R1vpD1LPYAh4EvgSJuv4E3gEPAt0Ao8Iv1242z3le06r9ntZ9g3SPCKldADet9CeAb6/rdwAAgyDr3JLDM6k8c+n+jtZ+fvZb1G+3s8lta4XLe8X9R2zreD7RwOT8EmOpyXMGqXyirfoO56ZXjHbgSX+gV1VpgIFAQuAbYAbS0zg/CEgbWD/I4euANAu6zjktb539Fz3ZCgQLAnVb5XcA+t/sOsgagdlZbRYDBwCqgDFAaLXSGuLSRZNUpYPUhHgi1zh8E7rDehwINXe51Erg9g89nIjA0jTobrHt4e33u530+dq1rPWsFPGQdNwaWo4VEUWAyMNKPdouiBeRdqdRxfsfW8RTgLet7KXwZz+554Fe3ssXA09b7J4FlbudHArPRE4sQ4GdguNtv4H200CgClAI6WJ8zBJgBzPJ2P5cyV2HwDfCTdW1VYDvQ06V/icAzQD7gf+hJiqTymT+3fpcKiAGKWeWjgC/c6v5j9T3Uqn+1y7mOwEa3+qeBG7J6TMgNL6MmyhhN0IP5YKXURaV1qeOALl7qPgbMUUrNUUolK6Xmo5e7bUSkHNAaeE4pFaeUSlRK/ZnGvVcqpWZZbZ0HugGDlVJHlFJH0bPW7i71E63ziUqpOejZXi2Xc3VFpLh1/xjHRUqpkkqpLNNNK6VusO7h7dXbz2bmAJ0tY2ERtHBW6EEO9CC1Bz2DPI2eWQ/2o90O6Nl9Wt+FK4lodUV5pVTCZTy7kmhB5BciIuiB92Wl1Aml1Bm06sz1t5gMvKOUuqCUOq+UOq6U+l4pFW/Vfw+408/75QMeAforpc4opXahhbLrb263UmqcUuoS8DVQDm1f8Yr1fYcAd6DVQhesU8XQKy1XTll1i7kcu59z5Qz6mWYalp3iiIj840fdZiISIyJJItLRpby+iKwUkU0iskFEHsnMPmYEIwwyRhWgvIicdLyAN/H+g68CdHKrezv6H6QScEIpFZeOe+91Oy6PXqo72G2VOTiu7HrteFL+kTqgVwu7ReRPEWmajn7kOEqphcA7aHXdbmAX+p/fYXj/Aj1LL4VWMfwA/OZH008A3yhrauknrwMC/GX9gz+VjmtdicNzQEuN0mjht9bl9zXXKndwVFnGaAARKSoiY0Vkt4icBpYAJa2BPi3C0Kth99+cq2H+kOONUireeluMVFBKXbIEaEX0agL0xKW4W9Xi6O/4rMux+zlXQtCrzcxkItAqrUoWe9Crpclu5fHA40qpelZbI0UkU4VWejHCIGPsBXa6zWZDlFJtfNT91q1usFJqhHXuKh8/Al8DkXv5AbTAcVDZKksTpVS0UuohtIppFjDdn+v8aTqtCtaA6e6943h96feNlBqjlKqplCqDFgr50aoEgBuBidaM+QLaeHyTZZj01a9KaNXKN/72werHIaXUM0qp8mij5eciUiM9bVhsAK5N7VZux8fQevF6Lr+vEkobwX1d8yp6dXiz0obbZla5+Kjvfj/HKshBZfTqKzPID1S33m9Cf4e6cyLB1rlN1gTqoOt56/0ml/rl0YJrWyb1DQCl1BLghGuZiFS3vNnWishSEalt1d2ltGdTslsb25VS/1rvD6Bteq4CPNsxwiBj/AWcFpE3LH/zfCJynYg08VJ3EtBWRFpa9QpbbqMVlVIH0TPVz0UkVEQKiIjjH/MwUEpESqTRlynAANG+6WFoVUmanigiUlBEuolICaVUIlqNcsnPz58Wh9F2FJ8opeopF+8dt9dz/tzEepbXiaYyEAmMcllpRQOPi0gJESkA9AYOKKWOpdJsd7TR8j9/+uDSl04iUtE6jEMPqBl5nn+hZ+leXWDRz7aiiBQEUEolo1WUn4pIGasvFUSkZSr3CEELkJMichV6deV+D6/fn6X6mQ68JyIhlqvnK2TA+0lEyohIFxEpZv1vtAS6AousKj8C14lIB9F7LgYCG5RSW63z36B/+6HW4PsMetbu4C5gkTURyGoigReUUo2A19B2EL8QkZvQQitdv7nMxgiDDGD9Q7QF6qO9JY4BX6G9LNzr7kW7Pr6J9r7YC/Ql5dl3R8+0tqJnBy9Z121FD/Q7rOV/ebwzFG2D2ABsRBvg/PXx7w7sslQFz6HtG4Bzk9EdfrbjThTaFnFSRGZlsA1/KIxefp9FD6Ir0W6IDl5De8X8i372bYD2jpOiN3O96dbm42g9d3ppAqwWkbNoY+6LSqmd6W1EKXURPaA95qPKIvTs95CIOITaG0AssMr6LheQYhfyxki0IfkY2vnA3X12FNBRROJEZLSX618AzqGdJpahv4PxqX8yryi0SmgfWoB+BLyklPoJwLKBdUDbNOKAm7HbQt5BD6C70fadD5VSrp+lG9qzKksRkWLArcAMEVkHjEWrgf25thzaw6uHJdhzDEmfWtRgMGQ1IlIaWAo0sJwEDOlERK4HIpVSWWIHE5GqwC9KqetEpDjaZdmnABCRiVb9mS5lxdGeW8OVUpm6iz0jmJWBwRBgKKWOKqVqG0GQcZRSG7NKEHi512lgp4h0Au3hJSI3pnaNpeb7Ee2okOOCAIwwMBgMhnQhIlPQKslaIrJPRHqiVVI9RWQ9Wo33kFW3ieiwMp2AsSLiMHB3RhvunxSRddarvp/3T9W11RJGo0WHadkgIg39ateoiQwGg+HKwXIyOYteVVzn5XwbtF2nDdrOMkopdXNa7ZqVgcFgMFxBeHNtdeMhrH0ySqlVaO+0NA3agRa0KtsICwtTVapUzelueOVo/FH2xu2HIB+eiRcL0bCKx4TA4AdH44+y9/hBgguHUau0Lwctg8FOTMzaY0qpDO8DyFe8ilJJ/pmA1Pmjm9BecA4ilVKR6bhdBeybU/dZZQdTuyjPCoMqVaqyfPWanO6GB1ExkYTPsQItio9K6gIb1oVwZuYf2davK5HQJuEAPPduOMPb1NbP9jf9bM9xkKdaD6Jnw1452UXDFUKRArI77Vq+UUnnKVSrs191E9aNSVBKNb6M23kbOdK0Bxg1UYARET1Kv/ElCCySqq/P+s5cwUTFRHKx6WySqjg3pDJr6/e2Ou7HBkPWISBB/r0un33oUDcOKuJHVAIjDAKIfnM/Zuuxzbay2mF16VKvG2WLlk0pFKB4HFEx6Vk55h0cK4DkMntJqr8YguYA0K62PU+N+7HBkGUIEJTPv9flMxu9815E5BbglBXtIFXyrJooEPl6o7WD3VoV1C5Vh7+fTZnZNhhbL0VYKOjz7Qhee3k3cX++l809DWycM37rOf5zYh7wilMlNGvr97Sr3cGoiAzZi6Sx3Pe7GZmCDrURZrmtvoMOUY9S6kt0NN826F3p8UAPf9oNGGEgOkPRKHQM9K+sQG6u55uht9HfAHRx28l3CR2KAWCPUurB7Ol15hEVE8nJi1ZWQQUIhN/0kq1OeJMXnTpvAC4UxeBJu9odWLDzd9uxg54NexkhYMgBJLNUQCiluqZxXqHzYqSLgBAGokPnjkEnftkHRIvIbKWUq87EEQr2NS9NnFdK+bVhI1D5YNnHTiGA6FXBS58vIrzMOxB0GgBJLAQXy0DYERBIrrCJFnek+rvIk5gVgCEgyaSVQVYREMIAuAmd6m8HgIhMRfvKOoWBlUQDEcnRYE5ZQVRMJHvObNcHlkDYum83VN1iq6cKx9vqoOCXlWNpfugOFr7cDEMKZgVgCCiETFsZZBWB0jtffrH+UlhE1ojIKhFp56uSiPSy6q05euxoRvua6bjruAFwDPzi9nJDFTnLocTZWdtBg8FwmYheGfjzyiECRRhkyC/WhcqWX+6j6IxB1b1VUkpFKqUaK6Ualw7L0TwSNkIKlkr5tNaM39fg7yxLCgIBVTyOHYkfG88iLxyIO8+BuPMkJKZs3ouKiST4tVoMXeQtMrPBkIVknzdRxrqXY3e2kyG/WAdWpiAsNdNioEFmdi4riYqJ5MdtU3yeLxtclrLBZQkp6JIJUYD8LtoyBQMXvZ91nbwCiYqJpOY7taj1TBs6j492loX/9izJJbfz3soXbQJ097F4EpOSSUzKdVpIQ0CQrfsMMkSgCINooKaIVLNCu3ZB+8qmiZXlqJD1Pgy4DRdbQ6DjVUXk4lq686WD7HzpIEf6nqZ2WF2f7Zy4sMOsDizc9xnsO6/z67g/a8dxVEwkPX99kAnrxuVEdw15AcGoifzBStgeDswDtgDTlVKbRGSwiDwIqYaCrQOssULH/gGMcPNCCmi8bnyyVEbeXEttdRwvt8Etr2Mb9AUqlPkb8L7pzCE4lu9dyIvznuP5n80Ky5BFBPjKIFC8iVBKzUFvlnAtG+jyPhqtPnK/bgVwfZZ3MCs5HUq+Eme5lJxocy1194ZxHA/8oz8nEjyDFrap0Y5zCUkEFw6YrzVH8LXPwJvLadvJVqpgS6AePL8Y6J+NvTXkDTJvn0FWkbdHjRzGGTgtBC45DMg+Npw5cAxorpvPgvOHULJwWa/18yKp7TNwdzlNbYOawZBpCJAv54zD/mCEQQ7iYS+wPIm8rQpc6dmwF8v2LGHqP98BcC7xDOcSz/DK/N5sPnyGz9q+nrUdvwLwd5+B2aBmyDbMpjODLxYvCoWqeLiT+loVuHIs/miKEHGxG+w6sxAwwiA9mA1qhqwn8NVEgd27XExUTCTJRVfA8TK28i71unkMTFv2n2b8X7s4ciqBI6d0zgtf6oy8quYIbRLOzPX7mLl+X053xWDwjvEmMrjj6vpIqSO60PoNHIs/6lG3w483MWTFfUz+J8pZ3rNhL7rU62ar602Q5AUcuQsW7f4up7tiMPgmwL2JjDDIAdxdH133Wjtm9tsOnCG4Vy3C5zzLzpPbOHQ2lv5/hFNlUBWC+1Tm46VjUgSHJUimxswkpOPdth23uR1XwTphYz/+PjQjp7tkMHji76rArAzyFu1qd/AabMMxsz8Qd56GgxqTXNkKXucamyjsCMll9jLgz3DCirqE1FBAwQsk1V/MhL/zzuYpdyP8huNzM9ROaJNwth04w7YDZzKpZwaDGyYchcEr8WUolM/KR+CiIoqKiaTl5IZ2QeCOVbbuUIxdVWSV//zvD1nS5UAkM7KXOdRM32+bkFndMhjcCPxwFMabKJtx7i0oChfctDlhRUvbk9eksWLcenwLFx0bFFzcUzvU6Zhp/Q10Ltc11Pl9lIEhK16kWOH81CrfOyu6asjrBLhrqVkZZDM2tYYCzhflurBmRLQey5+7VqdUdPnddKnXjYjWY7m3WgvKBpe1Xb/j4B5b+3nRiNyzYS8unXyHVlW7s//E+XRd665mmr/zp0zuncEAznwGAbwyMMIgm/FQYxSOp3HZ1gAcPBery6zJfu2wukS0HsuEdpPo2bAXPz86jwHN3vW4vku9btxbrYWzbl4jKiaSdWdeZuqm8em+NjPUTAZD2hg1kcEL+aQwl1SCcza65+wiVqze55H28u9nN3lc27NhLyKiR7H12OYUL6KVc4h4ZATh0/rxwrR+5PvvRs7M/CPbPk9O4lTzKBiw5C82HT3N+Id1bKH1u08CUKtcCIULejfMmR3IhmwjB43D/mBWBtmIY+C6lJxg8yYqE1yG7SesFJc+Ipa6YoteChASZ8U4ikOFxJFUf3GeCWftruY5mrAY0M/61o9v4PZX2zNtw17bNaFNwm3qJMeqa+2OpvSeuZFLyfpLuJSsuJSs2HHkXJZ/DkMewLiWGhy4D1xF8gcz7K4Ij/0C/sQm8prbwCU7Wl4JZ51aWGpHPoOle1OSBzk8h9xVSlExkczb+yzbTs50lo3/exwPTW3FjC3pVz8ZDDbEqIkMLrhHyDyfdI5ftx6hUqnS6Y5NFN7kxRTPI9fYRtZxXtF9+xOW+rAVltrVc2jAknBKBhegZ8NeNlXTgXMr+TK6LIUL5KPPXP18F+74nbCQQkaFZLg8jDeRwYFtRm/9Lo4nzmDqpu+cx53r+ucN5LE6ECicryjXlKjN6FZf0rb645nc+8DFoeZxPDdfRmFfmc4iokfayr9a95l9ZSV5Z6VlyDpExK9XTmGEQTYSFRMJym3rsduX7x6bKDXcbQfli1WmTqkbGBM9inu/a5Bn7Abu9GzYy+mKG9F6bJpCwnNDhxgvI0OmorNeBrYwMGqibCIqJpLwOSkbysKKXM2guwezbM8Sth5N8Qx6uI7/g45jkIv4ayRbj21hx8mt7Di51XneoUbKi+oNb2GpfXkOuavcPAz0XkKHGAzpQgQJMmoiA5aawcXAeyzhsE5Q46IiysiGsZ4Ne1GxeCV7/KI8aEj2F3eVkqPs4Vpd4UIhgnZfS8+GvYyayJDpBPrKwAiDbMKmZnCJMuo663RXEe06eo5dR88R+sCnhDYJt72W/ptSNzUVhlFvpE1UTCQ/bJsCBS+QXHk7UTGRKcEEre/HPEfD5WKEgZ+ISCsR2SYisSLSz8v5ZiISIyJJItLR7dwTIvKv9Xoi+3rtP97yD5Bs34TiPuBM2zKe+6c15sIN73OxwXwS7plMQssJXLhnMr/+942t7YjWY7mmRG3CipQlrEhZqpesbdOXG3zjy7DMmVDkTCijW31pnqPhsjHCwA9EJB8wBmgN1AW6ioi7I/0e4Elgstu1VwHvADcDNwHviEhoVvc5vYxY+C8JJ1+ifon+1AytrQsLxwNQrXgtj4H7/m86MmhJH3ac3IoqelhHMQ2Jg8LxqJA4Rq15jbvGt2dyzG7nNTtObuVY/CGOxR/iv4N7eGFaP0I63p2tn/NKxH3V5gwYaG3ik7QiBhoMaeFNjevrlUMEhDBAD+KxSqkdSqmLwFTgIdcKSqldSqkNQLLbtS2B+UqpE0qpOGA+0Co7Ou0vUTGRDP+zE7NXdGPD9knE7nbJbiZQvVQVmyDoNKULi/a4JcDx8oNZfWAWzw57kr92nLDbJAQoEo8qHkdSg7yxG7nF6GWcPHeRk+cupvvang17kX93N+6p1oLRrb60bwIUeHOuPT/EyXMX+Wnj/kzotSGvIPi3KsjzKwOgAuAaM2CfVZap14pILxFZIyJrjh7z34XzcnBsaLpYcD3JlbeTXGYvKuSErY7rzDQqJpJfdkyzOoxvTxbrN5NUfb1HG+7kduNnVEwkG+NfYdKGrzJ8fXLo37Sr9TA96j/j8SzzUcJWt8sP97Ngl0mxaUgfQUFBfr1yrH85dmc73sShvw59fl+rlIpUSjVWSjUuHVbaW5VMxyPFpVuqyzL5WzhXBePWRjLwj/4eu4nLBpelS71u1C5Vh5CCIfYbhMRx19gaHD6dQETrsdQuVcejD7nZ+OkQtieToum76Hk+XT7Gr2uC+1Rm3NqxjFs7VoeuCNlMn7nPMW7tWA/7zkm1kKiYSOe9/tyzgK/Wv5EnVlyGzMOsDPxjH1DJ5bgicCAbrs1yfA7E1nd+g9XzqJhI+vz2LCfO21cNXep1Y+dLB5nQbhJ/P7eZI31P23cxC6iQOIYse5GLSZfo1fAFOB0KFwtAYn6nq2Ruxd34G3Ms9bSXrnGL+sx9jk9Xfmq7/ud/fwTcPLss11LjbmrIMMZm4DfRQE0RqSYiBYEuwGw/r50HtBCRUMtw3MIqCwhcd8M6ZveuOIRFRPQoXWD9GK4qfJXP/AQem6Ksa0YsH8wr83trQ3OBRMif5HSVzK2kd6ewe+iJ0xdO2c6HFSnts12zK9lwOQT6yiAgdiArpZJEJBw9iOcDxiulNonIYGCNUmq2iDQBfgRCgbYi8q5Sqp5S6oSIDEELFIDBSqkTXm+UA0TFRPLqb8O4ePo0+fbdClwDFQ9RpEQJPmzV3xkobeuxzfoCS0U0+O7hPmf0tp3Hx7c4y4/EH9Jv3H5PUzZOz7Wrg/TnI7A/nBKFSnJf9eZ685+CGZsnc2fVO3UY69OhCPDZIyOc7S7bs4Rftv9KfGyZXPtMDZmPw4Ccae2JtAJGocfLr5RSI9zOVwa+Bkpadfoppeak1mZACAMAq6Nz3MoGuryPRquAvF07Hgi4OMPOaJgAIZBU91fnufMqzvk+InqUzU6QVghrSAm30GBsvZRENw5LiZvheeXyvRCQuy8yB2+hJ3xR/+oG+nlZz7tu6Rs9QohHROvwHoTYjU9RMZFaaABUPklUTKQRCAa/yaxwFC6u+Peh1eTRIjJbKbXZpdoAYLpS6gvLTX8OUDW1dgNFTZQrcdcxeztvWxVY+BPC2lnXXWXkhdykKoqKiaTt5JYZ/jzrDsXoN9b3sfnoei/qHrH9cXyP7jYCYzMw+I1kqpooTVd89DymuPW+BH7YUY0wyELS0im3q93Bw1bgz6rAFW9hsZ3vXV65YeByrLQW7Pid8N+ezZhAcPtnK1ggyCPKqU3AuuSGcN+cZmwGhvSQDmEQ5nCBt17uA4I/7vSDgMdEZB96VfBCWv0LGDVRbsQxqI9Y9jGJl5I5uiWI5NCjTj00YFNZQPpWBQ58Jrpx0XHkhoHLW9iI9KppbM+KlJWVN1WTux3C5Es2XA7psBkcU0o1Tq0pL2Xu7vRdgYlKqY9FpCnwrYhcp5Ry37TrxAiDbCCsSHnySQkOV/4JSPnW3Ae39K4KHDiuGblKu0nu2nUVNa6JY+vBWBBF0IFrcsXA5Z4pLiMCzt8B3ZcdIj32CYPBQSYbkP1xp++JFYlBKbVSRAoDYcARX40aYZCFlH/vPuJYYDfsWsza+j2LVhyGslzWqsCV2Dgrl0Fx2HocKKAPHTaDK30QS8/MPComkj4ThxJ0oDp7v55HyeCCtnb8eRbvLhjJH3tms3ZZac6Mn3b5H8CQt8k8ZyKnKz6wH+2K/6hbnT1Ac2CiiNQBCgOphl0wNoMsIiomUgsC8LqZJKxoaZLLrnceZySXgSsexmqXnMq5yWYwa+v3LP7hIg/W8O0e5bqxLKn+Yqr1e852PrRJuF/3GrH6ZVYf/IOka6Y77RNRMZFU+7ipCQBoSB+SeeEolFJJgMMVfwvaa2iTiAwWkQetaq8Cz4jIemAK8KRS7mkW7ZiVQRbhMfgqIKEokliIzx4ZQZ8pn2oPYIu00l0eiDvPC99vBOBM/EU+63gjtcqnhKZwV6G4c6XbDGxuuvXh+20TeK7Jc17ruqvfEorOAsY7hUlSlYv0n7OV4W1q+7yfr93Gzj40IFestgzZR2buM/DDFX8zcFt62jQrgyzC6+BrhZ9etmcJyQVOpl3fhSmbxvPnsUdYcKQNa8525/ttE2znHR4xVxW+ShdYv7vgAsG5Iq+Bu3Cdvf0Hn3U9nmVIHD1mPaY9kXb+TlL9xXy9+f5UvZG87TY2rqWGy8KEo8ib9GzYi9L5W5Cf4nC+qO3LnrrpOyiqdwtfXbSG18E6IfES9T7sS7nhN1Hk5asZsDicc0m7uJh8nPPJuxiy/EWCw+sT2mIYCRcvOe85+O7hugErS9e5g8H0mTj0ildruLt1dqjT0Wddm7utxdzY32zXxyXsSNU91d3dtGfDXiYcheGyMOEo8ig1P27N0URLbVPESwXrO7/+ak9PnwuJlyj1fF2d0AagFF5nDMll13MheA+lH53P/Q98yNQnG9OzYa+U3MoAYUdIVpBcZu8VrdZIr1unc6exRfXQ6qw95BKlxM09tcnoN9kcO4mgA9U5M/MP5z3dcyX76sPuY/Es3a1VfY81qpLxD2rIleT0QO8PZmWQBUTFRLIvwYqeaX3/ZYuW5d5qLWhc7iZbXW+zy14/P54iCNL4/aiQOJLqL2bN8bedZR72B2eYhVF+f4ZAxFsye1+4P4MShUvqEN9uK4Z2tTsQFRPJP2eGOw3OqamPfPVh2ubxfBrdnSV7Jvu40pDXCfSVgREGWYC7ARMFh84dIqxoadYc/MvpaurNg6jHrMeYvnmy/XqX30ehfIVSDlx0jPvPz6XMu81p8PY83+qL1J0Jrmj+2nECpRQOh4mwovZ8FWWCdWC5v5/d5KH+cc85MWvr94xe+TnBfesQ8nSXNO8dFRPJO0teYPOxpXy76c1cE/rDkLlIkPj1yimMMMgCPAZja5CZ8++clGM8Z68hHe9m6j/f2eoANC53k3PwOtnPSxIbq/0z+RYRu2UEFQq3tSVncbiZ1i/bMDM+XsARFRPJ3SMvxu7tAAAgAElEQVTr82X0l8Rf0PYT93wErsfus3v37yusaGneWPQ8ySW2klR1WpqDu3vKUWNYNnjDrAzyII5MWUXzF7WVVyx2je3YPd1lUt2V+sDl99ClXjeWPrXaNnj1bNiLv5/bbB/wLRxpMN0HQ4+yXILrnoJX5vfmmw06X3F6jL3uxmL3KKZpDe7GsGxIk8wNVJclGGGQBUTFRDL1n++IT4wHBbXD6tKlXjc2H1/r9PJxVRH1mPUY4XOehYIXbO10qdfNa3IbBxPaTfIUCCFxRK2L8jog3Vz2frbsP33Zny+QcFfJzYmdBaQM8LXD6iCnQjl+9qLPNj5aGkGfiUOdRmFfAele/OUDaoy6lqJvXEXTiDftjSiXl8HghqBjJPrzyimMMMhkomIi6Tv/DX1gfbFbdxzUs00XVYJj9mmLkW+dSy3LmTsT2k3ySIP5y9ahTPxrj1OdVDa4LHI6lPc//5Fb272ZanuBTFRMJA9Mbmlzk01rVr712BZU8TjeWfqCV3VPVEwkby95geQye52upg5Bcmfle3n/njHUD+1EVEwkkevfYP/Zf1Ehcaw7OdzZnlETGdLGv1WBWRnkEhwqi/NJ1oYyxywxJM7DoOkr3SWknuXMGx45DQpeYM3x91i2ZwnhN73EoXOHnF5HFxvMT89HChgcz3ahtWnMMRB72w/gwFuUU3d81enZsBdtarRnTuyPzP53otfcFI4yoyYy+ENQkPj1yrH+5didcyEeA4brRrPV83QaxdOhzkHLmdjGRbWQkRhFXncfK7257bXfX7OFyL5SE92klozeYRB+4sanSbqUEqHXn0HaV52omEjeWPg8f+5ewAd/veIhzF3VR6kJJIMBsGwGga0mMpvOMpFU4wMVOwakjPtRMZGEz+oDBbGFsPZHNeQNxwDkntcgIemM3UVVwfAlX19xA1Za4atvHtuODfvnEnSoCucitwH+bVTzVcep+rE4Fn+U4XdFMH59BAdOX+D9Fv1s7d1Rriv5LrWAS5nzeQ25C4EcnfX7gxEGmYhj9++PW34hcefVBJ0oT3L5/yhbvTAHzv7rrOdMZF/Qfv3lhrD22H3s/tuzJNHBzccu6z45QWoDe49Zj7Hh2E9QCJKrbKfHrMeY0G4STSPe5EDCIk6sKsLzg9sCWgi/Ne8rzq0N9rnTGLwLn7/3xVE4fxkurAmiZz97/Ts+eZ2zF34l6EB1nrTaNRhcCfANyEYYZCb2hOmnUKFHkbjSuLuYnEyI02+smXrxgqEMaz4iU2brE9pNYt3hvz3yKrtypeY38JWH4Pf/fvM4joqJZN0pK05Tffg0+gX2J7SwRT5N7Rm4Cx+AqI39vF4bFRPJ6RJfAld+2A9D1mHCUfiJiLQSkW0iEisi/bycLyQi06zzq0WkqlVeVUTOi8g66/VldvfdwQfLPk45EFDF40iusl2vClxcTA+dO2RLeJNZgsCBh0E5Wez5DYCI6JGZdr+cpkX11h7H7sbiJfu+t39mP7x+XDenpWazMN5EhjQxNgP/EJF8wBjgPnRKt2gRmW3F5HbQE4hTStUQkS7A+8Aj1rn/lFL1s7XTbkTFRLLnjBVPyMVg60SgYkhF7VLqcj61VJdnzicC8OR3f7No7Dc+7z3yi9d4onFV57GjPac6SpRzFZLSr8CepaSHCe0moZReEdxdtSUT2k0iKiYyRc3j4zO72h1KhPcgKWihLVCde11fNovMSMdpyN0I4lfimpwkIIQBcBMQq5TaASAiU4GHAFdh8BAwyHo/E4iQAFp3+TMbdAwSC3akDByXayfwhWM2q4WBVegQCHhZPVzhfPXgN5w6n+Q89rCfkPKZ3e0OUTGRXCw7EfCt5knNZpHeiKqGvEngjFbekTQyoWVPJ0Q6Aq2UUk9bx92Bm5VS4S51/rHq7LOO/wNuBooBm4DtwGlggFJqqY/79AJ6AVSqXLnR9v92Z9pnsGXiUlDi0j0kcpJ8qiTnTvzL6CcHOAeJkEdaUOG2ePre/rjXgSPpUjK9Z25kxkfjbOWF6t4CQPsHbuCHn9dzcctq2/nQm+8BYEfEw559svoFELTnWqfHTW6h68Q1zB0zEYA9Sz6lQP4gRi7ZwdrD00hgaaqDdNvJLW0z+3urteDnR+f5vNe/h86y7lAcnepX8lnHkLsoUkDWKqUaZ/T6ouVrqVrPfuFX3XWDml/WvTJKoKwMvMlMdynlq85BoLJS6riINAJmiUg9pZRH3AWlVCQQCdCoUeNMlYI9G/Zi7b44og/NYevvQVzYXYfon0cAsDPuHPfVudqZe/eOHoOY0/tWjzYuJmkf+aub9gGg8WM6Yub8F2/3qPtFpxuA7gAkJysejFzF8ig9Cw5tuY24ef1tM9ZFi3fRrFkV2l7bniWbm/DJn7G8cmeNTHwCOcuUJxsTagmD/PmC2HMsnvf76Q19cdG+B3ZIv5rnjn6zuLBpFZ2iI5xly2OP8eMWvav8o7Y6iKBrruU4l7qGPEgO2wP8IVCEwT7AdZpVETjgo84+EckPlABOWEmeLwAopdZaK4ZrgTVZ3ms37qnSjXuqdOOZcSOy+9Y+cXjghH4azozR2oC6ZPO6HO5VYGHUPIasRscmCmxpEChqovxoNU9zYD8QDTyqlNrkUud54Hql1HOWAflhpVRnESmNFgqXROQaYKlV74TnnVJo1KixWr468+TFrqPnaD96GQB/D2nJ3uPx7Dx+DoBm1+rdqy/+qD9Ou7qlubtWGY82LncmOWKh3svgmBEvmjEUgAZVS5KYlEwZa8VxOffISZKT9W91yb/HeOyjhewbl3auAVeWbNcz94e6vZvmZ3/9ly2Me3cMkPKcjp3RgQRnbznIUzdVtdWv+r+ZnFqz2Fa/0/hoABZEfkfcqtzjvZUXuVw1UXCFWqrO//xzdFz79j15V02klEoSkXBgHpAPGK+U2iQig4E1SqnZQBTwrYjEAicAx0jQDBgsIkno/Z/PpSUIsoL9p86za+7PABx57U66T4hm/bQZgB4cQpuEk6+m/n5HTX7S4/rQJuEUqK2zoB36unuG+tCveU0A6n/9Fl2feI97Og0AoOsbz/LZw9dlqM1AIvbwWQDaP/auVZI+YdCoSigAI0a/mmbd4W1qM866TWiTcOKiIxi6MBaAr9/7gqfchMmuLzoC9rzMFxKt7ciXkjAYzA5kP1FKzQHmuJUNdHmfAHTyct33gHHsNhgMgYsYNVHAktlqon/2nuKOh99yHrurITbuOUVIES17q5YOtp0LbRJOp9ee4fOO1wPaAJoZhLbX3gvX3VKHX164jYL5dbuVe0xi8oBW3Ffn6ky5T3bTZeIa5o2Z6HzGm/ad5vb2b3o88183HQSgz9hV/De6fbrvk2gZ9C9eSia4UMDMmww5wOWqiYpVrKWuC/cvQOTq/nflXTVRbsDhCQQQOe4Nwh6dyDFLHeSwBbgPVo7yngOfZ0SbWpkmBBzE/fg/532qrtxE3KznAYgZ3YkbWr1+xdkMHDxwfWlc/YNqli3GoE9eZv1uHTr8xiolAZix7hAAJ1YuBFKEwT2fLOHvKdOdn//E2YvM2LifZ5tWs92ngCU8HX9TQynlMfMLvUur6Th38op91obMImdzFfiDEQYGg8GQDQS4LDDCIDM4l5DEqYuJztnfjHV7bbOAXX9+Sn4341Fok3DufEYbioe2vDbTVwWuOAzYA+fqjWZdry+XZffKDh5rVIXHXGbaBfMH8cVPWxj051wgZQU2sVsDXaGbfVber/W1jKCz8zgqeg/DXh/Jkyu0F1ahAvnS1Z9ar/7MkSXzWPL9ewBcX7kEAEu/7QtA7Mmz6WrPkAuRwDcgG5tBJjB380G6PvGe89gxGPlyFQ1tEk7xRncS89FDAJQq5hbL2uL8Re2NMmXdXl59/qNU+1D4uqbMGqADtt1c/SqP86Eth8OJ/fbCgkV035Z/mGrbVwqO571i1jDqVCieoWshbZfbGi/O4viKBR7fqb/XG648LtdmEFKptqr/0ld+1V322h3GZnClUr5YUduxwxXx+OrPbOWtIpY73y8Y1NqnEDh8KoHa977m+4ZhlfXfY3ucRQn/rKRVl5XO4x8mDbTtZYib15/Pl+8A4K2XPgFg2ldpu1gGIveOXMra76Z5DLr1OuidwxWuKpLuNtMzgL/dvT4/1C3rPK76v5le22j+6RIAYuYuJ25ef2f5H9uOsP3EOQ8bhSF3Y2wGBoPBYDA2g7xA0YL54JoGbPziUQCW7DrioTZIupTM6q+nADBp4lvULFvM1sap+ESq3vmyreyJt7Q30Mh29fzqx8z1+wB45ukRPPzYYGd5mWYt2fZxW3rfdg0AvaMjaD9uNY88PtTZv0Djwz9iGfa63rXr3r/32taj1Xee1yzrd3em9sHhmrowNo5PHqprW1m59ik24mEuJLbzuD6spF6hFC5f2Vbu+G6eDcDnbsg6zMogDxBcOD+Nb61FcCFteHy0YRU6rxptq1P6lj50fUNHEL2/njbgXrLCK7z121bGDhrjrLtw+hAaVgtNdz863lhR/42OYP+J8zR+9QcAjiyZR+idq4j7M8WusTjy23S3n530bFKZYdZ7h9rNQY0ywd4vykQSEi/xWG/rnvGn+OShCEoWSTEsb9hzigU7dXiLV+6sQf58QR4TgGk9mugDx1+LQnVv4cLmVVn7AQyBhQlUZzAYDAad3CawpYERBpfBvM16U1OXJ7S65ZpJU23nXb2KRn/Rl+6NqzjPJV1KpvQtKYHjeg583hn6ODOocFURDk7oBsCA3xoxZmCEc+Zap/3Dtrq+NsXlJJGrPXNNTIzeBcDLvT/y6Gu7yNX8OU6vdtLy5pq1cT9zNh8j8pEbfd7/5kHzIf4UAPW7dLKtTh6NjrC1veK5x1n4pWcmutX/6RBZr83cQPP65RjUshaAWRXkUYICfGlghMFlULJQijeQ62BzKj4RpZQzSmlw/du5qbzd3dNVEPg7CDvUSsfPXuTIqQRKBuv7lyleyBlqwhtDW9emaeW3eOxJrSba8uMPXuslXdK7qLNyz4O/PNW4Eu+7lT3WUOveP7nvAQ/V0U3VQ/nTeh976Cyfr07xtHJ4dZ1N0AHjejw1HIDIR1Kuj9kZR/PObzuP46Ij4L1WgF2oADR653fb8dNNK7HQS0DKVl2cobX4ZyYMaqnv9/23A9l/9rzXz23IvWSmLBCRVsAodGDPr5RSHnHzRaQzOjukAtYrpR5NrU0jDAwGgyGLkUwMVOdPzngRqQn0B25TSsWJiGfMfDeMMLgMKln+7FK9Ic9O38B0R5pKpYiLjuCbYTpQXL/3X6RW+RAWbj0MQMfuQ6h03wNsGNbKa7unzycyeEEsUYPHeD3vL7XbaXXQl4815P565XxuknLQaKCe8a5/z3u/spMyJQpzfScdEnrjDO3H71ixPNq8Op/svclZ9/CpBI6cSXQei8A799WkbW09M3foah+ZEO2sE3zj7Tb1WPOu7+IvdaqXYofLcau6+tmW66FdnBL+Wcm7v28jqEYjAJJj19qu79BdexN1DyC1nCHryUSTgT85458Bxiil4gCUUkfSatQIg8tg3QEdGE39F8P0D2NY99sHgFa3hDYJp/0rTwPwxj01nRulAFb9NJxa5UOc7Zw5n8j/Zmzg188meL9RybJ0792O8Fu0zeHaciG200op4s4lOvXsjuQ2W2dpddBd1t+X3nsBgP/dXIX504Zw3yNv29rZ8/sv+k0ACAOAQwc9MpcCOm+DI3cDwDcx+/j6vS881G2OTXceNpH/NbUJw1kb90PpqnAo1nZ9ledmpBwUKkr8Ba1mGtn+On6dXh0O/wfAgbjzzN5ykIR/Ujb9jXzLvuHQlSXfv0ezDm/Z+mV2MOd+0mFADhMR1/AIkVbKXgcVgL0ux/vQ+eBduRZARJajVUmDlFJzU7upEQYGg8GQxQjao8hPjqURjsKfnPH5gZrAXeg0wktF5Dql1ElfjRphkEE27DlFN8sgu/63D6gfPpX6rV8HoHKLB+jctxfD2tQGILTNR3B0F7v+/BSAEkULcPBkAnXv8x5yYsL4/rS7voLffRERripW0Dlb7uc2s/xp436efGq4c7aaVgLGmev3OfcsZBehLYZBnE57HRcdwUuzNnF0mVZbde5rz0k8btVOft1whFm99GSo7901+LJpc4/ZdWhb75908bajtuPovWfgUCw3P9EVwLk5sH2rugB8vfZPuBBPhQcsG93JQ9Tv0olChbSqql63MXB0l7O9Jt27EBpSiN8//9rr/Zt1eMtruSF3k4lqIn9zxq9SSiUCO0VkG1o4ROMDIwwyyH8nzzjf39j6dRbNGMrZxLYAPPjou7zc7jVq3P2Ks87OxZ9wzlIzuO807tb/OSJc0lImJyv2HItnqJXTeMYPa2DH3+nvZHntynhHmyas+WUE1a/Wu56Pn71o65s7z3/8Bx2/yVjqzQwTZ/8tv3FXdb629shNHzONsZ1vcJ4bMiGaMzFLCHVxJf3fw9fz3sqFtjai3tM2h549R0C+lJ96StpMzXttahM17RanEADYcyyeB2vr3NV/tmrLrrk/Ezdf5ycIbRLOuqkpKiR3V9bob+0uxu68OPQFRg3wrUZyeEot+/cYABcuXaJ57SszEZHBQjI1n0E0UFNEqqFzxncB3D2FZgFdgYkiEoZWG+0gFXLeh9BgMBjyACL+vdJCKZUEOHLGbwGmO3LGi8iDVrV5wHER2Qz8AfRVSh1PrV2zMsgg5YPtkUrveXkK7NP7Cho+2pmXe6eEnF49ezjV7rLPxP+YMdS5N6DVkLl8N9yLo/rlckDnL1j61TYa+xc9F4CLW1YD3flosTao3lyhBHfULJ35/UuFciULpxzEnyK0SThvfvASAGdilnjUP3neM+n8jhMJKQcuSekPLh9FuTbD4NRhZ9kj7RrwjbUZrEyzljR+eSaJW//y2rediz+h2hMTIUiHp5i+bi/PPmPfFTFi9Kv06/OxrcybB1dqtH10kPP97MnvZPt3YMg8hMzddOZHzngFvGK9/MIIgwxSvmRhKFsDgAnDOtHjqeEMGamf+9tWiGgHNz9ohS8uqpOeEH+KuzsNyLa+ZgT3gWvfspHOPMDxF5K4lKwIKVIg1TYmrdXeTSNmbOarZ27iluqlvLbtLR3ozsX2ZwjwYC2tKhnmcQbGDLS3MXblTt7ra7cZxOyMA7BtLnPgcAMGHcspLjqCGi/qnAjHVywA4I73FwPwz8yZtmv7fumZO6Hfa5976aV3ziV4CjJ3Hnz0XQ911ITx+neVHvuSIecI9HAUAZPcJq0ddSJSCPgGaAQcBx5RSu2yzvUHegKXgD5KKdcUuV4JKlpGFarVOa1qBoMhjxMXHXHZyW2uqlZXNX9nkl91Z/ZolCPJbQLCZuCyo641UBfoKiJ13ar1BOKUUjWAT0FHK7DqdQHqAa2Az632DAaDIWAIEvHrlWP9y7E723HuqFNKXQQcO+pceQhw+OrNBJqLNs8/BExVSl1QSu0EYq32DAaDIWAQP185RaDYDPzZUeeso5RKEpFTQCmrfJXbtV6VqCLSC9BO6wWKeauSKVzVtDn/fPQgRQpeOQsUmx7/ar271lv0TwAKFYUL8VnWlxeGvMBnb6e4XsZFR/DDhn3aRdSFfxdpA23Ne1511gPoPXMjU94fa7ve/TNsW/gxtZrb0346rq/aeyanohfbr793iM3g7N7mVU2b89/o9kDK84qK6gfAwzdU9LrDOLUc2e5lJ89ddO4qCg32ni7VENiY5Db+4c+OOl91/LlWF+ot3ZGgbQbp6aDBYDBkFO1NlNO9SJ1AEQb+7qirBOwTkfxACeCEn9d6ULbi1cRdTo/d2L9sJEULBcrjvDzmjX6Clo8M5NBJ7ZpZofn9vNahToq77IV4ruvYkS+7NQTg9vZv6vIS1sYoawYd/bOeyTd7czbnN65wtl/x3vuZ9/pdPD1Fb6RbOWEyAH9+b4XYPn7K1h9fLpmOFQEA5a51vv3DCl/tOrOOi47gyOkLAJQsWoCC+YPoMaA3ACs2HmTVgObOurXrlmNL8p3s/rITgE536bYqAB2AEGDLwbNM7NYgpS+lq8LRXTx8Q8Z2cXuLTVTSrAaubMQkt/EXf3bUzQaeAFYCHYFFSiklIrOBySLyCVAeveXau4O4C2fOJ4Jb9sRr2uj9Gnc3rsSEyas8ok364uDyURS+glRC3nAfgOKiI5i+Tmvu9i/8lZcX/mo7/8/Mmdzu4mLpzT20SVutJpk9+R12nbqNPv/7EIB9C36l/PDWbLFyDDu4obJ2vW3+5ixbeY8BvZkw9HMI0/kM4n7TYT+OnNLC6nxiMlXCitJz6joADi3+zaM/m/adZu/pc4COMgrw6xIdaO7IknngIgzmht9mu/aRGyrwFilRYB2MeGNUykG3lPsVq1iJsy7hKXxhAtLlLYyayA8sG4BjR10+YLxjRx2wRik1G4gCvhWRWPSKoIt17SYRmY4O35oEPK+UupQjH8RgMBi8cCWoiQJmn0F206hRYzVr/nIABs7bxtQPIj3qBN94OwC33Vbda9Cxwyt10vvUsoxdqYQ2CadBV70PY9ErzbzWORWvcwis3RNHh+6DKXxdUwBe6n4T99cswx0PWwHZSlUibu4bjP9rFwCvPv8RJZrcxa7Pdeyg42cu0GPy3yz9KsUPe+/SkZw+r9svH1rErz7HHjoLwNCF/9rVNkDoLS85dyGnNSO/3DSg3q43IaqvbC53n0HYNfVU22Gpx6xyMLHrDTmyzyDPCoNS1eqq+JL32MqeHfQ8AINaXMvS2GN0fnxIysly18LB7c7DBdOH0KhaaLb0NbtxD69QpllLooe2okozHWDvh0kDnbkCwLdO3zHofbtmN+cuXuK5W68BoPmnS4iZPJ2w2+4D4Njy+bbrKjS/n39GtGb+Fq2n7/z4kHQNoJc7mP93+Cwn4xNt3296vIG6TlzDggWbODrpiQzd3xB4ZIYweNBPYTAhh4RBQKiJDAaDITcjAvkCXE/ktzAQkceBhUqp/W7lXZVSU3xcFrBUCi3CD/O0QbN8aBEuJF5i+vp9AJS7VXuJFKp3CwD9nmrKu69+ars+t64KAL0qKFONG+/Wk5PWDcs7VwUA36zdz8OPDXaq0aJ/HkGNsvZ9G6FtPiL0fitQ25GdgE7I6qBm23b8+5uOs7Vl/kecu5DkDLHtoGiBFKP8mfOJnE9MBqBM8UL6Hi7tu87MN877kOtb9uWPbTrTn2MVs9aKTVS7fAjBhfJT7w19/wOL5hAXHcHfu3Tej3s6DfBYVWyY+4FTLeYg9g8dP+n8RbuJam7UTEg4i/Z3MBg0ucmAPAE4KCKdlVIrXMrHAlecMMgnQlHLA6jN5yuc7o0AwfVvZ9+4Ls7Bwl0Q5Hadr7fP90Z0BKv/OwFAqy4D+WXKIB7oOgiAJm2XeVzTotOdzh//1CdfZc2OOO57XecAqN2gBivfuofQn7XXUB0ryc+LQ3VazlHj/oTdG5xteksLOWzhdqeQmTjeVcxARSs3dVKyVoGOW7WT119IiSDad0Qf3mx+LQO66BwS31YpCUBIYd//DpVKFaVSKXvZ5yt3ARD1wwZ2fdEx5UTCWZ/tGPIuAS4L0hWOIh4dH+hHEXnapTzAP6LBYDDkLIJ/cYlyMjaR3wZkETmtlCouIteis+gsBF5CB4/zjOEb4NSod6PaX/AO53HDRzuz8OUUrxmbUbRCHdi/xXmY21cGmcXFJK3WyR+U+oab6n1+5IRLlrIF04ew8kAc4bdd4/OaRVuP0OGNaQDE/fRCqv04EHeeei36UuaOlgBs+6St7Xxok3C+mfAmba8rr49vfRUSL9i+59d/2cK4iNn6fnPfAKDlZ9ob7a9vpngYkOd+8S1xq132IRiuaC7XgFymxnWq4wfT/ar7RYd6AW9AFgCl1HYRaQp8B8xPZxsBQ3DB/E71wkNu8eAdgmDK19o1susTemdsXhICp+ITnek5/f3cr/y0GYCnGlbgukoluLppHwCu69iRpW/c5awXes87fDyiB0/dVBWA/0a3575RpcmXTwuMRtVC07TJ3FO7TJpCwEH50CLc8uSjrJroUAW2Zf3uk9zVUeeU2LbgI0qFFHLW3zl/OGfccgwcO3MBju+1lX3WUafiXNnU/vuZ8mRjeDLb/5cNAU5ushn84XijlDolIm3ReUaqZXqvsoH8QeIUAkophi/6lw/76X0DDR/tzO8v3kHYzf4NNrmFlbE6K16bru+wb1lKYphFW4/Qoftgp1CIPXSWJm37+QxkN8H661OInDnO9qPnbUVrVmwjfwHr5+i2A3jdrpO8vzhWD7J+sO3AGRbuPEpvl5XFb8/fCs/f6jwu5mIfKFOisO36ksEFPcI/jO9an/Fd3ewig3XajFNrFvNEHpooGNKPoO2UgYzfNgOl1INux0op1V8pdUUKA4PBYMhOgsS/V06RHtfSwb7OuebevJK4kKhdAstarqT/WK6mFa4qku58tbmBW6pfBWidfcXbX3LO7Hcd1TF9wh6dCMDOqG7OOE4An37+GmWDC9GyTlkAfvrnAMH5PX9aoc0sr58iIYy4v46zvMHb82DH3xz1Mbt+ffY/RH871afqJbTtSFZ8+RR1KmjT1YMfLebI0nn0TmW2Xv3qYrR/RftBhDYJ58DyUamGHN9zLJ6/9mtvqo436gB0t9xcFYB5a3xeZjA4CfBtBulSE1VyOy4L3An8mHndyT6SkpVTCIBn6ICeA58n6ksr37TlwpjbaTjwdwB2rV7L6tnDneVVSwczf9oQ7ntE5w4OKfIka99tQZvPtYfxyPbXc225EGf9dtdXILRJuM8dxp379iLu3EWSLdfPW24oR2Li/fSath6AGRPmOo20AL/3uR363O7R38kxOscyh2LZcvy0UxhoA3Fbj/rutK6jfUV/BA6dTKBaGR258MM/Yhn2+kjbb+KBT5awd/4vAHS0yueNmfuqZdoAAB5WSURBVJjmPQwG0G6lucZmoJTq4V5m5S3umqk9MhgMhlxIbloZeON3YFpmdCS7yRckfP+11m7dU1vvUA1tNwaA4o3uJGrwGFv9vOBJtGvuz873BfIFsfTfowDcUbM0ja8J9XgGjo16X1bozScP2VNWt+j9BF0a6VDR9424n0ot3obzZwAY2/kGz7g+nW6g+7cxuuCcZ6aJvcfj2X5UX9+8ts6b8PuWE87zGckd0Km+Xux2sj6XY1PdsNdHetTdMKwVDGtlK9uxWO9APhCXkO57G/IeAb4wSJfNwN3puyg658BeL9UDHiFFCADcPuIP516Cn0Z24+d/b+STtz/XJy8leWkh9+GIOtquzfU07PYpnDwEwJpfRlC0UH5Kh6R42OTPF5SqgJzWo4ntOG5JitoptEk4S394zxnVNLRJOHHREXzbXSfLaXnyvLPMwS2v/0T8Bu3X7yh3Ria1cgnsPKJtGze9MtMjSNyS7Ud5qNu7ABxdNZr8+Tx9Jxpb7qzrf/uAG9vbTWQdo/5i4Zff2O7vSD9p0lAa0kKA/AEuDdKzMojFnmYyHvgbE4DFYDAY0iTAZUG6bAa5L2i/xeOTYtj0/fcssdIuNuvwVg73KGc4OKGb8/0XnW5wvk8rRLWDdpGrAZj6ZOM0M7/tP3OeA8v1Dt3ES8m2cw80KMuO/+6z14/qSlrmqS1HTwOQtC2aEQtv5YXbtddzcKH8zN52zFnvv8PnqFU+xON6R1TJZKU84gutWB6b6r0NhtSQHA414Q9X5O7hzOLRr3Vay98iJrD8x2H8vkPryKd9M4DKJYJp+pB2hSx3d5sc62NOMGPdXno98z7Nn3sc8Bz0V/13nDMXPVVnf477FoDDD19PlbCiPvMKuB+Xv60fXDzvLH/h9uq8cHt1v/sb2qw/f38/gDb1yjnbD20Szt1Ttarn5upX8VHbOnzU1n7fZ6Zq76WZH4+z9an5kN897jH6xWY88/QKj3KDwV8CXBbkbWFgMBgM2UVu9ya6YtmwJ47NETpwwppfRlD96mLc0fd7AJJj19rqbv4gb60Mnnt/AQArV+iE8fS8yXb+luql3C8BMu5x9eq7zxAXfxlG+vNnOHz6AlVL630CczYdBPSKIDUG3lcTgJlWdOvtB7W3kmvQPAcdb6zo3F9gMKQXIRclt8ltXDp3hv8WfATo2DShd/SjaVe9q/bHbx4n6q/dvPXSJznZxRzj+JQeQA8SrKQt7p49aRHaJJxrH2zv85rQJuH8MmUQt9UIA2DAvddeVn/d73Mi4aJ/152zJ6txbJzLC27Ehmwmh0NN+EOeFQYGg8GQnUiAp37JcWEgIlehN65VBXYBnZVSHruOROQJYIB1OFQp9bVVvhgoBzjCYLZQSh1J674N6lR2RquM2RnHoy914/elOwBsYSryIu3HreaW6lfx6p2WEbdgEa/1LlnhJBzRXR0z6ha9nyD89qrOetsOnKF8aGEqu6TOrF+xZBb0XPNYoyo85ja7/2vHCVo+MtDWz7IldNjqoBqNsqwvBgNoNZFZGaRNP3Ru5REi0s86fsO1giUw3gEao/c6rBWR2S5Co5tSKsPhwpp3fpsGXTvz46t3AdC7fAk2r9vFL0PSjm+TG1kc+S2rrmvKw3W1d87nES/Qf85WqpfSg2f7ujoJTI17XgWg7sMduKFGih3BfcPZLQ/1p+7DHXh20PMAjB00hj3H452xhHx5HaXG58t32NR4qV27ad9ppyBwcOhkgjPdplELGbIDIwzS5iHgLuv918Bi3IQB0BKYr5Q6ASAi84FWXGbuZccg1K3/c1QqWYh2H+mUDXP738uE68r6NJTmdhyDY8VnpgJwbt0yfaKYNsj2PXuCjq8+46y/vP/dfrXnoFGFN6h+dbGUgvK1CKtWOV19bHPt1Qyxdkx3frB+qnWrhhWl/StPM75rSr3gQvmgUNF03dNguBwCPVBdIGwku1opdRDA+lvGS50K2MNe7LPKHEwQkXUi8rak8sRFpJeIrBGRNUePHc2MvhsMBkOaiEC+IP9eOUW2rAxEZAE65LU7/m719TbAO5I3d1NK7ReREOB7oDvwjbdGlFKRQCRASKXaqkHXzgD0aVqFdYdPcnyFdqls0lb/fa9N3lYfOFcEeFeljOuSUnbvyKWs/W6as25ok3CeH6xXXkNb1/YITLfjyDkKF7B++Qe2cezANvQi0Tujlv7HoFc+dV5ftXSwbce0Kxv3nKJZh7ecfQ4unN+2KgAIKVKAuGUf+LyfwZDZZOYOZCti9CggH/CVUmqEj3odgRlAk7RU6dkiDJRS9/o6JyKHRaScUuqgiJQDvBl/95GiSgKoiFYnoZTab/09IyKTgZvwIQxcOXfqHM/cXRWA2dsO89vfB9j0u05uU+/ZybDz7zQ/V25n9Bd9AUhISk6jJsx6rin7O6cMuMt+HMY1Vn4A0Lu6wwqn5BludH+KJnD25HcoXrCAz7Y37DnlFATe+OTPWF647RoK5NfCpVCBQFjwGgwpZKYBWUTyAWOA+9BjY7RlQ93sVi8E6AOs9qfdQPivmU1KsLsngJ+81JkHtBCRUBEJBVoA80Qkv4iEAYhIAeAB4J9s6LPBYDCkC53gJu2XH9wExCqldiilLgJT8b6sHgJ8APgVYz0QDMgjgOki0hPYA3QCEJHGwHNKqaeVUidEZAgQbV0z2CoLRguFAujl0gJgnD83bVDzaro20EbLEQv/5eDBsxw9fQGAreO6cXWJnpn3Ca9Qujeu4nfdYoXz24K/1atY3Ha+RR27ltChSgJ48NF3iYuOcGZa2/nbbGcdgA8Wx9qO3Rny2kg6zf2ASqW0QfjaciHGQ8gQYAhB/u8zCBMRV5VOpKXiduDNhnqz7W4iDYBKSqlfROQ1f26a48JAKXUcaO6lfA3wtMvxeGC8W51zQIadxJ+dvgGATTuOc32d0tzVcYDznBlMPHEM3pt+/5Dyod73Hjj4csUO+r+oXT99PcudVnKYxEva/PPQ7Vr4/JjcljXvpkQtnfR4I3jc99dsvitDoCOkK1DdMaWU94TfKc25o5wnRYKAT4En/b4jASAMDAaDIdcjkD/zNhrsw56TviJwwOU4BLgOWGw5V5YFZovIg6kZkfO0MKh1tVYrJCcrxnW5ke75dQz+X0aPT+2yPE+9Fn3TnI3fXqmUM3OaL0q6ZQh7p0Ut29+0WLND7zm875G3zerAENCkc2WQFtFATRGpBuwHuqCzTgKg/t/enYdHVd97HH9/CassEjZBhYpIaxEVhIB15XF5VGrdrihUvVilXqupWje0vS7QS4tYK7b4aFFU2lpxay1FigvCVXoRibgUsEq0iEgqRiICViDke/84Z8IkmcxMksnMCfN5+czDnHN+58yP4zDf89vdNwM9qj87mKXh+kj0Joqitz+s4L2ZwTKKN192NL0u+i2v3HE2AKcMuiGXWYusknlB77Xhp9+UMu3gvntXd/18r2wLA3t3yvigm8KO9fdAEomaTHUtdfdKMysm6FhTADzk7qvMbDJQ4u5zG3PdvA0GIiLZlMlnIXefD8yvte/WetKOSueaeRsMBvTpwsxw7qGKr3aw8x+vceSZrwXbqnJIKDaFRMXyGaz8aDPlXwZTRY/6Rs86g8rijTzjZt5deBe9urQjk/Zql7dfX2lhjGj0408mb/81dWxbQJ9w1tL2rQv4zQMTmbdSU1TUp7ComPVLpgOws7KKY8/ZPXi8YvkMnvjtLezVpqA6bfx6Bc0VXPcJg8uyuT9v1PmNmSBPpFEssyOQm0PeBgMRkWwJRiArGETWOTOCBc5L5z3DKVdezKvL1gYHLjwid5mKsBHhoLANL82v8TS97P1N9C/syEG9g2qkBXMmM/RrddcriD2JP/DgTZx7+P4N+uzKXVX8O1x5rXOHoOG4VdhVL7ZC2d/XbQaoMS+RSFREOxTkeTBYflswZVLh6g957t5H9AOSRM17U3NN6FPH1lw0JtXaw53bNPxrd9YDy/jbrEcT5GW3b+4XBIV0q430/1uyKeIFg/wNBm+Ubqx+Un356Sls23lWjnPU8iRrNB522/N8ML/mtBJN+fGdd/m34PLk4xZah/P/xkoKItFhkV/PIG+DgYhItqg3UYQdNqAnN8+6GQjqmOnam4oX/jvFWRJv49JfAbBzVxWFRcV863vBIMj5VxzFpDGDuT/JE3rlrqrqBrVWWVgPcF35l/TroZXNJHfUgBxRBWbc+PAKAGzAEWyac0mOcxRt75Vt4eRJCwD48P4xANXrB7Rp3Ypzr/s+Pzqmf3X60wfvy6nhTKXlW7ZT2LFt9XzuZkbPI6+CLj0BqFh4W1p5aGxX0MpdVRx+2o11zotdr+xv99C+bUGDrinSIBb9ZS/zNhiIiGSLqoki7omrjwWgIAvVFC3Zc6v/xdjx/xO3ZwyFRcVMmX4tAFccfSAPjD28znl3v/wBAD+7MRisRr/BAFQ8fXnSp/vBN/2Vjxc+m7HePq0LWiW91s5dVbRHJQNpXioZRNTK9Zur1y9oN+hI/jX7whznKLqeWRWsRBr/g9r9qJM4oX/P6u3ComKu+/lVAJx9cG+OOfvH1cca+qM+6/sjmT285jiETVt31Nje+lUlc94K1veYMLI/jaGupZJN0Q4FeRwMRESyxQjaKaMsb4NB78IOTJ0VTMV89mENGw2bb+4bcxj3jan5FF16T81xGT+/51rGhPexY9sChowdw82jk69LUN84hZEDutUZuHbv0rU1theXbuSG4rsAmKAnfGkBIh4L8jcY/Luyavc6cZLUD558mxX/+JRlt9RZnbTa5UcdWGN70XXHp7xu6aJg2cvYv5H5q8oAeL/iS354zIAaaccdui+/jNs+ffC+quaRFsSwiFcU5W0wEBHJJpUMIurzL77i2dXlAJyjaqKkFv7fWj5d8jzj+u4NwMMXDOWInzzH6mmjU5yZXPdONZe9vGDCncGbyh38sNZTf/fObWn99aImfZ5IrgRdS6MdDXIeDMysG/A4cACwFjjP3SsSpFsAHAkscffT4/b3B+YA3YAVwEXuvqP2+bUd2rcrs8YOycRfYY/33t1nMPSWdiy49xEAvjjnUMoWzSc2Yd2tC96l+KgD6ixeM/3l9wGYdN3daVXpVCz9ZcL9h0ycX2emVJEWxaJfMojCOIibgIXuPhBYGG4ncidwUYL9dwB3h+dXAJc2Sy5FRJqglVlar1zJeckAOBMYFb6fDSwGJtZO5O4LzWxU/D4LRnGcAHw37vzbgfuaJad57I2fngI/PaV6O/4p/de3/JrO065h+64qAO66+VdULJ9Bl/aZGci16o7RuJ+WkWuJ5EKwuE2uc5FcFILBPu5eBuDuZWbWqwHndgc+d/fKcHs9sF99ic3sMuAygL79+jUyu/KLxaVMuWF6nampy7dsB6DTXT8C4JIRBwR/hsfjpww/tN/eDfrMqI/eFElFvYkAM3sR6J3g0E8S7GvQpRPsq7fHqLvPBGYCDBs2XD1LG2lCUT96339Dnf09OgdtBtccF3QL/fWSoM3gZ7NepezhC5j32O0AHLyv1huQ/BP155msBAN3P6m+Y2b2iZn1CUsFfYCNDbh0OdDVzFqHpYP9gQ1NzK6ISMZFvWQQhQbkucD48P144M/pnujuDiwCzm3M+dI4XTu25cJhX0uZbsmaTSxZs4mvVi4F4OiDenD0QT1o07oVPb77CG+v28zb4brFza2wqJhNW3fUmeNIJBtibQbpvHIlCsFgKnCyma0BTg63MbPhZvZgLJGZvQI8CZxoZuvNLNaaORG41sxKCdoQZmU193mssKiYwqJi7lxUmvD4498r4vHvFSXsErprTQlLP97E0o83NUu+EnF3gucHkSxLsydRXvcmcvfPgDrzHLh7CTAhbvvYes7/ABjRbBkUEcmAaFcSRSAYSMv3sxunc8Hzd7JvYYe0z0k2gGzeyg3MWPxPFhQfnYnspfw8keYWVBNFOxxEoZpIWqiK5TOqf2Tbtc7cV2nyH1ezbPZjjT5fP/wSRZbmK1dUMhARyYZoFwwUDKTpMv0k/tqtJ8Gt9fZGFmmRVE0kEgH/3LiNyl1VVIZTZohkm6qJRERE1UQiUP8Sl9lyxLcnMvcPtwFw7MCeWf98yW/BU3+0o4GCgWTM30qDxYJOv2ImVGyo8aP/+rN3MOzbdSajzRr1MJKcagHrGSgYSMacPu726vd7Dx9V49iBvTrW+UHOdWlBJJsyGQvM7FTgHqAAeNDdp9Y6fi3BoN1K4FPgEnf/MNk11YAsItLsDLP0XimvZFYA3AucBgwCxpnZoFrJ3gCGu/thwFPAtFTXVclAMqYhT/eFRcV8/7YrAZgwLFiD+uDr5wGwcf1GNs25JOn5az/dxtDRExv8uSK5ksFqohFAaTgVD2Y2h2CRsNWxBO6+KC79q8CFqS6qYCA5c/4hwRIXX+8TrG/Qr19XANq0Sb1CWq8u7Tj8/DHNlzmRDGpgt9EeZlYStz0zXIslZj/go7jt9cDIJNe7FPhrqg9VMBARyYb0o0G5uw9v4JUSTsdrZhcCw4HjU32ogoE0WqwB+KNXptOpffKv0sYvtvONE68Das5pFO/5q44BYOwjJRQWFSet/tmrXWsWX5/y+y0SGRnsWroe6Bu3nXBRLzM7iWA1yePdfXuqi6oBWZosnVG93Tq24YapV3HD1KtSph1+QFfaHLx7VvIX3vmk3jUKEtl/why2flWZOqFIFpml90rDcmCgmfU3s7bAWIJFwuI+y4YCvwHOcPe0Vo9UyUBEpLllcJyBu1eaWTHwHEHX0ofcfZWZTQZK3H0ucCfQCXgy7KG0zt3PSHZdBQNptIb04mld0Iofn/j1tNJeP+ogrh91UPX25h07G5SvbW8toWLbGSmrrkSyKZMjkN19PjC/1r5b4943eKZHVRNJThRNepHyLdsp35KyKpNzD9+/QYGnYvkM+nbfqynZE8koI6PVRM1Cj04iIlkQ8dkoVDKQzCk8bRqFp03jmmdWpUxbOu8Z3t+4jfc3bstCzkQiIOJzWOc8GJhZNzN7wczWhH8W1pNugZl9bmbzau1/xMz+aWZvhq8h2cl5fttRWcVDr63lodfW7t5Zvg7K1/H5th0pz69YPoORA7oxckC3OscOmTi/Qb2HRFqCVmZpvXKWv5x98m43AQvdfSCwMNxO5E7gonqO3eDuQ8LXm82RSRGRpoh4wSASbQZnAqPC97OBxUCduY7dfaGZjaq9X3Ljw/Ivue7KXwBwSdi4m6k5guZceTSPjzowI9cSiYyINxpEoWSwj7uXAYR/9mrENaaY2dtmdreZtcts9iSRgb071TuSuKle+rCce6f/qdHnFxYV8+6GLRnMkUjTxBa3See/XMlKycDMXgR6Jzj0kwxc/mbgX0BbYCZBqWJyPfm4DLgMoG+/fhn4aIl37B2LAVj51FOw195U/O+URl1nzaf/hk0fNykvXfZq06TzRTJKi9sEkg2AMLNPzKyPu5eZWR8graHTcdcuC99uN7OHgeuTpJ1JEDAYNmx4womdRESaQ8RjQSSqieYC48P344E/N+TkMIBgwZjrs4CVGc2dpG3lU08FpQLgvCvPr97/2ZbtDeodNOOcwU2qfqpYPoM+Xds3+nyRzMvc4jbNJQoNyFOBJ8zsUmAdMAbAzIYDl7v7hHD7FeBgoJOZrQcudffngEfNrCdB4H0TuDwHfweh/gbkHbvSK4SVff4VAO7OvoUdkqbdVeXsc+FsAMr/cHH6mRTJEVUTpeDunwEnJthfQrCGZ2z72HrOP6H5cici0nS57jaajpwHA9nz9enaPmGpIVZ1dMWkYqaMPphBJ+9u7klVTVS5q4pda2KLQV2cqayKNJ+IRwMFA8m5NgXBv5KGtBO0a1OgtY+lRcllt9F0KBiIiGSB2gxE6qEne8kbBq0iHgyi0LVU9jAbv9jO5i8btiBNMtu+quTv6zZn7HoiuRHt2YlUMhARaWaxxW2iTCUDybhvnHgdBxz/o4xd7/q/rOa4/8jEzCUiuRPtcoFKBtIMMt0WcN+Yw7hvjNoXpGWLeslAwUBEJAtyOdVEOlRNJC1WYVExhUXF7KisynVWRFJSNZFImuIns0urqqn/UAAKot5nT/KeaQprkfS9vWAaAFVpTi5e8cSlzZgbkczSCGQREdHcRCKbv9zJ0rXlnDqoT9J0fbvvlaUciWRfxGOBGpCl+U1b/D7jxjduCUyRPYPRytJ75YpKBiIizUwjkEWAKaMPrnc9g8KiYkZMfjHp+X9ZuaFBy2aKSMOpZCA58+gjwRQTQ/crTJpuQNdO0Ll7NrIk0myiXjJQMBARyQJ1LRWpx+hDkvcuihm0fxcqXprUzLkRaUYadCYiImpAToOZdTOzF8xsTfhnnQpkMxtiZkvNbJWZvW1m58cd629my8LzHzezttn9G4iIpGZp/pcrOQ8GwE3AQncfCCwMt2v7EvhPdz8EOBWYbmZdw2N3AHeH51cAmqNARCInNj9RqleuRCEYnAnMDt/PBs6qncDd33P3NeH7DcBGoKcFc8KeADyV7HzJrXGPlKhrqOS9TM5aamanmtm7ZlZqZnUeoM2sXVhTUhrWnByQ6ppRCAb7uHsZQPhnr2SJzWwE0BZ4H+gOfO7uleHh9cB+Sc69zMxKzKzk0/JPM5J5EZG0ZCgamFkBcC9wGjAIGGdmg2oluxSocPeDgLsJalCSykoDspm9CPROcKhBaxmaWR/gd8B4d6+yxKtF1DvnpbvPBGYCDBs2PM25MaWppn1nEIf3vbrO/lhpoddxp/DuXd/JdrZEssYgk1NNjABK3f0DADObQ1DDsjouzZnA7eH7p4AZZmbuXu/vXlaCgbufVN8xM/vEzPq4e1n4Y7+xnnRdgGeB/3b3V8Pd5UBXM2sdlg72Bzakk6cVK14v79DGPqy1u0d4TWmGe1Ff59B1b95Lh19l8pMySt+J3fL5XnytKSevWPH6cx3aWI80k7c3s5K47Znhg2zMfsBHcdvrgZG1rlGdxt0rzWwzQU1Kvf//otC1dC4wHpga/vnn2gnCHkJ/An7r7k/G9ru7m9ki4FxgTn3nJ+LuPRN8Tom7D2/MX2JPo3sR0H3YTfei8dz91AxeLp0akQbVmkA02gymAieb2Rrg5HAbMxtuZg+Gac4DjgMuNrM3w9eQ8NhE4FozKyWIfLOym30RkaxaD/SN205UI1KdxsxaA3sDm5JdNOclA3f/DDgxwf4SYEL4/vfA7+s5/wOCOjQRkXywHBhoZv2Bj4GxwHdrpYnVuCwlqDl5KVl7AUQgGETMzNRJ8obuRUD3YTfdiwgI2wCKgeeAAuAhd19lZpOBEnefS1BD8ruwxmQTQcBIylIECxERyQNRaDMQEZEcUzAQEZH8DQZm9pCZbTSzlXH7bjezj+N6LI3OZR6zwcz6mtkiM3snnAjw6nB/ygkE9zRJ7kU+fi/am9lrZvZWeC8mhfs1MeQeKm/bDMzsOGArwdiFweG+24Gt7v6LXOYtm8KBfn3cfYWZdQZeJ5jf6WJgk7tPDec+KXT3iTnMarNLci/OI/++FwZ0dPetZtYGWAJcDVwL/NHd55jZ/cBb7n5fLvMqmZG3JQN3f5kU/W7zgbuXufuK8P0W4B2C0YspJxDc0yS5F3nHA1vDzTbhy9HEkHusvA0GSRSHayY8lA9VI/HCmQ2HAsto4ASCe5pa9wLy8HthZgVm9ibBFDEvEEwOmfbEkNKyKBjUdB8wABgClAF35TY72WNmnYCngWvc/Ytc5yeXEtyLvPxeuPsudx9CMMJ1BPDNRMmymytpLgoGcdz9k/AfQBXwAHkysjmsE34aeNTd/xju/iSsQ4/VpSecQHBPk+he5Ov3IsbdPwcWA0cSTgwZHkp7YkiJPgWDOLEfv9DZwMr60u4pwobCWcA77v7LuEOx4ezQgAkAW7L67kWefi96xlYTNLMOwEkEbSixiSEhT74X+SKfexM9BowimJb3E+C2cHsIQdF3LfBfsXrzPZWZHQO8AvwdqAp3/5igrvwJoB+wDhjj7nt0g3uSezGO/PteHEbQQFxA8ND4hLtPNrMDCWYI7ga8AVzo7ttzl1PJlLwNBiIispuqiURERMFAREQUDEREBAUDERFBwUBERFAwEBERFAxERAQFAxERQcFABDM738y2xr22m9niXOdLJJsUDCTvufvj7t7J3TsB+wIfAI/lOFsiWaXpKERCZtaKYIK+j9z9B7nOj0g2qWQgstsUoDNwVa4zIpJtrVMnEdnzmdlYgtlJi9x9Z67zI5JtqiaSvGdmQ4HngZPd/c1c50ckF1RNJAJnAoXAkrgeRX/NdaZEskklAxERUclAREQUDEREBAUDERFBwUBERFAwEBERFAxERAQFAxERQcFARESA/wcZi4tePhCc2AAAAABJRU5ErkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -147,7 +147,7 @@ { "data": { "text/plain": [ - "[]" + "[]" ] }, "execution_count": 5, @@ -158,7 +158,7 @@ "data": { "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -215,7 +215,7 @@ { "data": { "text/plain": [ - "[]" + "[]" ] }, "execution_count": 7, @@ -226,7 +226,7 @@ "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYMAAAEZCAYAAAB1mUk3AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4xLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvAOZPmwAAIABJREFUeJzsnWd4VEUXgN+TAKFD6L1ILyIIoSggilQFpEoV+BRQip2miHRQEREBNZFmAaQIIiq9g2AoiiCiNKlSQ+gQkvl+zN3N7mY32YSUJZn3eRb23jt3Zu7uZs7MOWfOEaUUBoPBYEjb+KV0BwwGg8GQ8hhhYDAYDAYjDAwGg8FghIHBYDAYMMLAYDAYDBhhYDAYDAaMMEgSRGSEiHyd0v0wJB0ikklEfhCRcBFZmMh15xWRgyKS0Tr+WUS6J2YbCejTNRF5ICX7EB9EpIqIbEvpftxPGGHgo4hIAxE5mdL9SAgiMltExiRTWy+IyCFrsFohIoUcrgWIyGciclZELlmDd2EP9dSz6nB8KRFp66HpdkB+ILdSqn0iP9YQYJZS6haAUqqZUmqO1c8eIrIlkdtzQkQ2iMgLjueUUlmVUkeSoK2vReSMiFwRkb9d2xWRhiLyl4jcEJH1IlLc4VqAiMy07v1PRF536O9e4LKItEjsPqdWjDC4jxGRdCndh5RERB4DxgGtgFzAUWCeQ5FXgDpAFaAQcBn4xF1dSqnN1oCXVSmVFXgauAas8NB8ceBvpdTdxHgWGyISAHQHkmRl6YO/mfFACaVUdqAlMEZEqgOISB7gO+Ad9Pe7E/jW4d4RQBn0d/E4MEhEmjpc/wbok9QPkGpQSplXAl7owWUxcB49CL3scG0E8LXDcW1gG3ow+h1o4HAtFzALOA2EAUuBLMBNIAo9IF2z2hsBLEIPFFeAF4AAYLJ1/2nrfYBVdwPgJPAGcA44A/R0aLs58CdwFTgFvJkIn0tvIAK4Y/X7hyT8DiYC01y+EwWUso4/Bd53uP4UcNDLumehZ+furo20ni/CesbngdLARiAcuAB8m8Bnqg8ccjm3wfquKwC3gEir3cvW9QDrszgOnAU+AzK5/AYGA/8BXwGBwHLrtxtmvS9ilR9r1X/LamOqdV4Bpa33OYAvrfv/BYYBfta1HsAWqz9h6L+NZl4+eznrN9rB4be0zeG67e+ivHV8CmjscH00MN/huLBVPiCpfoOp6ZXiHbgfX+gV1S5gOJABeAA4AjSxro/AEgbWD/IieuD1AxpZx3mt6z+iZzuBQHrgMet8A+CkS7sjrAHoGauuTMAoYDuQD8iLFjqjHeq4a5VJb/XhBhBoXT8D1LPeBwIPO7R1GaibwM9nNjAmjjJ7rTbcvaZ72c6HjmWtz1oBrazjGsBWtJDIDMwFJntRb2a0gGwQSxn7d2wdzwPetr6XjPfw2fUDfnQ5twF4wXrfA9jicn0ysAw9scgG/ACMd/kNvIcWGpmA3EBb6zmzAQuBpe7aczjnKAy+BL637i0B/A0879C/CKAX4A+8hJ6kSCzPPN36XSpgN5DVOv8x8KlL2X1W3wOt8vkdrrUD/nApfwWoktRjQmp4GTVRwghCD+ajlFJ3lNalhgAd3ZTtCvyklPpJKRWllFqNXu42F5GCQDPgRaVUmFIqQim1MY62f1FKLbXqugl0AUYppc4ppc6jZ63dHMpHWNcjlFI/oWd75RyuVRSR7Fb7u203KaVyKqWSTDetlKpiteHu1dfLan4COljGwkxo4azQgxzoQeo4egZ5BT2zHuVFvW3Rs/u4vgtHItDqikJKqVv38NnlRAsirxARQQ+8rymlLimlrqJVZ46/xSjgXaXUbaXUTaXURaXUYqXUDav8WOAxL9vzB54FhiqlriqljqGFsuNv7l+lVIhSKhKYAxRE21fcYn3f2YB6aLXQbetSVvRKy5Fwq2xWh2PXa45cRX+miYZlpzgnIvu8KFtfRHaLyF0RaedwvqqI/CIi+0Vkr4g8m5h9TAhGGCSM4kAhEblsewFv4f4HXxxo71K2LvoPpChwSSkVFo+2T7gcF0Iv1W38a52zcVE567VvEP2H1Ba9WvhXRDaKSJ149CPFUUqtBd5Fq+v+BY6h//hthvdP0bP03GgVw3fAz15U3R34UllTSy8ZBAjwq/UH/r943OtIGDEHtNjIixZ+uxx+Xyus8zbOK8sYDSAimUXkcxH5V0SuAJuAnNZAHxd50Kth19+co2H+P9sbpdQN621WYkEpFWkJ0CLo1QToiUt2l6LZ0d/xNYdj12uOZEOvNhOT2UDTuApZHEevlua6nL8BPKeUqmTVNVlEElVoxRcjDBLGCeCoy2w2m1KquYeyX7mUzaKUmmBdy+XhR+BpIHI9fxotcGwUs87FiVIqVCnVCq1iWgos8OY+b6qOq4A1YLp679hen3ndkFLTlFJllFL50EIhHVqVAPAQMNuaMd9GG49rWoZJT/0qilatfOltH6x+/KeU6qWUKoQ2Wk4XkdLxqcNiL1A2tqZcji+g9eKVHH5fOZQ2gnu65w306rCW0obb+tZ58VDetT3bKshGMfTqKzFIB5Sy3u9Hf4e6cyJZrGv7rQnUGcfr1vv9DuULoQXXwUTqGwBKqU3AJcdzIlLK8mbbJSKbRaS8VfaY0p5NUS51/K2U+sd6fxpt03MU4MmOEQYJ41fgiogMtvzN/UWksogEuSn7NdBCRJpY5TJabqNFlFJn0DPV6SISKCLpRcT2h3kWyC0iOeLoyzxgmGjf9DxoVUmcnigikkFEuohIDqVUBFqNEunl88fFWbQdxSNKqUrKwXvH5fWiN41Yn2Vl0RQDgoGPHVZaocBzIpJDRNIDfYHTSqkLsVTbDW20POxNHxz60l5EiliHYegBNSGf56/oWbpbF1j0Z1tERDIAKKWi0CrKj0Qkn9WXwiLSJJY2sqEFyGURyYVeXbm24fb7s1Q/C4CxIpLNcvV8nQR4P4lIPhHpKCJZrb+NJkAnYJ1VZAlQWUTait5zMRzYq5T6y7r+Jfq3H2gNvr3Qs3YbDYB11kQgqQkGBiilqgNvou0gXiEiNdFCK16/ucTGCIMEYP1BtACqor0lLgBfoL0sXMueQLs+voX2vjgBDCT6s++Gnmn9hZ4dvGrd9xd6oD9iLf8L4Z4xaBvEXuAPtAHOWx//bsAxS1XwItq+Adg3GdXzsh5XZqBtEZdFZGkC6/CGjOjl9zX0IPoL2g3Rxptor5h/0J99c6C17aLozVxvudT5HFrPHV+CgB0icg1tzH1FKXU0vpUope6gB7SuHoqsQ89+/xMRm1AbDBwCtlvf5Rqi7ULumIw2JF9AOx+4us9+DLQTkTARmeLm/gHAdbTTxBb0dzAz9idzi0KrhE6iBehE4FWl1PcAlg2sLdqmEQbUwtkW8i56AP0Xbd/5QCnl+Cxd0J5VSYqIZAUeARaKyG/A52g1sDf3FkR7ePW0BHuKIfFTixoMhqRGRPICm4FqlpOAIZ6IyINAsFIqSexgIlICWK6Uqiwi2dEuyx4FgIjMtsovcjiXHe25NV4plai72BOCWRkYDD6GUuq8Uqq8EQQJRyn1R1IJAjdtXQGOikh70B5eIvJQbPdYar4laEeFFBcEYISBwWAwxAsRmYdWSZYTkZMi8jxaJfW8iPyOVuO1ssoGiQ4r0x74XERsBu4OaMN9DxH5zXpV9bL9WF1bLWE0RXSYlr0i8rBX9Ro1kcFgMNw/WE4m19CrispurjdH23Wao+0sHyulasVVr1kZGAwGw32EO9dWF1ph7ZNRSm1He6fFadD2taBVyUaePHlU8eIlUrobHtlz4Lj9ffnShQm/fZczJ87az1WrUCwlunX/c+E8V0+e4U5gHnIX9+SgZTA4s3v3rgtKqQTvA/DPXlypu96ZgNTN8/vRXnA2gpVSwfForjDOm1NPWufOxHZTmhUGxYuXYOuOnSndDbcENhlPQLlTnNn2MQAZ0+uNoTdu643ElV7/nj9/XU9Y6NQU6+P9QGBQfwBeHNmf8c3L4xcSTPq+VhDLi2eIGD2CqF69U7CHhvuFTOnl37hLeUbdvUlAuQ5elb3127RbSqka99CcuDkXpz3AqIkMqRK/kGCWHV5Gzwv2Dan4L1kMRP+l2I4NhqRHQPy8e907J9GhbmwUwYuoBGl2ZeCLbP7nPAB+uQqwdOoL9hWBjcwB+ut6r1dNQsp6jPuV5rGtAJ4Enrx6ggN7foLm5Yls3Ra/1avsU6TI1p7y1hgMiYwAft6EfkoUlgH9RWQ+2oAcbkU7iBUjDHyI+Xt1fK+oQ7uoV6anx3Idqhalz+CvCfxOx1wL2zg2Wfp3v+C4AlBAua0rieB1onr1JsK6Htm6rVERGZIXcae9SUg1Mg8daiOP5bb6LjpEPUqpz9DRfJujd6XfADwPJg74jDAQnaHoY3QM9C+sQG6O1+ujt9FXATq67OSLRIdiADiulGqZPL02+CKxrQCievU2QsCQAkhiqYBQSnWK47pC58WIFz4hDESHzp2GTvxyEggVkWVKqT8ditlCwb7ppoqbSimvNmz4KusPnmPuhM8B7IbhwFZWhsbTzkEXw0KnMmJYByIizR4Rd5gVgMEnSaSVQVLhE8IAqIlO9XcEwNJ1tUKnZAR0KFjrWooGc0oqCmfPRMbK0bvnbZ4wAH6lq5MtZzbCd26wXwsLnWov83PnDqx9rT6GaMwKwOBTCIm2MkgqfKV3nvxivSWjiOwUke0i8oynQiLS2yq38/yF8wntq8FgMMQT0SsDb14phK+sDBLkF+tAMaXUaRF5AFgnIn+4i0dvbdwIBqhevYbP6FguXL1NrZZD7eqhmqPWALBivs7QWKtULgDu3G0DwKNj1xEY1J/qXXSmvI51irhWaQBOh+lNPrmyZrB7ZvmFBLPxnQ8p+0Y/8g98OSW7Z0hrJJ83UYLwFWGQIL9YG1amIJRSR0RkA1CNFE4UER/Emg3sP3kFgH9+/YPn3nrJLgRsZEinF3Lf9K7Fe+XyMKOjNpMEBvXn6Mj+jG1ePhl77dv4hQRzePAYluQoxaEh41nWp7aTyylvvUJEzox2VdK/F25QKGdGANKn85UFsyH1kHgG5KTCV3oXCpQRkZJWaNeOaF/ZOLGyHAVY7/MAj+JgazCkPeyD/tUTTDu5gWZbdH4dT5vO/EKCKdyxJelmhKREdw1pAcGoibxBKXVXRPoDK9GupTOVUvtFZBSwUym1zEopuQQIRKeRHGklk66ADg0bhRZuE1y8kHye4xducHHHJwz60crmd/YwH7eu5LF82YLZ+O7DL/juQ31coXUbOlQqkAw9vT9w3Wfw8sU9RODe5dQmONIDbFzLlpOXCBo9NEX6bUjl+PjKwCeEAYBS6if0ZgnHc8Md3oei1Ueu920DHkzyDiYhT7QfRnDIYGaMmgbgVcyhM9s+5rfjlwHIkTE9h8KuUfqWzoGeJaPPfK0pgqd9Bu5cTtM316mCbYLjkV0biMAIA0Ni4/tqorQ9ahhSJbHtM3B1OTUhKgzJggD+xoBsiIOw0KmcuHiDgo839/qejOn9adbxXadzs2fqGW2rB+PjlZs68XafgdmgZkg2zKYzgydsO4w3TOlGg3bD4h2S2lY+aOQa2tUrboRAAjEb1AxJj++riXy7d6md0wfh9EEiIhUFGjTzWOzAqSvM/PUY58JvcS78Vozrh5YvZcOBtL2JLjCoP4t+P8mi30+mdFcMBvf4uDeREQaG+x5b7oLS332T0l0xGDyTfPkMEoRRE6Ug9oB0Qf05vukjp2sHT1+lditnr5Y3HN7vW/kBhXNlstcTfiPCHqvozLaPY+RCSK04bSQbN4ScGTLAQ6+ldLcMBmdSeNbvDWZlkEIENp/I+oPnWH/wHAB3o6KjY5wOu+kkCHYun0BY6FT7C6Byk4FO9ZV4LHoAVD4TaCPpcd1IVmbrigTVExjUn4Onr3Lw9NVE6pnB4IKfv3evlOpeirVsMCQCNlfQe3ENtamZcs2dlYg9MxgcSda0lwnCqIlSivPHuHk3Eoi5yWzk6n/cnrdx9pcp5K/zMofPXgOgVP6s8fZESi3cq2uok5pp6CtkzZgO+vdNiq4a0jo+riYywiCFcMxH8FnwIJ6tVoy5u/8FYMEHwbEO7hnS+fHN7Lep8fQQe11pmahevWkaUZmQttXg0k27LcUbXENXZP/peyKMMDAkNiafgcGQ9PiFBDPh09fI9uXMeN+bGGomgyFujJrI4IZ+i/+gW9VChP6g0zwXzZ2Jqzcj6NfnAwAOr58UZx3NKxVk8IRXgJiZzyDtrBZsap4ggIG/sv/8FQqP1cb33//VsZvKFcxGxgzuDXNmB7Ih2fDxfAZmZZACzJ3wOc1e+pxsmdKRLVM6AlzcQHNlzeBVPW0qFqBNxQJQsCy9v/09Kbrq87h6E9XfswHQQuJKtSrMadCab/eecLonMKg/py7dtB9H9epNxE8reTGwDn0X/UGk5dkVGaWIjFIcOXc9yZ/DkAYwm84MhqTDnZrHNZ9B+aXz7OVtnkOuKiW/kGBeG9eH+msX2c+l+yKEgKeakvPr+KufDAYnxKiJDG6wqXRGrdFeQ9PaPkix+q/xz7oP41VP2YLZAHj48aosnBiSZlRDjngTlrrubh2W2slzaGB/IrKkJ6pXb/v5ykDlP37h6oMFSJ/en/T9+gBQcM0qIrIFGBWS4d4w3kQGd7gO3O3e6EX2TOkTVNfa1+pzvFsN+4apUvmzcOnaHfLlyHjP/bwf8DYstavnkP+SxUT16o3/J5Odzmf57BMoUtRtWYMhoYiPCwOjJjKkOqJ69SZi+udENWqs/7cGcc+eQ65/pGK8jAyJis56KV69UgqzMkhGHL19fvl+POULZbOfXzb3XXvC+4TwULNBMc6lRbWRDXdhqT15DkUOeAW/vn2iB/4BryRvZw2pHxHEz7dXBkYYJCOHLJtA6Sfe4KV5u1n/xmMAvD7uZaoUznlPdTsO/HuPh1OxcLZ7qi+14klI3Fi/gZvffcfKbMVp68buYNREhnvF19VERhgkI7mzBQDO0UoBZs4YQo7MMe0Fx85rl8ZqPYPh7GGna8vmvku9Mnndls+ZOT0nLt6kZL4sifsAqRS/kGACFs4jM9D58t9EhASbdJiGRMfXhYHP2AxEpKmIHBSRQyIyxM31+iKyW0Tuikg7l2vdReQf69U9+XptSA247lWwHR8ICORAQCC3p31mVgWGe8bYDLxARPyBaUAj4CQQKiLLlFJ/OhQ7DvQA3nS5NxfwLlADvaLfZd0blhx995YJa//h9xPhAExrV4VcWTOQvbpWEz2QI2uM8hsOnqd115Ee62vZeSTTPtdhrDs/XByAas0Huy2blm0H3uC6ClB585K+bx8qWMd3ENJQVHBDUiDE9FPwMXxCGAA1gUNKqSMAIjIfaAXYhYFS6ph1Lcrl3ibAaqXUJev6aqApMA8fImTpPi5tXwtAqZBMfDZ1AOtHNQfgARd1zuGz12jddSQ5ghoAcGy600II0ComW/iK0t+OouYDuZwG/eu373Lx6p2keBSfpPGULSx4viYAObN4t4PbRlSv3vT7fBNT8p7nbus2pF/6HRBtL9g1KYSHe0evDC5fv8PGI+dNzmmD1wgpO+v3Bl9RExUGHGMGnLTOJeq9ItJbRHaKyM7zF9J2zuDUhF9IMB98/jqZZn+R4Ptbn97D3dZtuPt8rxhupRcz53AqG9jmKR5YbFJsGuKHn5+fV6+UwldWBu5Eprcrc6/vVUoFA8EA1avXSNaV/+FPWgOt7ceBQf2p3aMzAD/3ewTAHhOnxtNDeKLPcyx+oabH+hwD0zV5djg7lo2370geueog1QtlI53lylYsT+ZEfx5fwbZ7uCbAq6Gcv3qbnENiT3vpFxLMxsFjqDfhbQDS93tR70ru9yJ3I6OIeuklIrdswn+uHvCf/mMtESHBumxfvSu5xro1RBTOaWwJBq/x9ZWBrwiDk0BRh+MiwOl43NvA5d4NidKrJMSdHj9PrQHWm2KxCgLXOgKD+lOr5VBObdE7aSe//UmcbaUWXHcVl9y0gohYhIFTSIp+L3KrdHmn+zN8v4Sol15Czp93Om9rx/WcEQYGr7gPbAa+oiYKBcqISEkRyQB0BJZ5ee9KoLGIBIpIINDYOmdIA8R3p7D/Jx8DDp5Dl8Oc7o/Kk9djvWZXsuFeMN5EXqCUuisi/dGDuD8wUym1X0RGATuVUstEJAhYAgQCLURkpFKqklLqkoiMRgsUgFE2Y7Kv0GDiRn7/diFky61P3AgnqHM7Vr1c114mKipaa3Xw2/jtgHWXy2DfiXAyWqGx/71wg+KpVFUU/3wEztrByMCc+DV+0q4SCvh2LhGPPUZklOJQQCAApT+aEL1becsm7i7/kcV++WhrVgUGL0lsA7KINAU+Ro+XXyilJrhcLwbMAXJaZYYopX6KrU6fEAYAVkd/cjk33OF9KFoF5O7emYDPxhl+vkEJBv/5CN8MfhKAuXvO0KxibqcyuWsN4KPp2ms2X/aAeLdxeP0kCtd9FdDCoF6bt52up2ZVkbtdxZ5Q1R6GAwfsIuF2lapkcFUJfTKZ9AcO2F1LI6z//UKC8Z/7Df5AZy4TERJs1EQGr0mscBReuuIPAxYopT4VkYrosbVEbPX6iprIYPAKv5Bg0jdvgp9l0I0vsme3/t86zrT39xjqH9tV101onjanGQxxIomqJrK74iul7gA2V3xHFJDdep8DL2ywPrMySM10q1GcbjOL248fL5fP6foj49Y5Ba5LCJky+EPOAvbj1LgSsBl/AfxWryICEjAzd/5jS5fOjwgXVRPgHLjOOmdCVBjuhXioifKIyE6H42DLE9KGO3f6Wi51jABWicgAIAton4nYMMIgGVh94CxHLt9gyMvRyWscB+sDS75jZ5NS9ywMDizUaqYC3b/mvzldU11OZE/5COKDpwilrqomd3YIky/ZcC/EQxhcUErViK0qN+dcXeU7AbOVUh+KSB3gKxGprJRy3bRrxwgDw31DYszMvR3QPdkh4mOfMBhsJLIB2RtX/OfRkRhQSv0iIhmBPMA5T5UaYZCE1J2wHoD9i/WMdv8qHT7C3zIkBTYeB8CH096ka/XibmqIH+eu3Abg9p/bga73XJ+vEZ+ZuW1j2ZIcpRi+b6VTiApvB/TT700m14plvHUpL5N+/zYxHsGQlkk8ZyK7Kz5wCu2K39mlzHGgITBbRCoAGYFYwy4YYZCEhHSrDsDeJqVo91C0ILcJA8mldfxZM/gnSntViumwCSvmjyIwqH+qUA054hcSjP+SxQw4cIeh87uTN5Zyto1lT149wSuNXuT9bdHOZt58Nn4hwZQcpjevTQMiQhra8yUfmD6Lzy9nZNLR9YnzYIbUj5BooSa8ccUH3gBCROQ1tAqph1Iq1qgLRhgkIRUKZ7f/76q/D2z1Cc/1eAKADlWLur3fkdNhNxmw+A8Art64wyftHqKcBxtDRJRHteB9i6PxeBpwY94s6POi27KutoU+e5cCM+3CpOeFOwz96S/GNy/vsT139gnQ4SiqYBMQxrXU4D2Juc/AC1f8P4FH41OncS013Be4unVmWPKdx7KurqIVb4eRrntX0vftg9/qVUw7uYFB/Z6O1T3V3W5j41pquCfEy1cKYVYGSUjTqVsB2DFnXgy1RIkqZamQP5PHe29FRPL0tG0A7Pompr669lfzIbAQAGeWDyajg6qpbpk8lG3Z2mk1Ave3R1GMnANtY4b1thHVqzdRn0zG78AB+8yen38Gomf6BU4ehr59PLqnerJPGNdSQ0IxgerSKJ1m72THHJ1SYcDoAU7XmnyylaceKc6Ljzzg9t7bEZEUfCQ6JEXRRk+zY0QjvZfA4s0fDjBj1DQACj76Ck369WB+j2hvtHWDHuNS3zoAVGk6iGKNn06cB0sh4uvW6brTWJUqBTsv2Y9d3VODu79FhR++ZkmOUnZbgKuhObY+/HvhBpv/1fa5xHAGMKQuUjrukDcYNZHhviGqV28iflrplZ7eMeooADlyEjH9c6Iq6CATjrN7v5BgBswdz5NXTzDt5IZY1Uee+pD965k0faUb5ZbOje9jGdIIJlBdGmX8UxV45qFBALzY+30+eSdaTXNg3ykyZ/T80RewVgWxqXUmtqjAxBb6eqmXl7By2myqHb4IwJ7RTcgSkI6f//rPXv74quUwtum9PZQP8+uRSwSV1IHlRASVV/sa2VcC+fMRac30bYZk2+w+ffMmugzRq4Xrt++yc+wnLCnwEJP2zI+1bb+QYAoM1Ku/wjs2E1EstzEsG2KQWLGJkgojDJKIEnmzUCKvTmf5rDWo//7vZQB+fLsJDxbLEeMeRx3/mW0fe93W4Smt+WRLFYa/9hEAKzpVoWnFgizaEy0MmvXvGf+HuE/wCwnm9uAxRI4dyu2evciSMV2MfAS2Y4ip/nGXAznna/20a+qFv4gIeSLWwT0xdkYbUj9GTWQwJCH2PQVXT5Dl5b4EzAoB4pfnIKpXb61CatSYiOmfx1AxxeU1ZPIcGOIkcQPVJQlGGCQRZV79nsCg/k6z/QbthtGg3TDqtxsWo3zJftEDzsG1H9pzEXjLgLql7O9/O3MNgPk9ajC/Rw3CQqcyonFZDpy6woFTV+L7KD6Nq7tnph+WAg4DfIWKHAgI5OL1Ox7rCJ88lY2Dx9jVRp4G930j3+d22bIcyZqLmf97K0mex5A6EUDEu1dKYdREScDEDYe4sHU1+eppXbRtx6snG8Dl63e4/Ot6Ni4eCyQsnwE4p8E8+NrzzOpczX6tVsuhMcrdb/iFBOP/3WIG/HXH7vETV7wivwN/6rwEAwcQkSVDDPWNX0gw+QYO0CEdHVxNI4CohQu52aI1fz7ZnqCQYKqPGQzouMAVvhpPRJ0SRPXqbdREBi8w3kQGQ6JgUwf5rVnl5PHjquJxHIS92STmqUxUr97cbNGaTD8sIf+3s53KuZY1aiKDN/j5iVevlMKsDJKAZ8oX4PCg3oxqUg6AsOsNCHxyNISf1ccuM/OSDV5nwOgB9thC98rWJeN4tPVb1CutQ1oPD96eKPWmJLHNvm0G4buRURAZRTp/PcfxJsqppzJ+IcHkfL0fAKXWryGycxfAOU6wrawJbW2IkxSu8je8AAAgAElEQVRWAXmDEQZJQKYM/jQonZO8lronb/YAts5+hdt3nWMG2ewJ04MH0alasURrv2KR7Hw0/U1e6zsRgI6DenPp0VKsWrEXgJeX7GNK68qJ1l5yENfAfrDJMxTeuIKV2YrT9vxBwLtB2lMZV+Ej589zadJUsn02ldNXblNo+BCn+v56uhPbqjYGoEciPrchdSCQorN+bzDCIAkYv+Ew34z/DFsYtZAvhrDlaDiTn6lkL3Pm8i0yV9FxpCoEZndTy73RI6gEwa3bADCmWXlyZ81A4PQ5AHw1bg9TWt9fdoPYBvZ03btSZd33AHS+/DeR3btyd87XzPzfW9TZtY6QK5loPLEFTdEz/j0ffcGcm1k87jQG98Ln0KkwiubKx/s3/JjkUv7LLoNo8tuPLMlRCkw0U4MbzMrAYEgkPOUh8FvhHHfIb8XP+IUE89JX4wEdYfT4WwPwe6ox6fv2oSY6iWxsUUddhQ9AzbFD7PU53usXEswHmz8DdMhsE83U4A5fNyD7jDAQkabAx+j43F8opSa4XA8AvgSqAxeBZ5VSx0SkBHAAOGgV3a6Uch/bOInZ9Lf2T/9m/GdsWDSGiZuOADB19WF+/2kdk58ZaS9bsdGbVGyjB5mqJXImSX+2vaVDZLsGrEttRDVthv/cb+yz+KimzWKoeYr9uJioIweczsXl9eMofNztUvakUjLeRIYYGJuBd4iIP3rC1Qid0i1URJZZMbltPA+EKaVKi0hH4D3gWevaYaVU1WTttBsCM+psWgEVa/NQ8Zx81e3h6ItvPmZ/W+2dlcyYMYQ2VYrEWt/VmxEA9PhmD+s+/9Jjucmfvkn3GiU8V5SzAKFfvcrjw38E4NqezXE8yf3F3TlfE6XAf8XP3GrUBP85X+MXEmxX89gjlzr962x3GFinJy0PrnUKVOdIbDaLxEjHaUjdCJJoyW2SCp8QBuhV+yGl1BEAEZkPtAIchUErYIT1fhEwVXx93WVINu7M+pLwm3cByI2e1Udu2eS0Yogc8CqRuAlLHRLMlJ2zAc9qnthsFsabyOANvj5a+YowKAyccDg+CdTyVMZK+xaO/rsHKCkie4ArwDCllNupr4j0BnoDFC2WeN47NtKn05L/9oWzBI1cw507enA6vmq5kzvpsXVr2P1IcdpUcV/P3cgo+i76g4UTQ5zOB1SsDUDrp6vw3Q+/c+fADgBefWkirwKBtbRa6MjUNk73ha0expK9J8mWU2dGu3Zvj+mTdPtqNyumzQbg+KaPSJ/Oj8nPvcvDecrz1IHNToO062DtrZrHpjb6579r/PbbCdo7ZKjzNq+yIe3i63NXXxEG7j4l13ydnsqcAYoppS6KSHVgqYhUUkrFiLuglAoGggGqV68Raz7QhLDvfLh+c+4oh5YfJfQHbfY42lXvBLbp7uv07MyYZjFTLt6xXE/z13kZgBpdOwKw+pW6Mcp+2r4K0A2AqChFy+DtbJ3xjW6nyUHCVg51Kv+/5ydwYvNkAF6Yn49JGw/x+mOlE/ysvsa8HjUItIRBOn8/jl+4wXtDdLC/sNCVsd4bXzVPvSFLub1/O+0dBPzWQxdYckDbjCa20GGyXVOdGtIwxmbgNScBx0TARYDTHsqcFJF0QA7gkpXk+TaAUmqXiBwGygI7k7zXhlSBUfMYkhodm8i3pYHosTSFO6EH97+BhsApIBTorJTa71CmH/CgUupFy4DcRinVQUTyooVCpIg8AGy2yl2Krc3q1WuorTsST14cO3+d1lO2ADqfwImLNzh68ToA9cvq2PqvLNGP80zFvDxeLl+MOu51Jjlh7T8A9hnxuoVjAKhWIicRd6PIZ6047qWNlCQqSv9WN/1zga4T13IypGO87rd5e7XqMjLOZx+0/AAhI3UmOVvZC1dvA7DswBn+V7OEU/kSLy0ifOcGp/LtZ4YCsCb4G8K2T45XXw2+Rab0skspVSPuku7JUricqvDSZ16V3fXOE/fUVkLxiZWBZQPoD6xEu5bOVErtF5FRwE6l1DJgBvCViBwCLgG2kaA+MEpE7gKRwItxCYKk4FT4TY6t+AGAc28+RrdZofz+7UJADw6BQf3xL6O/34/n9ohxf2BQf9KXrwnAf3O6JagPQxqWAaDqnLfp1H0sT7TX0VE7De7DJ23urx3H7jh0Vls7Wne1uejGTxhUL66T30yY8kacZcc3L0+I1Ywt0OCYtYcAmDP2U/7nIkyOfdoOcM7LfDsiUr+JvBuvfhpSJ2YHspcopX4CfnI5N9zh/S2gvZv7FgOxB5w3GAyGlESMmshnSWw10b4T4dRr87b92FUN8cfxcLJl0rLXlgHNRmBQf9q/2Yvp7R4EsAdau1cCW38KQOXaFVg+4FEyWN5OxXp+zdxhTWlUIX+itJPcdJy9k5XTZts/4/0nr1C39VsxPvMf958B4OXPt3N4Sut4txNhGfTvREaRJcBn5k2GFOBe1URZi5RTlft7zq3tyI6hDdKumig1cMchCF1wyGDydJ7NBUsdZLMFuA5WtvPPD+/HhOblEk0I2Ahb8pK9nRK/7CdsqY7CuXtKe6o0HXTf2QxsPP1gXhz9g8oUyMqISa/Z04o+VFzv6F74m077eemXtUC0MHhi0ib2zFtgf/5L1+6w8I9T9KlT0qkdm6uw7f/YUErFmPkFNrCSGF2/fN9+1obEwvfzGRhhYDAYDMmAj8sCIwwSg+u37hJ+J8I++1v42wmnWcCxjR+RzsV4FBjUn8d6aUPxmCZlE31V4IjNgD18hQ7f1OnBgknWVnLQtXpxujrMtDOk8+PT7w8wYuMKIHoFNruLlemti/OsfEizskygg/14Ruhxxg2aTI9t2gsrIJ4pR8u98QPnNq1kk5Wp7kErL8XmrwYCcOhyatzmZ4gX4vsGZGMzSARW/HmGTt3H2o8d00+6nrOdz179MXZPbAVA7qwZ3NZ78472Rpn32wne6Dcx1j5krFyHpcOaAVCrVK4Y1wObjIdLp5xPZsik+7b1g1jrvl+wfd7blo6jQuH4hQWPj1tv6VeWcnHbmhjfqbf3G+4/7tVmkK1oeVX11S+8KrvlzXrGZnC/UihrZqdjmyvixR2fOJ1vOnWr/f2aEc08CoGz4bco/+SbnhvMY4XSuHDcfurWvl9o2vEX+/F3Xw932ssQtnIo07fqKKpvvzoJgG+/iNvF0hd5cvJmdn3zbYxBt1JbvXO4cK5M8a4zPgP4O92q8l3FAvbjEi8tcltHw482AbB7xVanHeHrD57j70vXY9goDKkbYzMwGAwGg7EZpAUyZ/CHB6rxx6edAdh07FwMtcHdyCh2zJkHwNez36ZMgaxOdYTfiKDEY685nev+tvYGcsyQFhuLfj8JQK8XJtCm6yj7+Xz1m3Dwwxb0ffQBAPqGTqV1yA6efW6MvX++xgfrDzFukN6169q/sS0q0fSbmPdsGfJ4ovbB5pq69lAYk1pVdFpZOfbp0NQ23I54Jsb9eXLqFUrGQs5BEW3fTR8f/NwNSYdZGaQBsmRMR41HypElQBseOz9cnA7bpziVyVv7ZToN7gPAU5W0ATfSCq/w9s9/8fmIafayaxeM5uGSgfHuR7uHdH6EdqFTOXXpJjXe+A6Ac5tWEvjYdsI2Rts1NgR/Fe/6k5Png4oxznpvU7vZKJ0vi/ubEpFbEZF07Wu1eSOcSa2mkjNTtGF57/Fw1hzV4S1ef6w06fz9YkwAvu0ZpA9s/1sEVKzN7T+3J+0DGHwLE6jOYDAYDDq5jW9LAyMM7oGVf+pNTR27a3XLA1/Pd7ru6FU05dOBdKtR3H7tbmQUeWtHB457fng/e+jjxKBwrkycmdUFgGE/V2fa8Kn2mWuF1s75DjxtiktJgnf8G+Pc7NBjALzWd2KMvj4TvIONIXq1E5c319I/TvHTnxcIfvYhj+3XGrEabuiQ5FU7tndanXQOnepU97YXn2PtZzEz0e04rENkvbloLw2rFmREk3IAZlWQRvHz8aWBEQb3QM6AaG8gx8Em/EYESil7lNIsVetSs5Czu6ejIPB2ELaplS5eu8O58FvkzKLbz5c9wB5qwh1jmpWnTrG36dpDq4kOLPnObbm7kXoXdVLuefCW/9Uoynsu57o+rHXvkxo9HUN1VLNUIBut94f+u8b0HdGeVjavrmu3dMC4nv8bD0Dws9H37z4aRsMO79iPw0KnwtimQMwc0tXfXeV0/EKdoqx1E5CyaUd7aC32LYIRTXR7i78azqlrN90+tyH1kpiyIK6c8VaZDujskAr4XSnVObY6jTAwGAyGJEYSMVCdNznjRaQMMBR4VCkVJiIxY+a7YITBPVDU8meXUg/TZ8FeFtjSVCpFWOhUvhynA8UNee8VyhXKxtq/zgLQrttoijZ6mr3jmrqt98rNCEatOcSMUdPcXveW8s9oddBnXR/mqUoFPW6SslF9uJ7x/j7Wfb+Sk3w5MvJgex0S+o+F2o/ftmLp3LAUk07UtJc9G36Lc1cj7Mci8G6jMrQor2fmNl3ts7NC7WWyPFTXST3WsNNIvKVCqdwccThuWlF/tgV7ahenW/t+YeSqg/iVrg5A1KFdTve37aa9ibr5kFrOkPQkosnAm5zxvYBpSqkwAKXUubgqNcLgHvjttA6Mpg7vZsEHu/nt5/cBrW4JDOpP69dfAGDwE2XsG6UAtn8/nnKFstnruXozgpcW7uXHT2a5byhnAbr1fYb+tbXNoWzBbE6XlVKEXY+w69ltyW3+WqrVQQ2s/18dOwCAl2oVZ/W3o2n07DtO9RxftVy/8QFhAPDfmRiZSwGdt8GWuwHgy90nmTP20xjqNtumuxg2kZfqOAnDpX+cgrwl4L9DTvcXf3Fh9EFAZm7c1mqmya0r8+OCUnD2MACnw26y7MAZbu2L3vQ3+W3nDYeObFo8lvpt33bql9nBnPqJhwE5j4g4hkcItlL22vAmZ3xZABHZilYljVBKrYitUSMMDAaDIYkRtEeRl1yIIxyFNznj0wFlgAboNMKbRaSyUuqyp0qNMEgge4+H08UyyP7+8/tU7T+fqs0GAVCs8dN0GNibcc110vvA5hPh/DGObfwIgByZ03Pm8i0qNnIfcmLWzKE882Bhr/siIuTKmsE+Wx7iMrP8/o9T9PjfePtsNa4EjIt+P2nfs5BcBDYeB2E67XVY6FReXbqf81u02qrDQOecxCHbj/Lj3nMs7a0nQwMfL81ndRrGmF0HtnD/pBsOnnc6Dj1xFf47RK3unQDsmwNbN60IwJxdG+H2DQo/bdnoLv9H1Y7tCQjQqqpKXabB+WP2+oK6dSQwWwCrps9x2379tm+7PW9I3SSimsjbnPHblVIRwFEROYgWDqF4wAiDBHL48lX7+4eaDWLdwjFci2gBQMvOI3ntmTcp/fjr9jJHN0ziuqVmcN1p3GXoi0x1SEsZFaU4fuEGY6ycxgu/2wlH9sS/k4W0K2O95kHsXD6BUvn1rueL1+449c2Vfh+up92XCUu9mWDCnH/LgxuUYo61R27BtG/5vEMV+7XRs0K5unsTgQ6upC+1eZCxv6x1qmPGWG1zeP75CeAf/VOPTpupGdu8PDO+rW0XAgDHL9ygZXmdu3pj0xYcW/EDYat1foLAoP78Nj9aheTqyhr6lbOLsSuvjBnAx8M8q5FsnlJb/rkAwO3ISBqWvz8TERksJFHzGYQCZUSkJDpnfEfA1VNoKdAJmC0iedBqoyPEQsr7EBoMBkMaQMS7V1wope4CtpzxB4AFtpzxItLSKrYSuCgifwLrgYFKqYux1WtWBgmkUBbnSKVPvDYPTup9BQ937sBrfaNDTu9YNp6SDZxn4usXjrHvDWg6egXfjHfjqH6vnNb5CzZ/cZAa3kXPBeDOgR1ANyZu0AbVWoVzUK9M3sTvXywUzJkx+uBGOIFB/Xnr/VcBuLp7U4zyl2/GTDp/5NKt6AOHpPRntn5MwebjIPys/dyzz1TjS2szWL76Tajx2iIi/vrVbd+ObphEye6zwU+Hp1jw2wn69HLeFTFhyhsMeflDp3PuPLhio0XnEfb3y+a+m+zfgSHxEBJ305kXOeMV8Lr18gojDBJIoZwZoUBpAGaNa0/P/41n9GT9ub9jhYi2UaulFb44s056wo1wHm8/LNn6mhBcB66TWybb8wDfuH2XyChFtkzpY63j613au2nCwj/5oldNapfK7bZud+lAj25w/gwBWpbTqpJxMa7AtOHOdXz+y1HGDnS2Gew+GgbgtLnMhs0NGHQsp7DQqZR+RedEuLhtDQD13tsAwL5Fi5zuHfhZzNwJQ96c7qaX7rl+K6Ygc6Vl55Ex1FGzZurfVXzsS4aUw9fDUfhMcpu4dtSJSADwJVAduAg8q5Q6Zl0bCjwPRAIvK6UcU+S6xS9zPhVQrkNcxQwGQxonLHTqPSe3yVWyomr47tdelV3Us3qKJLfxCZuBw466ZkBFoJOIVHQp9jwQppQqDXwEOlqBVa4jUAloCky36jMYDAafwU/Eq1eK9S/FWnbGvqNOKXUHsO2oc6QVYPPVWwQ0FG2ebwXMV0rdVkodBQ5Z9RkMBoPPIF6+UgpfsRl4s6POXkYpdVdEwoHc1vntLve6VaKKSG9AO62nz+quSKKQq05D9k1sSaYM988CxUmPn1/vrnUX/ROAgMxw+0aS9WXA6AF88k6062VY6FS+23tSu4g68M86baAt88Qb9nIAfRf9wbz3Pne63/UZDq79kHINndN+2u4v0XcR4aEbnO9/crSTwdm1zlx1GnJ4Smsg+vOaMWMIAG2qFHG7wzi2HNmu5y5fv2PfVRSYxX26VINvY5LbeIc3O+o8lfHmXn1Sb+kOBm0ziE8HDQaDIaFob6KU7kXs+Iow8HZHXVHgpIikA3IAl7y8NwYFiuQn7F567MKpLZPJHOArH+e9sXJKd5o8O5z/LmvXzMINn+LNthWi3WVv36Byu3Z81uVhAOq2fkufz2FtjLJm0KE/6Jl8/beWcfOPbfb6izz5FCsHNeCFeXoj3S+z5gKwcbEVYvtiuFN/PLlk2lYEABQsa3+73gpf7TizDgudyrkrtwHImTk9GdL50XNYXwC2/XGG7cMa2suWr1iQA1GP8e9n7QF0ukuXVQHoAIQAB85cY3aXatF9yVsCzh+jTZWE7eJ2F5sop1kN3N+ISW7jLd7sqFsGdAd+AdoB65RSSkSWAXNFZBJQCL3l2r2DuANXb0aAS/bEB5rr/RqP1yjKrLnbY0Sb9MSZrR+T8T5SCbnDdQAKC53Kgt+05u7U2h95be2PTtf3LVpEXQcXS3fuoUEttJpk2dx3ORb+KC+/9AEAJ9f8SKHxzThg5Ri2UaWYdr1t+NZSp/M9h/Vl1pjpkEfnMwj7WYf9OBeuhdXNiCiK58nM8/N/A+C/DT/H6M/+k1c4ceU6oKOMAvy4SQeaO7dpJTgIgxX9H3W699kqhXmb6CiwNiYM/jj6oEt0e1mLFOWaQ3gKT5iAdGkLoybyAssGYNtR5w/MtO2oA3YqpZYBM4CvROQQekXQ0bp3v4gsQIdvvQv0U0pFpsiDGAwGgxvuBzWRz+wzSG6qV6+hlq7eCsDwlQeZ/35wjDJZHqoLwKOPlnIbdOzsLzrpfWxZxu5XAoP6U62T3oex7vX6bsuE39A5BHYdD6Ntt1FkrFwHgFe71eSpMvmo18YKyJa7KGErBjPz12MAvNFvIjmCGnBsuo4ddPHqbXrO3cPmL6L9sE9snsyVm7r+QoGZvOrzof+uATBm7T/OahsgsPar9l3Icc3I7zUNqLv7TYjq+5t73WeQ54FKqsW42GNW2ZjdqUqK7DNIs8Igd8mK6kbOJ5zO9RnRD4ARjcuy+dAFOjw3OvpiwbJw5m/74ZoFo6leMjBZ+prcuIZXyFe/CaFjmlK8vg6w993Xw+25AsCzTt826H2181+u34nkxUceAKDhR5vYPXcBeR5tBMCFraud7ivc8Cn2TWjG6gNaT9/hudHxGkDvdTA/fPYal29EOH2/8fEG6jR7J2vW7Of8190T1L7B90gMYdDSS2EwK4WEgU+oiQwGgyE1IwL+Pq4n8loYiMhzwFql1CmX852UUvM83OazFA3MxHcrtUGzUGAmbkdEsuD3kwAUfER7iQRUqg3AkP/VYeQbHzndn1pXBYBeFeQryUOP68lJs4cL2VcFAF/uOkWbrqPsarTQHyZQuoDzvo3A5hMJfMoK1HbuKKATstoo0+IZ/vlZx9k6sHoi12/ftYfYtpE5fbRR/urNCG5GRAGQL3uAbsOhfseZ+R8rP+DBJgNZf1Bn+rOtYnZZsYnKF8pGloB0VBqs2z+97ifCQqey55jO+/FE+2ExVhV7V7xvV4vZOLRex0+6ecfZRLVixiK4dQ3t72AwaFKTAXkWcEZEOiiltjmc/xy474SBvwiZLQ+g5tO32d0bAbJUrcvJkI72wcJVEKR2na+75xscOpUdhy8B0LTjcJbPG8HTnUYAENRiS4x7Grd/zP7jn9/jDXYeCaPRIJ0DoHy10vzy9hME/qC9hipYSX5eGaPTcn4cshH+3Wuv011ayHFr/7YLmdkzHcUMFLFyU9+N0irQkO1HGTQgOoLowAkv81bDsgzrqHNIfFU8JwDZMnr+cyiaOzNFczufm/7LMQBmfLeXY5+2i75w65rHegxpFx+XBfEKR3EDHR9oiYi84HDexx/RYDAYUhbBu7hEKRmbyGsDsohcUUplF5Gy6Cw6a4FX0cHjYsbw9XFKV3pIncpQz378cOcOrH0t2mvGyShauAKcOmA/TO0rg8Tizl2t1knnF/uGm1IvL+GSQ5ayNQtG88vpMPo/+oDHe9b9dY62g78FIOz7AbH243TYTSo1Hki+ek0AODiphdP1wKD+fDnrLVpULqSPH3kDIm47fc+Dlh8gZOoy3d6KwQA0+UR7o/365bwYBuQVn35F2A6HfQiG+5p7NSDnK11ZtXt/gVdlP21byecNyAKglPpbROoA3wCr41mHz5AlQzq7eqGVSzx4myCYN0e7RnbqrnfGpiUhEH4jwp6e09vnfv37PwH438OFqVw0B/nrvAxA5Xbt2Dy4gb1c4BPv8uGEnvyvZgkADk9pTaOP8+LvrwVG9ZKBcdpkniifL04hYKNQYCZq9+jM9tk2VWALfv/3Mg3a6ZwSB9dMJHe2AHv5o6vHc9Ulx8CFq7fh4gmnc5+006k4f6nj/PuZ16MG9Ej2v2WDj5OabAbrbW+UUuEi0gKdZ6RkovcqGUjnJ3YhoJRi/Lp/+GCI3jfwcOcOrHqlHnlqeTfYpBZ+OaSz4jXv9C4nt0Qnhln31znadhtlFwqH/rtGUIshHgPZzbL+9yhErl7k7/M3nU7t3HaQdOmtn6PLDuDfjl3mvQ2H9CDrBQdPX2Xt0fP0dVhZ/NzvEej3iP04q4N9IF+OjE7358ySIUb4h5mdqjKzk4tdZJROmxG+cwPd09BEwRB/BG2n9GW8thkopVq6HCul1FCl1H0pDAwGgyE58RPvXilFfFxLR3m65ph7837idoR2CSxguZLus1xNC+fKFO98tamB2qVyAVpnX6Tuq/aZ/bHzOqZPns6zATg6o4s9jhPAR9PfpECWAJpUKADA9/tOkyVdzJ9WYH3L6ydTNiY8VcF+vto7K+HIHs57mF0PWraP0K/me1S9BLaYzLbP/keFwtp01XLiBs5tXknfWGbrpfJnpfXr2g8iMKg/p7d+HGvI8eMXbvDrKe1N1e4hHYCudq0SAKzc6fE2g8GOj28ziJeaqKjLcQHgMWBJ4nUn+bgbpexCAGKGDnh+eD9mfGblm7ZcGFM7Dw9fBcCxHbvYsWy8/XyJvFlY/e1oGj2rcwdny9SDXSMb03y69jCe3PpByhbMZi//zIOFCQzq73GHcYeBvQm7focoy/WzdpWCREQ8Re9vfwdg4awVdiMtwKqX68LLdWP0d+5unWOZ/w5x4OIVuzDQBuIWMcq70qyC9hVdAvx3+RYl8+nIhR+sP8S4QZOdfhNPT9rEidXLAWhnnV85bXacbRgMoN1KU43NQCnV0/Wclbe4U6L2yGAwGFIhqWll4I5VwLeJ0ZHkxt9PWDxHa7eeKK93qAY+Mw2A7NUfY8aoaU7l04In0bEVP9jfp/f3Y/M/5wGoVyYvNR4IjPEZ2DbqfVa4L5NaOaesbty3Ox2r61DRjSY8RdHG78DNqwB83qFKzLg+7avQ7avd+sT1mJkmTly8wd/n9f0Ny+u8CasOXLJfT0jugPZV9WK3vfVctk114wZNjlF277imMK6p07kjG/QO5NNht+LdtiHt4eMLg3jZDFydvjOjcw6ccFPc5xGihQBA3Qnr7XsJvp/chR/+eYhJ70zXFyPvuqkh9WGLOvpM8wd5uMtHcPk/AHYun0DmgHTkzRbtYZPO3y9WAfltzyCn47BN0WqnwKD+bP5urD2qaWBQf8JCp/JVN50sp8nlm/ZzNmoP+p4be7Vfv+28PTKplUvg6Dlt26j5+qIYQeI2/X2eVl1GAnB++xTS+cf0nahhubP+/vP7PNTa2UTWbsavrP3sS6f2beknTRpKQ1wIkM7HpUF8VgaHcE4zeQPYgwnAYjAYDHHi47IgXjaD1Be03+K5r3ezf/FiNllpF+u3fTuFe5QynJnVxf7+0/ZV7O/jClFt45ngHQDM71Ejzsxvp67e5PRWvUM3IjLK6drT1Qpw5HAj5/IzOhGXeerA+SsA3D0YyoS1jzCgrvZ6zhKQjmUHL9jLHT57nXKFssW43xZVMkqpGPGFtm09FGvbBkNsSAqHmvCG+3L3cGLReY5Oa/nz1FlsXTKOVUe0jvzbL4dRLEcW6rTSrpAFH2+eYn1MCRb+doLevd6j4YvPATEH/e2HL3L1TkzV2caQrwA42+ZBiufJ7DGvgOtxoUeHwJ2b9vMD6pZiQN1SXvc3sP5Q9iweRvNKBe31Bwb15/H5WtVTq1QuJraowMQWzu32mq+9lxZ9GOLUp4ajVy0bn0EAABuESURBVMVoY8or9en1wrYY5w0Gb/FxWZC2hYHBYDAkF6ndm+i+Ze/xMP6cqgMn7Fw+gVL5s1Jv4GIAog7tcir75/tpa2Xw4ntrAPhlm04Yz/M1na7XLpXb9RYg4R5Xb4zsRdiNezDS37zK2Su3KZFX7xP4af8ZQK8IYmN4ozIALLKiW/99RnsrOQbNs9HuoSL2/QUGQ3wRUlFym9RG5PWrHF4zEdCxaQLrDaFOJ72rdsmXzzHj1395+9VJKdnFFOPivJ5AT25ZSVtcPXviIjCoP2VbtvZ4T2BQf5bPG8GjpfMAMOzJsvfUX9d2Lt264919152T1dg2zqUFN2JDMpPCoSa8Ic0KA4PBYEhOxMdTv6S4MBCRXOiNayWAY0AHpVSMXUci0h0YZh2OUUrNsc5vAAoCtjCYjZVS5+Jqt1qFYvZolbuPhtH51S6s2nwEwClMRVqkdcgOapfKxRuPWUbcDJnclou0wknYorvaZtSN+3anf90S9nIHT1+lUGBGijmkzqxaJGcS9FzTtXpxurrM7n89cokmzw536meBHDpstV/p6knWF4MBtJrIrAziZgg6t/IEERliHQ92LGAJjHeBGui9DrtEZJmD0OiilEpwuLCGHd6hWqcOLHmjAQB9C+Xgz9+OsXx03PFtUiMbgr9ie+U6tKmovXOmTx3A0J/+olRuPXi2rqiTwJR+4g0AKrZpS5XS0XYE1w1ntVsNpWKbtvQZ0Q+Az0dM4/jFG/ZYQp68jmJj+tYjTmq82O7df/KKXRDY+O/yLXu6TaMWMiQHRhjETSuggfV+DrABF2EANAFWK6UuAYjIaqAp95h72TYIdRn6IkVzBvDMRJ2yYcXQJ5lVuYBHQ2lqxzY4Fuk1H4Drv23RF7Jqg+zAa5do90Yve/mtQx/3qj4b1QsPplT+rNEnCpUjT8li8epj87L5GW3tmO7QsmqsZUvkyUzr119gZqfoclkC/CEgc7zaNBjuBV8PVOcLG8nyK6XOAFj/53NTpjDOYS9OWudszBKR30TkHYnlExeR3iKyU0R2nr9wPjH6bjAYDHEiAv5+3r1SimRZGYjIGnTIa1e83errboC3JW/uopQ6JSLZgMVAN+BLd5UopYKBYIBsRcurap06APByneL8dvYyF7dpl8qgFvr/sc3TtvrAviLAvSolpGP0uScnb2bXN9/aywYG9affKL3yGtOsfIzAdEfOXSdjeuuXf/ogF04fRC8S3fPx5sOMeP0j+/0l8mZx2jHtyB/Hw6nf9m17n7NkTOe0KgDIlik9YVve99iewZDYJOYOZCti9MeAP/CFUmqCh3LtgIVAUFyq9GQRBkqpJz1dE5GzIlJQKXVGRAoC7oy/J4lWJQEUQauTUEqdsv6/KiJzgZp4EAaOXA+/Tq/HSwCw7OBZft5zmv2rdHKbSn3mwtE9cT5XamfKpwMBuHU3Ko6SsPTFOpzqED3gblkyjges/ACgd3XnyRidZ7j6U9GawGVz3yV7hvQe6957PNwuCNwxaeMhBjz6AOnTaeESkN4XFrwGQzSJaUAWEX9gGtAIPTaGWjbUP13KZQNeBnZ4U68v/NUsIzrYXXfgezdlVgKNRSRQRAKBxsBKEUknInkARCQ98DSwLxn6bDAYDPFCJ7iJ++UFNYFDSqkjSqk7wHzcL6tHA+8DXsVY9wUD8gRggYg8DxwH2gOISA3gRaXUC0qpSyIyGgi17hllncuCFgrp0culNUCIN41WK5OfTtW00XLC2n84c+Ya56/cBuCvkC7kz/F84j3hfUq3GsW9Lps1Yzqn4G+VimR3ut64grOW0KZKAmjZeSRhoVPtmdaO/rzMXgbg/Q2HnI5dGf3mZNqveJ+iubVBuGzBbMZDyOBjCH7e7zPIIyKOKp1gS8Vtw50NtZZTayLVgKJKqeUi8qY3jaa4MFBKXQQaujm/E3jB4XgmMNOlzHUgwU7ifRbsBWD/kYs8WCEvDdoNs18zg0lMbIP3/lUfUCjQ/d4DG59tO8LQV7Trp6fP8qiVHCYiUpt/WtXVwmdJVAt2joyOWvr1c9XhOc9fs/muDL6OEK9AdReUUu4TfkdX54qyXxTxAz4CenjdIj4gDAwGgyHVI5Au8TYanMQ5J30R4LTDcTagMrDBcq4sACwTkZaxGZHTtDAol1+rFaKiFCEdH6JbOh2Df/mUmbHdluap1HhgnLPxukVz2zOneSKnS4awdxuXc/o/LnYe0XsOGz37jlkdGHyaeK4M4iIUKCMiJYFTQEd01kkAlFLhQB572zpKw5s+4U3ki+z9N4y/g3UaxaG9HyVfty/Z/F5rAJpUHJiSXfNZdi7X3ms1nh4SZ9nKRXPYXT//PnOVMgWyJvqmm8Asnj2QDAZfI7FcS5VSd0WkP9qxxh+YqZTaLyKjgJ1KqWUJqTfNCgODwWBIThJzLqSU+gn4yeXccA9lG3hTZ5oVBqUKZifYij0UdusOEX/9Su1Wv+pjo3Jwiy2ERFjoVPadCOfCDR0qukG5vDE2lTlSq+VQDq79kHzZA0hMMgek2Z+v4T5D8A0//thIs39NWTL4U9CKWpoxnT+fhwxm+T4TosITgUH9ObllMgARd6Oo1yZ683hY6FQWfPkOmdP728s65itIKuGa3xIuO5aNT9D9CQmQZzAkCEncHchJQZoVBgaDwZBc6B3IRhj4LG2m6gTnh5YvpUm/HmzfcUxf6PpwynXKh6lpbQo7ve4np9n0jsOXKBmYhdL/b+/O46so7z2Of36EsCgoYVFQoSLaWtygELGuvFxeRWpdekWh2otV6rWaqhUV7aJiLy1irdrCSy+Kym2tuHWxSnGhcJVeqiAuRbyWaBHRVIgEBKxgyO/+MXPCSXJyluTkzCTn++Z1Xjkz88ycJ8Pk/OZZ5nn6B9VIC+bdzPDPNZ2vIHEnfs+913H2Efvl9Nm1O+v4VzjzWs/uQcNxp7CrXmKGsr+t3QzQYFwikbiIdygo8mCw7MZgyKSyVe/y9KwH9AWSRsNz03BO6DHjG04ak2nu4Z6luV92Z97zIn+Z82CKvOzyxX2DoJBttZH+v6WQYl4wKN5g8Erl+vo71ecfn8a2z86MOEftT7pG4xE3PsM78xsOK9GaL98nL/kyXJL+uYXO4fi/iZKCSHxY7OczKNpgICJSKOpNFGOHD+nH9XOuB4I6Znr1p+bZH2bYS5KtX/oLAD7bWUdZeQVf/lbwEOT8S49m6rhDuTvNHXrtzrr6BrVOBZgPcG31Jwzqq5nNJDpqQI6pEjOuvX8FADbkS2ycd2HEOYq3v1dt4ZSpCwB49+5xAPXzB5R27sTZk7/N944dXJ/+tEP3YUw4Umn1lu2U7d6lfjx3M6PfUZfDHv0AqFl4Y1Z5aGlX0NqddRxx6rVN9kscr+ovd9KtS0lOxxTJicV/2suiDQYiIoWiaqKYe+SK4wAoKUA1RXv29Kp/Mn7ifyatGUdZeQXT7rgKgEuPOYB7xh/RZL/bn38HgJ9cGzysxqBDAah5/JK0d/eHXvcn3l/4VN56+3Qu6ZT2WJ/trKMbKhlI21LJIKZWrttcP39B16FH8c+550eco/j6/RvBTKTJX6h9jj6ZEwf3q18uK69g8k8vB+Csg/tz7Fnfr9+W65f6nG+PYu7Ihs8hbNy6o8Hy1k9rmfdaML/HpFGDaQl1LZVCincoKOJgICJSKEbQThlnRRsM+pd1Z/qcYCjmsw7P7WnYYnPXuMO5a1zDu+jKOxs+l/HTO69iXHged+9SwrDx47h+bPp5CZp7TmHUkN5NHlybtXRNg+XFleu5puI2ACbpDl/agZjHguINBv+qrds1T5yk9Z1HX2fF/23gxR81mZ203iVHH9BgedHkEzIet3JRMO1l4m9k/htVALxd8wnfPXZIg7QTDtuHnyctn3boPqrmkXbEsJhXFBVtMBARKSSVDGJq08ef8tSqagC+rmqitBb+7xo2LHmGCQP3BOD+84bzpR88zaoZYzPsmV6fHg2nvTxv0q3Bm9odfLfRXX+fnl3o/PnyVn2eSFSCrqXxjgaRBwMz6w08DOwPrAHOcfeaFOkWAEcBS9z9tKT1g4F5QG9gBfBNd9/ReP/GDhvYiznjh+XjV+jw/n776Qz/UVcWzHoAgI+/fhhVi+aTGLDuhgVvUXH0/k0mr7nj+bcBmDr59qyqdGqW/jzl+kOmzG8yUqpIu2LxLxnE4TmI64CF7n4QsDBcTuVW4Jsp1t8C3B7uXwNc1Ca5FBFphU5mWb2iEnnJADgDGB2+nwssBqY0TuTuC81sdPI6C57iOBH4RtL+NwF3tUlOi9grP/4K/Pgr9cvJd+m//NEv6TnjSrbvrAPgtut/Qc2ymezRLT8Pcr1xy1jcT83LsUSiEExuE3Uu0otDMNjb3asA3L3KzPbKYd8+wCZ3rw2X1wH7NpfYzC4GLgYYOGhQC7MrP1tcybRr7mgyNHX1lu0A9LjtewBceOT+wc9we/KQ4YcN2jOnz4z705simag3EWBmzwH9U2z6QYp1OR06xbpme4y6+2xgNsCIESPVs7SFJpUPov/d1zRZ37dn0GZw5fFBt9BfLgnaDH4y569U3X8eTz50EwAH76P5BqT4xP1+piDBwN1Pbm6bmX1oZgPCUsEAYH0Oh64GeplZ57B0sB/wQSuzKyKSd3EvGcShAfkJYGL4fiLwh2x3dHcHFgFnt2R/aZleu3fh/BGfy5huyeqNLFm9kU9XLgXgmAP7csyBfSnt3Im+33iA19du5vVw3uK2VlZewcatO5qMcSRSCIk2g2xeUYlDMJgOnGJmq4FTwmXMbKSZ3ZtIZGYvAI8CJ5nZOjNLtGZOAa4ys0qCNoQ5Bc19ESsrr6CsvIJbF1Wm3P7wt8p5+FvlKbuE7ly9nKXvb2Tp+xvbJF+puDvB/YNIgWXZk6ioexO5+0dAk3EO3H05MClp+bhm9n8HOLLNMigikgfxriSKQTCQ9u8n197Bec/cyj5l3bPeJ90DZE+u/ICZi//Bgopj8pG9jJ8n0taCaqJ4h4M4VBNJO1WzbGb9l2zXzvm7lG7+7SpenPtQi/fXF7/EkWX5iopKBiIihRDvgoGCgbRevu/EX7rhZLih2d7IIu2SqolEYuAf67dRu7OO2nDIDJFCUzWRiIiomkgEmp/islC+9NUpPPGbGwE47qB+Bf98KW7BXX+8o4GCgeTNXyqDyYJOu3Q21HzQ4Ev/5aduYcRXmwxGWzDqYSSRagfzGSgYSN6cNuGm+vd7jhzdYNsBe+3e5As56tKCSCHlMxaY2RjgTqAEuNfdpzfafhXBQ7u1wAbgQnd/N90x1YAsItLmDLPsXhmPZFYCzAJOBYYCE8xsaKNkrwAj3f1w4DFgRqbjqmQgeZPL3X1ZeQXfvvEyACaNCOagPvjqJwFYv249G+ddmHb/NRu2MXzslJw/VyQqeawmOhKoDIfiwczmEUwStiqRwN0XJaX/K3B+poMqGEhkzj0kmOLi8wOC+Q0GDeoFQGlp5hnS9tqjK0ecO67tMieSRzl2G+1rZsuTlmeHc7Ek7Au8l7S8DhiV5ngXAX/K9KEKBiIihZB9NKh295E5HinlcLxmdj4wEjgh04cqGEiLJRqA33vhDnp0S38prf94O184aTLQcEyjZM9cfiwA4x9YTll5Rdrqn926dmbx1Rmvb5HYyGPX0nXAwKTllJN6mdnJBLNJnuDu2zMdVA3I0mrZPNXbe/dSrpl+OddMvzxj2pH796L04F2jkj/75ofNzlGQyn6T5rH109rMCUUKyCy7VxaWAQeZ2WAz6wKMJ5gkLOmzbDjwX8Dp7p7V7JEqGYiItLU8Pmfg7rVmVgE8TdC19D53f8PMbgaWu/sTwK1AD+DRsIfSWnc/Pd1xFQykxXLpxdO5pBPfP+nzWaW9evSBXD36wPrlzTs+yylf215bQs220zNWXYkUUj6fQHb3+cD8RutuSHqf80iPqiaSSJRPfY7qLdup3pKxKpOzj9gvp8BTs2wmA/vs1prsieSVkddqojahWycRkQKI+WgUKhlI/pSdOoOyU2dw5e/fyJi28snf8/b6bby9flsBciYSAzEfwzryYGBmvc3sWTNbHf4saybdAjPbZGZPNlr/gJn9w8xeDV/DCpPz4rajto77XlrDfS+t2bWyei1Ur2XTth0Z969ZNpNRQ3ozakjvJtsOmTI/p95DIu1BJ7OsXpHlL7JP3uU6YKG7HwQsDJdTuRX4ZjPbrnH3YeHr1bbIpIhIa8S8YBCLNoMzgNHh+7nAYqDJWMfuvtDMRjdeL9F4t/oTJl/2MwAuDBt38zVG0LzLjuHh0Qfk5VgisRHzRoM4lAz2dvcqgPDnXi04xjQze93MbjezrvnNnqRyUP8ezT5J3Fp/freaWXf8rsX7l5VX8NYHW/KYI5HWSUxuk82/qBSkZGBmzwH9U2z6QR4Ofz3wT6ALMJugVHFzM/m4GLgYYOCgQXn4aEl23C2LAVj52GOw257U/M+0Fh1n9YZ/wcb3W5WXPXYrbdX+InmlyW0C6R6AMLMPzWyAu1eZ2QAgq0enk45dFb7dbmb3A1enSTubIGAwYsTIlAM7iYi0hZjHglhUEz0BTAzfTwT+kMvOYQDBgmeuzwRW5jV3krWVjz0WlAqAcy47t379R1u259Q7aObXD21V9VPNspkM6NWtxfuL5F/+JrdpK3FoQJ4OPGJmFwFrgXEAZjYSuMTdJ4XLLwAHAz3MbB1wkbs/DTxoZv0IAu+rwCUR/A5C8w3IO3ZmVwir2vQpAO7OPmXd06bdWefsff5cAKp/c0H2mRSJiKqJMnD3j4CTUqxfTjCHZ2L5uGb2P7Htcici0npRdxvNRuTBQDq+Ab26pSw1JKqOLp1awbSxBzP0lF3NPZmqiWp31rFzdWIyqAvylVWRthPzaKBgIJErLQn+SnJpJ+haWqK5j6VdibLbaDYUDERECkBtBiLN0J29FA2DTjEPBnHoWiodzPqPt7P5k9wmpEln26e1/G3t5rwdTyQa8R6dSCUDEZE2lpjcJs5UMpC8+8JJk9n/hO/l7XhX/3EVx/9bPkYuEYlOvMsFKhlIG8h3W8Bd4w7nrnFqX5D2Le4lAwUDEZECiHKoiWyomkjarbLyCsrKK9hRWxd1VkQyUjWRSJaSB7PLqqpp8HAASuLeZ0+KnmkIa5Hsvb5gBgB1WQ4uXvPIRW2YG5H80hPIIiKisYlENn/yGUvXVDNm6IC06Qb22a1AORIpvJjHAjUgS9ubsfhtJkxs2RSYIh2D0cmye0VFJQMRkTamJ5BFgGljD252PoOy8gqOvPm5tPv/ceUHOU2bKSK5U8lAIvPgA8EQE8P3LUubbkivHtCzTyGyJNJm4l4yUDAQESkAdS0VacbYQ9L3LkoYut8e1Px5ahvnRqQN6aEzERFRA3IWzKy3mT1rZqvDn00qkM1smJktNbM3zOx1Mzs3adtgM3sx3P9hM+tS2N9ARCQzy/JfVCIPBsB1wEJ3PwhYGC439gnw7+5+CDAGuMPMeoXbbgFuD/evATRGgYjETmJ8okyvqMQhGJwBzA3fzwXObJzA3f/u7qvD9x8A64F+FowJeyLwWLr9JVoTHliurqFS9PI5aqmZjTGzt8ys0sya3ECbWdewpqQyrDnZP9Mx4xAM9nb3KoDw517pEpvZkUAX4G2gD7DJ3WvDzeuAfdPse7GZLTez5RuqN+Ql8yIiWclTNDCzEmAWcCowFJhgZkMbJbsIqHH3A4HbCWpQ0ipIA7KZPQf0T7Epp7kMzWwA8CtgorvXWerZIpod89LdZwOzAUaMGJnl2JjSWjO+NpQjBl7RZH2itLDX8V/hrdu+VuhsiRSMQT6HmjgSqHT3dwDMbB5BDcuqpDRnADeF7x8DZpqZuXuz33sFCQbufnJz28zsQzMb4O5V4Zf9+mbS7QE8BfzQ3f8arq4GeplZ57B0sB/wQTZ5WrHi5erupfZuo9V9w2NKG5yL5jqHrn11Ft1/kc9PyitdE7sU87n4XGt2XrHi5ae7l1rfLJN3M7PlScuzwxvZhH2B95KW1wGjGh2jPo2715rZZoKalGb//+LQtfQJYCIwPfz5h8YJwh5CvwP+290fTax3dzezRcDZwLzm9k/F3ful+Jzl7j6yJb9ER6NzEdB52EXnouXcfUweD5dNjUhOtSYQjzaD6cApZrYaOCVcxsxGmtm9YZpzgOOBC8zs1fA1LNw2BbjKzCoJIt+cwmZfRKSg1gEDk5ZT1YjUpzGzzsCewMZ0B428ZODuHwEnpVi/HJgUvv818Otm9n+HoA5NRKQYLAMOMrPBwPvAeOAbjdIkalyWEtSc/DldewHEIBjEzOzMSYqGzkVA52EXnYsYCNsAKoCngRLgPnd/w8xuBpa7+xMENSS/CmtMNhIEjLQsQ7AQEZEiEIc2AxERiZiCgYiIFG8wMLP7zGy9ma1MWneTmb2f1GNpbJR5LAQzG2hmi8zszXAgwCvC9RkHEOxo0pyLYrwuupnZS2b2WngupobrNTBkB1W0bQZmdjywleDZhUPDdTcBW939Z1HmrZDCB/0GuPsKM+sJvEwwvtMFwEZ3nx6OfVLm7lMizGqbS3MuzqH4rgsDdnf3rWZWCiwBrgCuAn7r7vPM7G7gNXe/K8q8Sn4UbcnA3Z8nQ7/bYuDuVe6+Iny/BXiT4OnFjAMIdjRpzkXR8cDWcLE0fDkaGLLDKtpgkEZFOGfCfcVQNZIsHNlwOPAiOQ4g2NE0OhdQhNeFmZWY2asEQ8Q8SzA4ZNYDQ0r7omDQ0F3AEGAYUAXcFm12CsfMegCPA1e6+8dR5ydKKc5FUV4X7r7T3YcRPOF6JPDFVMkKmytpKwoGSdz9w/APoA64hyJ5sjmsE34ceNDdfxuu/jCsQ0/UpaccQLCjSXUuivW6SHD3TcBi4CjCgSHDTVkPDCnxp2CQJPHlFzoLWNlc2o4ibCicA7zp7j9P2pR4nB1yGACwPWvuXBTpddEvMZugmXUHTiZoQ0kMDAlFcl0Ui2LuTfQQMJpgWN4PgRvD5WEERd81wH8k6s07KjM7FngB+BtQF67+PkFd+SPAIGAtMM7dO3SDe5pzMYHiuy4OJ2ggLiG4aXzE3W82swMIRgjuDbwCnO/u26PLqeRL0QYDERHZRdVEIiKiYCAiIgoGIiKCgoGIiKBgICIiKBiIiAgKBiIigoKBiIigYCCCmZ1rZluTXtvNbHHU+RIpJAUDKXru/rC793D3HsA+wDvAQxFnS6SgNByFSMjMOhEM0Peeu38n6vyIFJJKBiK7TAN6ApdHnRGRQuucOYlIx2dm4wlGJy1398+izo9IoamaSIqemQ0HngFOcfdXo86PSBRUTSQCZwBlwJKkHkV/ijpTIoWkkoGIiKhkICIiCgYiIoKCgYiIoGAgIiIoGIiICAoGIiKCgoGIiKBgICIiwP8DGNbWYhbOVC4AAAAASUVORK5CYII=\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -259,7 +259,7 @@ { "data": { "text/plain": [ - "[]" + "[]" ] }, "execution_count": 8, @@ -270,7 +270,7 @@ "data": { "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -357,7 +357,7 @@ "data": { "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -373,6 +373,64 @@ "plt.ylabel('Longitudinal momentum uz')" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that reconstructing the trajectories can also be done with the method `ts.iterate`, in order to avoid having to explicitly write the above loops:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 29/29 [00:00<00:00, 166.88it/s]\n" + ] + } + ], + "source": [ + "z_trajectories, uz_trajectories = ts.iterate( ts.get_particle, ['z', 'uz'], select=pt, species='electrons' )" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(10, 4))\n", + "plt.subplot(121)\n", + "plt.plot( ts.iterations, z_trajectories[:,0], '-o' )\n", + "plt.plot( ts.iterations, z_trajectories[:,10], '-o' )\n", + "plt.plot( ts.iterations, z_trajectories[:,19], '-o' )\n", + "plt.ylabel('Longitudinal position z')\n", + "plt.xlabel('Iteration')\n", + "\n", + "plt.subplot(122)\n", + "plt.plot( ts.iterations, uz_trajectories[:,0], '-o' )\n", + "plt.plot( ts.iterations, uz_trajectories[:,10], '-o' )\n", + "plt.plot( ts.iterations, uz_trajectories[:,19], '-o' )\n", + "plt.ylabel('Longitudinal momentum uz')\n", + "plt.xlabel('Iteration')\n", + "plt.tight_layout()" + ] + }, { "cell_type": "code", "execution_count": null, From 0fd0b16e5e510cbacc637e12f136ef91af5f6d44 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Fri, 25 May 2018 07:24:51 -0700 Subject: [PATCH 39/90] Correct some errors and add example --- opmd_viewer/openpmd_timeseries/main.py | 38 +++--- opmd_viewer/openpmd_timeseries/utilities.py | 11 +- tutorials/5_Laser-plasma_tools.ipynb | 125 +++++++++++++++----- 3 files changed, 122 insertions(+), 52 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 622fb4de..df8e8a00 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -12,7 +12,7 @@ import h5py as h5 from tqdm import tqdm from .utilities import list_h5_files, apply_selection, \ - fit_bins_to_grid, try_stacking + fit_bins_to_grid, try_array from .plotter import Plotter from .particle_tracker import ParticleTracker from .data_reader.params_reader import read_openPMD_params @@ -538,10 +538,10 @@ def iterate( self, called_method, *args, **kwargs ): timeseries, with the arguments `*args` and `*kwargs`. The result of these calls is returned as a list, or, whenever possible - as a stacked array, where the first axis corresponds to the iterations. + as an array, where the first axis corresponds to the iterations. - If `called_method` returns a tuple, then `iterate` returns a - tuple of lists (or stacked arrays). + If `called_method` returns a tuple/list, then `iterate` returns a + tuple/list of lists (or arrays). Parameters ---------- @@ -554,32 +554,36 @@ def iterate( self, called_method, *args, **kwargs ): # Check the shape of results result = called_method(*args, **kwargs) - if type( result ) in [tuple, list]: - returns_tuple = True - tuple_length = len(result) - accumulated_result = list( [element] for element in result ) + result_type = type( result ) + if result_type in [tuple, list]: + returns_iterable = True + iterable_length = len(result) + accumulated_result = [ [element] for element in result ] else: - returns_tuple = False + returns_iterable = False accumulated_result = [ result ] # Call the method for all iterations for iteration in tqdm(self.iterations[1:]): kwargs['iteration'] = iteration result = called_method( *args, **kwargs ) - if returns_tuple: - for i in range(tuple_length): + if returns_iterable: + for i in range(iterable_length): accumulated_result[i].append( result[i] ) else: accumulated_result.append( result ) # Try to stack the arrays - if returns_tuple: - for i in range(tuple_length): - accumulated_result[i] = try_stacking( accumulated_result[i] ) + if returns_iterable: + for i in range(iterable_length): + accumulated_result[i] = try_array( accumulated_result[i] ) + if result_type == tuple: + return tuple(accumulated_result) + elif result_type == list: + return accumulated_result else: - accumulated_result = try_stacking( accumulated_result ) - - return accumulated_result + accumulated_result = try_array( accumulated_result ) + return accumulated_result def _find_output(self, t, iteration): """ diff --git a/opmd_viewer/openpmd_timeseries/utilities.py b/opmd_viewer/openpmd_timeseries/utilities.py index ff9c4b70..3637ad90 100644 --- a/opmd_viewer/openpmd_timeseries/utilities.py +++ b/opmd_viewer/openpmd_timeseries/utilities.py @@ -116,14 +116,17 @@ def apply_selection(file_handle, data_list, select, species, extensions): return(data_list) -def try_stacking( L ): +def try_array( L ): """ - Attempt to stack the elements of the list L in a single array. + Attempt to convert L to a single array. - This is done only if the elements of L are arrays of the same shape. + This is done only if the elements of L are scalars, + or arrays of the same shape. """ # Check that all element are arrays of the same shape - if all( type(x) is np.ndarray for x in L ) \ + if all( type(x) in [float, int] for x in L ): + return np.array( L ) + elif all( type(x) is np.ndarray for x in L ) \ and all( x.shape == L[0].shape for x in L ): # Stack the arrays return np.stack( L, axis=0 ) diff --git a/tutorials/5_Laser-plasma_tools.ipynb b/tutorials/5_Laser-plasma_tools.ipynb index 5bd37d44..90f4d7b1 100644 --- a/tutorials/5_Laser-plasma_tools.ipynb +++ b/tutorials/5_Laser-plasma_tools.ipynb @@ -107,7 +107,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "f12d46cae59e449dbd8380b8008bd803", + "model_id": "67d5ce646c1d4876bef42beb79f8bff7", "version_major": 2, "version_minor": 0 }, @@ -136,7 +136,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "372359273c9f47258b1bc0a8328bd267", + "model_id": "af69b5e03b634f54af65e3e2b67b6f86", "version_major": 2, "version_minor": 0 }, @@ -156,7 +156,7 @@ "

\n" ], "text/plain": [ - "HBox(children=(VBox(children=(Accordion(children=(VBox(children=(ToggleButtons(description='Field:', options=('E', 'rho'), style=ToggleButtonsStyle(button_width='initial'), value='E'), ToggleButtons(description='Coord:', options=('x', 'y', 'z'), style=ToggleButtonsStyle(button_width='initial'), value='x')), layout=Layout(width='330px')), VBox(children=(HBox(children=(HTML(value='Figure:', layout=Layout(width='50px')), IntText(value=0, layout=Layout(width='50px')))), VBox(children=(HBox(children=(HTML(value='Colorbar:'), Select(index=164, layout=Layout(width='200px'), options=('Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Vega10', 'Vega10_r', 'Vega20', 'Vega20_r', 'Vega20b', 'Vega20b_r', 'Vega20c', 'Vega20c_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'seismic', 'seismic_r', 'spectral', 'spectral_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'viridis', 'viridis_r', 'winter', 'winter_r'), value='viridis'))), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-5.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=5.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='x 10^', layout=Layout(width='45px')), FloatText(value=9.0, layout=Layout(width='45px'))))))), layout=Layout(width='310px')), VBox(children=(HTML(value='Vertical axis:'), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-10.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=10.0, layout=Layout(width='60px'))))), layout=Layout(width='310px')))), VBox(children=(HTML(value='Horizontal axis:'), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-10.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=10.0, layout=Layout(width='60px'))))), layout=Layout(width='310px'))))), layout=Layout(width='330px'))), _titles={'0': 'Field type', '1': 'Plotting options'}), HBox(children=(ToggleButton(value=True, description='Always refresh'), Button(description='Refresh now!', style=ButtonStyle())))), layout=Layout(width='370px')), VBox(children=(Accordion(children=(VBox(children=(Dropdown(layout=Layout(width='250px'), options=('Hydrogen1+', 'electrons'), value='Hydrogen1+'), ToggleButtons(options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w'), style=ToggleButtonsStyle(button_width='initial'), value='x'), ToggleButtons(index=7, options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w', 'None'), style=ToggleButtonsStyle(button_width='initial'), value='None')), layout=Layout(width='310px')), VBox(children=(HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), Dropdown(description='Select ', options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w'), value='x'))), HBox(children=(HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-0.1, layout=Layout(width='90px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=0.1, layout=Layout(width='90px')))))), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), Dropdown(description='Select ', options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w'), value='x'))), HBox(children=(HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-0.1, layout=Layout(width='90px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=0.1, layout=Layout(width='90px')))))), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), Dropdown(description='Select ', options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w'), value='x'))), HBox(children=(HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-0.1, layout=Layout(width='90px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=0.1, layout=Layout(width='90px'))))))), layout=Layout(width='310px')), VBox(children=(HBox(children=(HBox(children=(HTML(value='Figure:', layout=Layout(width='50px')), IntText(value=1, layout=Layout(width='50px')))), HBox(children=(HTML(value='Bins:', layout=Layout(width='50px')), IntText(value=100, layout=Layout(width='60px')))))), VBox(children=(HBox(children=(HTML(value='Colorbar:'), Select(index=2, layout=Layout(width='200px'), options=('Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Vega10', 'Vega10_r', 'Vega20', 'Vega20_r', 'Vega20b', 'Vega20b_r', 'Vega20c', 'Vega20c_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'seismic', 'seismic_r', 'spectral', 'spectral_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'viridis', 'viridis_r', 'winter', 'winter_r'), value='Blues'))), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-5.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=5.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='x 10^', layout=Layout(width='45px')), FloatText(value=9.0, layout=Layout(width='45px'))))))), layout=Layout(width='310px')), VBox(children=(HTML(value='Vertical axis:'), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-10.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=10.0, layout=Layout(width='60px'))))), layout=Layout(width='310px')))), VBox(children=(HTML(value='Horizontal axis:'), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-10.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=10.0, layout=Layout(width='60px'))))), layout=Layout(width='310px')))), ToggleButton(value=True, description=' Use field mesh')), layout=Layout(width='310px'))), _titles={'0': 'Particle quantities', '1': 'Particle selection', '2': 'Plotting options'}), HBox(children=(ToggleButton(value=True, description='Always refresh'), Button(description='Refresh now!', style=ButtonStyle())))), layout=Layout(width='370px'))))" + "HBox(children=(VBox(children=(Accordion(children=(VBox(children=(ToggleButtons(description='Field:', options=('E', 'rho'), style=ToggleButtonsStyle(button_width='initial'), value='E'), ToggleButtons(description='Coord:', options=('x', 'y', 'z'), style=ToggleButtonsStyle(button_width='initial'), value='x'), ToggleButtons(description='Slice normal:', options=('None', 'x', 'z'), style=ToggleButtonsStyle(button_width='initial'), value='None'), HBox(children=(HTML(value='Slicing:', layout=Layout(width='50px')), FloatSlider(value=0.0, layout=Layout(width='180px'), max=1.0, min=-1.0)))), layout=Layout(width='330px')), VBox(children=(HBox(children=(HTML(value='Figure:', layout=Layout(width='50px')), IntText(value=0, layout=Layout(width='50px')))), VBox(children=(HBox(children=(HTML(value='Colorbar:'), Select(index=164, layout=Layout(width='200px'), options=('Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Vega10', 'Vega10_r', 'Vega20', 'Vega20_r', 'Vega20b', 'Vega20b_r', 'Vega20c', 'Vega20c_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'seismic', 'seismic_r', 'spectral', 'spectral_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'viridis', 'viridis_r', 'winter', 'winter_r'), value='viridis'))), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-5.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=5.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='x 10^', layout=Layout(width='45px')), FloatText(value=9.0, layout=Layout(width='45px'))))))), layout=Layout(width='310px')), VBox(children=(HTML(value='Vertical axis:'), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-10.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=10.0, layout=Layout(width='60px'))))), layout=Layout(width='310px')))), VBox(children=(HTML(value='Horizontal axis:'), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-10.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=10.0, layout=Layout(width='60px'))))), layout=Layout(width='310px'))))), layout=Layout(width='330px'))), _titles={'0': 'Field type', '1': 'Plotting options'}), HBox(children=(ToggleButton(value=True, description='Always refresh'), Button(description='Refresh now!', style=ButtonStyle())))), layout=Layout(width='370px')), VBox(children=(Accordion(children=(VBox(children=(Dropdown(layout=Layout(width='250px'), options=('Hydrogen1+', 'electrons'), value='Hydrogen1+'), ToggleButtons(options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w'), style=ToggleButtonsStyle(button_width='initial'), value='x'), ToggleButtons(index=7, options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w', 'None'), style=ToggleButtonsStyle(button_width='initial'), value='None')), layout=Layout(width='310px')), VBox(children=(HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), Dropdown(description='Select ', options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w'), value='x'))), HBox(children=(HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-0.1, layout=Layout(width='90px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=0.1, layout=Layout(width='90px')))))), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), Dropdown(description='Select ', options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w'), value='x'))), HBox(children=(HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-0.1, layout=Layout(width='90px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=0.1, layout=Layout(width='90px')))))), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), Dropdown(description='Select ', options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w'), value='x'))), HBox(children=(HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-0.1, layout=Layout(width='90px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=0.1, layout=Layout(width='90px'))))))), layout=Layout(width='310px')), VBox(children=(HBox(children=(HBox(children=(HTML(value='Figure:', layout=Layout(width='50px')), IntText(value=1, layout=Layout(width='50px')))), HBox(children=(HTML(value='Bins:', layout=Layout(width='50px')), IntText(value=100, layout=Layout(width='60px')))))), VBox(children=(HBox(children=(HTML(value='Colorbar:'), Select(index=2, layout=Layout(width='200px'), options=('Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Vega10', 'Vega10_r', 'Vega20', 'Vega20_r', 'Vega20b', 'Vega20b_r', 'Vega20c', 'Vega20c_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'seismic', 'seismic_r', 'spectral', 'spectral_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'viridis', 'viridis_r', 'winter', 'winter_r'), value='Blues'))), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-5.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=5.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='x 10^', layout=Layout(width='45px')), FloatText(value=9.0, layout=Layout(width='45px'))))))), layout=Layout(width='310px')), VBox(children=(HTML(value='Vertical axis:'), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-10.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=10.0, layout=Layout(width='60px'))))), layout=Layout(width='310px')))), VBox(children=(HTML(value='Horizontal axis:'), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-10.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=10.0, layout=Layout(width='60px'))))), layout=Layout(width='310px')))), ToggleButton(value=True, description=' Use field mesh')), layout=Layout(width='310px'))), _titles={'0': 'Particle quantities', '1': 'Particle selection', '2': 'Plotting options'}), HBox(children=(ToggleButton(value=True, description='Always refresh'), Button(description='Refresh now!', style=ButtonStyle())))), layout=Layout(width='370px'))))" ] }, "metadata": {}, @@ -214,8 +214,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Mean gamma\n", - "To calculate the mean energy and standard deviation of the selected particles `get_mean_gamma` can be used. In the example below, only the particles with $u_z > 0.05$ are selected." + "#### Charge\n", + "`get_charge` calculates the charge of the given particle selection in Coulomb." ] }, { @@ -226,7 +226,7 @@ { "data": { "text/plain": [ - "(1.0665548693800455, 0.10151101005407513)" + "-0.0023057475697829941" ] }, "execution_count": 7, @@ -235,15 +235,14 @@ } ], "source": [ - "ts_2d.get_mean_gamma(iteration=300, species='electrons', select={'uz' : [0.05, None]})" + "ts_2d.get_charge(iteration=300, species='electrons')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### Charge\n", - "`get_charge` calculates the charge of the given particle selection in Coulomb." + "Note that the evolution of the charge (or of any of the quantities below) can be easily obtained with `ts.iterate`:" ] }, { @@ -251,10 +250,46 @@ "execution_count": 8, "metadata": {}, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 29/29 [00:00<00:00, 360.08it/s]\n" + ] + }, { "data": { "text/plain": [ - "-0.0023057475697829941" + "[-0.0021049319607583184,\n", + " -0.0021403572862428925,\n", + " -0.0021556829061753998,\n", + " -0.0021817763542571313,\n", + " -0.0022063677618091746,\n", + " -0.0022291579223580171,\n", + " -0.0022504196064638497,\n", + " -0.0022704808597783558,\n", + " -0.0022887024138521007,\n", + " -0.0023057475697829941,\n", + " -0.0023212906851842003,\n", + " -0.002334958052371933,\n", + " -0.002347099346381503,\n", + " -0.0023565213462161264,\n", + " -0.0023659842015531576,\n", + " -0.0023739450163605012,\n", + " -0.0023792321990250011,\n", + " -0.0023844893408789076,\n", + " -0.002388244442203126,\n", + " -0.0023904975029976575,\n", + " -0.0023907678702930011,\n", + " -0.0023667352218180011,\n", + " -0.0023366944112242511,\n", + " -0.0023066536006305012,\n", + " -0.002277093443006251,\n", + " -0.0022470526324125011,\n", + " -0.0022170118218187511,\n", + " -0.0021869710112250012,\n", + " -0.0021569302006312508,\n", + " -0.0021268893900375013]" ] }, "execution_count": 8, @@ -263,7 +298,35 @@ } ], "source": [ - "ts_2d.get_charge(iteration=300, species='electrons')" + "ts_2d.iterate( ts_2d.get_charge, species='electrons' )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Mean gamma\n", + "To calculate the mean energy and standard deviation of the selected particles `get_mean_gamma` can be used. In the example below, only the particles with $u_z > 0.05$ are selected." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1.0665548693800455, 0.10151101005407513)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ts_2d.get_mean_gamma(iteration=300, species='electrons', select={'uz' : [0.05, None]})" ] }, { @@ -276,7 +339,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -285,7 +348,7 @@ "(1.3080546184771431, 1.5751303670998404)" ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -305,16 +368,16 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(1.1078612528297555e-07, 1.6065235739504965e-09)" + "(1.1078612528297555e-07, 1.6064831448020442e-09)" ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -333,14 +396,14 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -370,7 +433,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -387,14 +450,14 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -422,14 +485,14 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -450,7 +513,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -459,7 +522,7 @@ "2354564459136067.0" ] }, - "execution_count": 15, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -478,7 +541,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -487,7 +550,7 @@ "1.0542688340645183" ] }, - "execution_count": 16, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -507,7 +570,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -524,7 +587,7 @@ "4.1474107457732672e-06" ] }, - "execution_count": 17, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -543,7 +606,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -552,7 +615,7 @@ "2.9493466667473121e-06" ] }, - "execution_count": 18, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } From dfa1acb77e88b917cbabbdb5199e8e474ca43665 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Fri, 25 May 2018 07:54:57 -0700 Subject: [PATCH 40/90] Fix array stacking --- opmd_viewer/openpmd_timeseries/utilities.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/utilities.py b/opmd_viewer/openpmd_timeseries/utilities.py index 3637ad90..a0fe7f3a 100644 --- a/opmd_viewer/openpmd_timeseries/utilities.py +++ b/opmd_viewer/openpmd_timeseries/utilities.py @@ -119,18 +119,11 @@ def apply_selection(file_handle, data_list, select, species, extensions): def try_array( L ): """ Attempt to convert L to a single array. - - This is done only if the elements of L are scalars, - or arrays of the same shape. """ - # Check that all element are arrays of the same shape - if all( type(x) in [float, int] for x in L ): - return np.array( L ) - elif all( type(x) is np.ndarray for x in L ) \ - and all( x.shape == L[0].shape for x in L ): + try: # Stack the arrays return np.stack( L, axis=0 ) - else: + except ValueError: # Do not stack return L From d58c8cbe152610c8758e6a96ab9de902c6dad610 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sat, 26 May 2018 08:28:35 -0700 Subject: [PATCH 41/90] Remove microns and femtoseconds --- opmd_viewer/addons/pic/lpa_diagnostics.py | 68 +++++++++---------- .../data_reader/particle_reader.py | 5 +- opmd_viewer/openpmd_timeseries/main.py | 3 +- .../openpmd_timeseries/particle_tracker.py | 2 +- opmd_viewer/openpmd_timeseries/plotter.py | 44 ++++++------ opmd_viewer/openpmd_timeseries/utilities.py | 10 +-- 6 files changed, 62 insertions(+), 70 deletions(-) diff --git a/opmd_viewer/addons/pic/lpa_diagnostics.py b/opmd_viewer/addons/pic/lpa_diagnostics.py index 299b9f90..a90f9fdc 100644 --- a/opmd_viewer/addons/pic/lpa_diagnostics.py +++ b/opmd_viewer/addons/pic/lpa_diagnostics.py @@ -69,8 +69,8 @@ def get_mean_gamma( self, t=None, iteration=None, species=None, select : dict, optional Either None or a dictionary of rules to select the particles, of the form - 'x' : [-4., 10.] (Particles having x between -4 and 10 microns) - 'z' : [0, 100] (Particles having x between 0 and 100 microns) + 'x' : [-4., 10.] (Particles having x between -4 and 10) + 'z' : [0, 100] (Particles having x between 0 and 100) Returns ------- @@ -122,8 +122,8 @@ def get_sigma_gamma_slice(self, dz, t=None, iteration=None, species=None, select : dict, optional Either None or a dictionary of rules to select the particles, of the form - 'x' : [-4., 10.] (Particles having x between -4 and 10 microns) - 'z' : [0, 100] (Particles having x between 0 and 100 microns) + 'x' : [-4., 10.] (Particles having x between -4 and 10) + 'z' : [0, 100] (Particles having x between 0 and 100) plot : bool, optional Whether to plot the requested quantity @@ -160,12 +160,12 @@ def get_sigma_gamma_slice(self, dz, t=None, iteration=None, species=None, if plot: check_matplotlib() iteration = self.iterations[ self._current_i ] - time_fs = 1.e15 * self.t[ self._current_i ] + time = self.t[ self._current_i ] plt.plot(z_pos, spreads, **kw) - plt.title("Slice energy spread at %.1f fs (iteration %d)" - % (time_fs, iteration), fontsize=self.plotter.fontsize) - plt.xlabel('$z \;(\mu m)$', fontsize=self.plotter.fontsize) - plt.ylabel('$\sigma_\gamma (\Delta_z=%s\mu m)$' % dz, + plt.title("Slice energy spread at %.1f s (iteration %d)" + % (time, iteration), fontsize=self.plotter.fontsize) + plt.xlabel('$z \;(m)$', fontsize=self.plotter.fontsize) + plt.ylabel('$\sigma_\gamma (\Delta_z=%s m)$' % dz, fontsize=self.plotter.fontsize) return(spreads, z_pos) @@ -190,8 +190,8 @@ def get_charge( self, t=None, iteration=None, species=None, select=None ): select : dict, optional Either None or a dictionary of rules to select the particles, of the form - 'x' : [-4., 10.] (Particles having x between -4 and 10 microns) - 'z' : [0, 100] (Particles having x between 0 and 100 microns) + 'x' : [-4., 10.] (Particles having x between -4 and 10) + 'z' : [0, 100] (Particles having x between 0 and 100) Returns ------- @@ -227,8 +227,8 @@ def get_divergence( self, t=None, iteration=None, species=None, select : dict, optional Either None or a dictionary of rules to select the particles, of the form - 'x' : [-4., 10.] (Particles having x between -4 and 10 microns) - 'z' : [0, 100] (Particles having x between 0 and 100 microns) + 'x' : [-4., 10.] (Particles having x between -4 and 10) + 'z' : [0, 100] (Particles having x between 0 and 100) Returns ------- @@ -270,8 +270,8 @@ def get_emittance(self, t=None, iteration=None, species=None, select : dict, optional Either None or a dictionary of rules to select the particles, of the form: - 'x' : [-4., 10.] (Particles having x between -4 and 10 microns); - 'z' : [0, 100] (Particles having x between 0 and 100 microns). + 'x' : [-4., 10.] (Particles having x between -4 and 10); + 'z' : [0, 100] (Particles having x between 0 and 100). kind : string, optional Kind of emittance to be computed. Can be 'normalized' or 'trace'. @@ -386,8 +386,8 @@ def get_current( self, t=None, iteration=None, species=None, select=None, select : dict, optional Either None or a dictionary of rules to select the particles, of the form - 'x' : [-4., 10.] (Particles having x between -4 and 10 microns) - 'z' : [0, 100] (Particles having x between 0 and 100 microns) + 'x' : [-4., 10.] (Particles having x between -4 and 10) + 'z' : [0, 100] (Particles having x between 0 and 100) bins : int, optional Number of bins along the z-axis in which to calculate the current @@ -427,11 +427,11 @@ def get_current( self, t=None, iteration=None, species=None, select=None, if plot: check_matplotlib() iteration = self.iterations[ self._current_i ] - time_fs = 1.e15 * self.t[ self._current_i ] + time = self.t[ self._current_i ] plt.plot( info.z, current, **kw) - plt.title("Current at %.1f fs (iteration %d)" - % (time_fs, iteration ), fontsize=self.plotter.fontsize) - plt.xlabel('$z \;(\mu m)$', fontsize=self.plotter.fontsize) + plt.title("Current at %.1f s (iteration %d)" + % (time, iteration ), fontsize=self.plotter.fontsize) + plt.xlabel('$z \;(m)$', fontsize=self.plotter.fontsize) plt.ylabel('$I \;(A)$', fontsize=self.plotter.fontsize) # Return the current and bin centers return(current, info) @@ -536,20 +536,20 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', if plot: check_matplotlib() iteration = self.iterations[ self._current_i ] - time_fs = 1.e15 * self.t[ self._current_i ] + time = self.t[ self._current_i ] if index != 'all': - plt.plot( 1.e6 * info.z, envelope, **kw) + plt.plot( info.z, envelope, **kw) plt.ylabel('$E_%s \;(V/m)$' % pol, fontsize=self.plotter.fontsize) else: - plt.imshow( envelope, extent=1.e6 * info.imshow_extent, + plt.imshow( envelope, extent=info.imshow_extent, aspect='auto', **kw) plt.colorbar() - plt.ylabel('$%s \;(\mu m)$' % pol, + plt.ylabel('$%s \;(m)$' % pol, fontsize=self.plotter.fontsize) - plt.title("Laser envelope at %.1f fs (iteration %d)" - % (time_fs, iteration ), fontsize=self.plotter.fontsize) - plt.xlabel('$z \;(\mu m)$', fontsize=self.plotter.fontsize) + plt.title("Laser envelope at %.1f s (iteration %d)" + % (time, iteration ), fontsize=self.plotter.fontsize) + plt.xlabel('$z \;(m)$', fontsize=self.plotter.fontsize) # Return the result return( envelope, info ) @@ -743,13 +743,13 @@ def get_spectrum( self, t=None, iteration=None, pol=None, if plot: check_matplotlib() iteration = self.iterations[ self._current_i ] - time_fs = 1.e15 * self.t[ self._current_i ] + time = self.t[ self._current_i ] plt.plot( spect_info.omega, spectrum, **kw ) plt.xlabel('$\omega \; (rad.s^{-1})$', fontsize=self.plotter.fontsize ) plt.ylabel('Spectrum', fontsize=self.plotter.fontsize ) - plt.title("Spectrum at %.1f fs (iteration %d)" - % (time_fs, iteration ), fontsize=self.plotter.fontsize) + plt.title("Spectrum at %.1f s (iteration %d)" + % (time, iteration ), fontsize=self.plotter.fontsize) return( spectrum, spect_info ) def get_a0( self, t=None, iteration=None, pol=None ): @@ -1037,11 +1037,11 @@ def get_spectrogram( self, t=None, iteration=None, pol=None, theta=0, if plot: check_matplotlib() iteration = self.iterations[ self._current_i ] - time_fs = 1.e15 * self.t[ self._current_i ] + time = self.t[ self._current_i ] plt.imshow( spectrogram, extent=info.imshow_extent, aspect='auto', **kw) - plt.title("Spectrogram at %.1f fs (iteration %d)" - % (time_fs, iteration ), fontsize=self.plotter.fontsize) + plt.title("Spectrogram at %.1f s (iteration %d)" + % (time, iteration ), fontsize=self.plotter.fontsize) plt.xlabel('$t \;(s)$', fontsize=self.plotter.fontsize ) plt.ylabel('$\omega \;(rad.s^{-1})$', fontsize=self.plotter.fontsize ) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/particle_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/particle_reader.py index 0ecf9f6f..85afcd4e 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/particle_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/particle_reader.py @@ -18,8 +18,6 @@ def read_species_data(file_handle, species, record_comp, extensions): """ Extract a given species' record_comp - In the case of positions, the result is returned in microns - Parameters ---------- file_handle: h5py.File object @@ -73,11 +71,10 @@ def read_species_data(file_handle, species, record_comp, extensions): w = get_data( species_grp[ 'weighting' ] ) data *= w ** (-weighting_power) - # - Return positions in microns, with an offset + # - Return positions, with an offset if record_comp in ['x', 'y', 'z']: offset = get_data(species_grp['positionOffset/%s' % record_comp]) data += offset - data *= 1.e6 # - Return momentum in normalized units elif record_comp in ['ux', 'uy', 'uz' ]: m = get_data(species_grp['mass']) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index df8e8a00..a61e68ec 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -124,7 +124,6 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, If two quantities are requested by the user, this plots a 2d histogram of these quantities. - In the case of positions, the result is returned in microns In the case of momenta, the result is returned as: - unitless momentum (i.e. gamma*beta) for particles with non-zero mass - in kg.m.s^-1 for particles with zero mass @@ -154,7 +153,7 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, select: dict or ParticleTracker object, optional - If `select` is a dictionary: then it lists a set of rules to select the particles, of the form - 'x' : [-4., 10.] (Particles having x between -4 and 10 microns) + 'x' : [-4., 10.] (Particles having x between -4 and 10) 'ux' : [-0.1, 0.1] (Particles having ux between -0.1 and 0.1 mc) 'uz' : [5., None] (Particles with uz above 5 mc) - If `select` is a ParticleTracker object: diff --git a/opmd_viewer/openpmd_timeseries/particle_tracker.py b/opmd_viewer/openpmd_timeseries/particle_tracker.py index 868bc5e1..7aa5dfd7 100644 --- a/opmd_viewer/openpmd_timeseries/particle_tracker.py +++ b/opmd_viewer/openpmd_timeseries/particle_tracker.py @@ -73,7 +73,7 @@ def __init__(self, ts, species=None, t=None, select: dict, optional Either None or a dictionary of rules to select the particles, of the form - 'x' : [-4., 10.] (Particles having x between -4 and 10 microns) + 'x' : [-4., 10.] (Particles having x between -4 and 10) 'ux' : [-0.1, 0.1] (Particles having ux between -0.1 and 0.1 mc) 'uz' : [5., None] (Particles with uz above 5 mc) diff --git a/opmd_viewer/openpmd_timeseries/plotter.py b/opmd_viewer/openpmd_timeseries/plotter.py index 15af43dd..baadf135 100644 --- a/opmd_viewer/openpmd_timeseries/plotter.py +++ b/opmd_viewer/openpmd_timeseries/plotter.py @@ -95,7 +95,7 @@ def hist1d(self, q1, w, quantity1, species, current_i, nbins, hist_range, # Find the iteration and time iteration = self.iterations[current_i] - time_fs = 1.e15 * self.t[current_i] + time = self.t[current_i] # Check deposition method if deposition == 'cic' and not cython_function_available: @@ -119,8 +119,8 @@ def hist1d(self, q1, w, quantity1, species, current_i, nbins, hist_range, plt.xlim( hist_range[0] ) plt.ylim( hist_range[1] ) plt.xlabel(quantity1, fontsize=self.fontsize) - plt.title("%s: t = %.0f fs (iteration %d)" - % (species, time_fs, iteration), fontsize=self.fontsize) + plt.title("%s: t = %.0f s (iteration %d)" + % (species, time, iteration), fontsize=self.fontsize) def hist2d(self, q1, q2, w, quantity1, quantity2, species, current_i, nbins, hist_range, cmap='Blues', vmin=None, vmax=None, @@ -168,7 +168,7 @@ def hist2d(self, q1, q2, w, quantity1, quantity2, species, current_i, # Find the iteration and time iteration = self.iterations[current_i] - time_fs = 1.e15 * self.t[current_i] + time = self.t[current_i] # Check deposition method if deposition == 'cic' and not cython_function_available: @@ -195,8 +195,8 @@ def hist2d(self, q1, q2, w, quantity1, quantity2, species, current_i, plt.colorbar() plt.xlabel(quantity1, fontsize=self.fontsize) plt.ylabel(quantity2, fontsize=self.fontsize) - plt.title("%s: t = %.1f fs (iteration %d)" - % (species, time_fs, iteration), fontsize=self.fontsize) + plt.title("%s: t = %.1f s (iteration %d)" + % (species, time, iteration), fontsize=self.fontsize) def show_field_1d( self, F, info, field_label, current_i, plot_range, vmin=None, vmax=None, **kw ): @@ -226,16 +226,16 @@ def show_field_1d( self, F, info, field_label, current_i, plot_range, # Find the iteration and time iteration = self.iterations[current_i] - time_fs = 1.e15 * self.t[current_i] + time = self.t[current_i] # Get the title and labels - plt.title("%s at %.1f fs (iteration %d)" - % (field_label, time_fs, iteration), fontsize=self.fontsize) + plt.title("%s at %.1f s (iteration %d)" % (field_label, + time, iteration), fontsize=self.fontsize) # Add the name of the axes - plt.xlabel('$%s \;(\mu m)$' % info.axes[0], fontsize=self.fontsize) - # Get the x axis in microns - xaxis = 1.e6 * getattr( info, info.axes[0] ) + plt.xlabel('$%s \;(m)$' % info.axes[0], fontsize=self.fontsize) + # Get the x axis + xaxis = getattr( info, info.axes[0] ) # Plot the data plt.plot( xaxis, F ) # Get the limits of the plot @@ -284,33 +284,33 @@ def show_field_2d(self, F, info, slicing_dir, m, field_label, geometry, # Find the iteration and time iteration = self.iterations[current_i] - time_fs = 1.e15 * self.t[current_i] + time = self.t[current_i] # Get the title and labels # Cylindrical geometry if geometry == "thetaMode": mode = str(m) - plt.title("%s in the mode %s at %.1f fs (iteration %d)" - % (field_label, mode, time_fs, iteration), + plt.title("%s in the mode %s at %.1f s (iteration %d)" + % (field_label, mode, time, iteration), fontsize=self.fontsize) # 2D Cartesian geometry elif geometry == "2dcartesian": - plt.title("%s at %.1f fs (iteration %d)" - % (field_label, time_fs, iteration), + plt.title("%s at %.1f s (iteration %d)" + % (field_label, time, iteration), fontsize=self.fontsize) # 3D Cartesian geometry elif geometry == "3dcartesian": slice_plane = info.axes[0] + '-' + info.axes[1] - plt.title("%s sliced in %s at %.1f fs (iteration %d)" - % (field_label, slice_plane, time_fs, iteration), + plt.title("%s sliced in %s at %.1f s (iteration %d)" + % (field_label, slice_plane, time, iteration), fontsize=self.fontsize) # Add the name of the axes - plt.xlabel('$%s \;(\mu m)$' % info.axes[1], fontsize=self.fontsize) - plt.ylabel('$%s \;(\mu m)$' % info.axes[0], fontsize=self.fontsize) + plt.xlabel('$%s \;(m)$' % info.axes[1], fontsize=self.fontsize) + plt.ylabel('$%s \;(m)$' % info.axes[0], fontsize=self.fontsize) # Plot the data - plt.imshow(F, extent=1.e6 * info.imshow_extent, origin='lower', + plt.imshow(F, extent=info.imshow_extent, origin='lower', interpolation='nearest', aspect='auto', **kw) plt.colorbar() diff --git a/opmd_viewer/openpmd_timeseries/utilities.py b/opmd_viewer/openpmd_timeseries/utilities.py index a0fe7f3a..c2052b28 100644 --- a/opmd_viewer/openpmd_timeseries/utilities.py +++ b/opmd_viewer/openpmd_timeseries/utilities.py @@ -74,7 +74,7 @@ def apply_selection(file_handle, data_list, select, species, extensions): select: dict A dictionary of rules to select the particles - 'x' : [-4., 10.] (Particles having x between -4 and 10 microns) + 'x' : [-4., 10.] (Particles having x between -4 and 10) 'ux' : [-0.1, 0.1] (Particles having ux between -0.1 and 0.1 mc) 'uz' : [5., None] (Particles with uz above 5 mc) @@ -143,7 +143,7 @@ def fit_bins_to_grid( hist_size, grid_size, grid_range ): grid_size: integer The number of cells in the grid - grid_range: list of floats (in meters) + grid_range: list of floats (in) The extent of the grid Returns: @@ -151,7 +151,7 @@ def fit_bins_to_grid( hist_size, grid_size, grid_range ): hist_size: integer The new number of bins - hist_range: list of floats (in microns) + hist_range: list of floats The new range of the histogram """ # The new histogram range is the same as the grid range @@ -173,8 +173,4 @@ def fit_bins_to_grid( hist_size, grid_size, grid_range ): hist_size = int( ( hist_range[1] - hist_range[0] ) / hist_spacing ) hist_range[1] = hist_range[0] + hist_size * hist_spacing - # Convert the range to microns (since this is how particle positions - # are returned in the openPMD-viewer) - hist_range = [ 1.e6 * hist_range[0], 1.e6 * hist_range[1] ] - return( hist_size, hist_range ) From 6043fe5364484238b0875924bae2953636595302 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sat, 26 May 2018 08:50:52 -0700 Subject: [PATCH 42/90] Correct particle selection in tutorial notebooks --- tutorials/4_Particle_selection.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorials/4_Particle_selection.ipynb b/tutorials/4_Particle_selection.ipynb index 17a492f5..c8b81e7b 100644 --- a/tutorials/4_Particle_selection.ipynb +++ b/tutorials/4_Particle_selection.ipynb @@ -172,7 +172,7 @@ "# Select only particles that have uz between 0.05 and 0.2 AND z between 22 and 26\n", "# and plot them as green dots, on top of the phase space\n", "z_selected, uz_selected = ts.get_particle( ['z', 'uz'], species='electrons', \n", - " iteration=300, select={'uz':[0.05, 0.2], 'z':[22,26]} )\n", + " iteration=300, select={'uz':[0.05, 0.2], 'z':[22e-6,26e-6]} )\n", "plt.plot(z_selected, uz_selected, 'g.')" ] }, @@ -197,7 +197,7 @@ "source": [ "from opmd_viewer import ParticleTracker\n", "# Select particles to be tracked, at iteration 300\n", - "pt = ParticleTracker( ts, iteration=300, select={'uz':[0.05,0.2], 'z':[22,26]}, species='electrons' )" + "pt = ParticleTracker( ts, iteration=300, select={'uz':[0.05,0.2], 'z':[22e-6,26e-6]}, species='electrons' )" ] }, { @@ -305,7 +305,7 @@ "metadata": {}, "outputs": [], "source": [ - "pt = ParticleTracker( ts, iteration=300, select={'uz':[0.05,0.1], 'z':[22,26]}, \n", + "pt = ParticleTracker( ts, iteration=300, select={'uz':[0.05,0.1], 'z':[22e-6,26e-6]}, \n", " species='electrons', preserve_particle_index=True )" ] }, From d94d34223e8232259f32bcc0182ac427bc97e493 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sat, 26 May 2018 09:02:18 -0700 Subject: [PATCH 43/90] Add better tick formatter --- opmd_viewer/openpmd_timeseries/plotter.py | 63 ++++++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/plotter.py b/opmd_viewer/openpmd_timeseries/plotter.py index baadf135..838c0813 100644 --- a/opmd_viewer/openpmd_timeseries/plotter.py +++ b/opmd_viewer/openpmd_timeseries/plotter.py @@ -22,6 +22,46 @@ except ImportError: cython_function_available = False +# Redefine the default matplotlib formatter for ticks +if matplotlib_installed: + from matplotlib.ticker import ScalarFormatter + + class MyFormatter( ScalarFormatter ): + """ + # TODO + """ + def __init__( self, *args, **kwargs ): + mticker.ScalarFormatter.__init__( self, *args, **kwargs ) + self.set_scientific(False) + self._offset_threshold = 2 + + def pprint_val( self, x, pos=None ): + """ + # TODO + """ + xp = (x - self.offset) + if xp != 0: + log_x = 3*math.floor( math.log10(abs(xp))/3 ) + else: + log_x = 0 + # Show 2 digits at most after decimal point + mantissa = round( xp*10**(-log_x), 3) + if mantissa !=0 and math.log10(abs(mantissa)) == 3: + log_x += 3 + mantissa /= 1000 + string = "{:.3f}".format( mantissa ) + # Limit the string to 3 digits + string = string[:5] + if '.' in string: + # Remove trailing zeros and ., for integer mantissa + string = string.rstrip('0') + string = string.rstrip('.') + if log_x != 0: + string += "e{:d}".format( log_x ) + return string + + tick_formatter = MyFormatter() + class Plotter(object): @@ -116,11 +156,16 @@ def hist1d(self, q1, w, quantity1, species, current_i, nbins, hist_range, bin_size = (hist_range[0][1] - hist_range[0][0]) / nbins bin_coords = hist_range[0][0] + bin_size * ( 0.5 + np.arange(nbins) ) plt.bar( bin_coords, binned_data, width=bin_size, **kw ) - plt.xlim( hist_range[0] ) - plt.ylim( hist_range[1] ) + plt.set_xlim( hist_range[0] ) + plt.set_ylim( hist_range[1] ) plt.xlabel(quantity1, fontsize=self.fontsize) plt.title("%s: t = %.0f s (iteration %d)" % (species, time, iteration), fontsize=self.fontsize) + # Format the ticks + ax = plt.gca() + ax.get_xaxis().set_major_formatter( tick_formatter ) + ax.get_yaxis().set_major_formatter( tick_formatter ) + def hist2d(self, q1, q2, w, quantity1, quantity2, species, current_i, nbins, hist_range, cmap='Blues', vmin=None, vmax=None, @@ -197,6 +242,11 @@ def hist2d(self, q1, q2, w, quantity1, quantity2, species, current_i, plt.ylabel(quantity2, fontsize=self.fontsize) plt.title("%s: t = %.1f s (iteration %d)" % (species, time, iteration), fontsize=self.fontsize) + # Format the ticks + ax = plt.gca() + ax.get_xaxis().set_major_formatter( tick_formatter ) + ax.get_yaxis().set_major_formatter( tick_formatter ) + def show_field_1d( self, F, info, field_label, current_i, plot_range, vmin=None, vmax=None, **kw ): @@ -247,6 +297,11 @@ def show_field_1d( self, F, info, field_label, current_i, plot_range, # - Along the second dimension if (plot_range[1][0] is not None) and (plot_range[1][1] is not None): plt.ylim( plot_range[1][0], plot_range[1][1] ) + # Format the ticks + ax = plt.gca() + ax.get_xaxis().set_major_formatter( tick_formatter ) + ax.get_yaxis().set_major_formatter( tick_formatter ) + def show_field_2d(self, F, info, slicing_dir, m, field_label, geometry, current_i, plot_range, **kw): @@ -321,6 +376,10 @@ def show_field_2d(self, F, info, slicing_dir, m, field_label, geometry, # - Along the second dimension if (plot_range[1][0] is not None) and (plot_range[1][1] is not None): plt.ylim( plot_range[1][0], plot_range[1][1] ) + # Format the ticks + ax = plt.gca() + ax.get_xaxis().set_major_formatter( tick_formatter ) + ax.get_yaxis().set_major_formatter( tick_formatter ) def print_cic_unavailable(): From 00aa363dd243224fa0eff73f68d600868adf32bd Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sat, 26 May 2018 09:19:31 -0700 Subject: [PATCH 44/90] Add better tick formatting --- opmd_viewer/openpmd_timeseries/plotter.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/plotter.py b/opmd_viewer/openpmd_timeseries/plotter.py index 838c0813..17838d9e 100644 --- a/opmd_viewer/openpmd_timeseries/plotter.py +++ b/opmd_viewer/openpmd_timeseries/plotter.py @@ -9,6 +9,7 @@ License: 3-Clause-BSD-LBNL """ import numpy as np +import math try: import warnings import matplotlib @@ -31,7 +32,7 @@ class MyFormatter( ScalarFormatter ): # TODO """ def __init__( self, *args, **kwargs ): - mticker.ScalarFormatter.__init__( self, *args, **kwargs ) + ScalarFormatter.__init__( self, *args, **kwargs ) self.set_scientific(False) self._offset_threshold = 2 @@ -156,8 +157,8 @@ def hist1d(self, q1, w, quantity1, species, current_i, nbins, hist_range, bin_size = (hist_range[0][1] - hist_range[0][0]) / nbins bin_coords = hist_range[0][0] + bin_size * ( 0.5 + np.arange(nbins) ) plt.bar( bin_coords, binned_data, width=bin_size, **kw ) - plt.set_xlim( hist_range[0] ) - plt.set_ylim( hist_range[1] ) + plt.xlim( hist_range[0] ) + plt.ylim( hist_range[1] ) plt.xlabel(quantity1, fontsize=self.fontsize) plt.title("%s: t = %.0f s (iteration %d)" % (species, time, iteration), fontsize=self.fontsize) From 6442ac8de7fcef0f1a3ce62fee8b28c12a2e9982 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Mon, 28 May 2018 08:29:56 -0700 Subject: [PATCH 45/90] Take into account review comments --- opmd_viewer/addons/pic/lpa_diagnostics.py | 44 +++++++++++------------ opmd_viewer/openpmd_timeseries/main.py | 2 +- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/opmd_viewer/addons/pic/lpa_diagnostics.py b/opmd_viewer/addons/pic/lpa_diagnostics.py index a90f9fdc..47a1d54d 100644 --- a/opmd_viewer/addons/pic/lpa_diagnostics.py +++ b/opmd_viewer/addons/pic/lpa_diagnostics.py @@ -69,8 +69,8 @@ def get_mean_gamma( self, t=None, iteration=None, species=None, select : dict, optional Either None or a dictionary of rules to select the particles, of the form - 'x' : [-4., 10.] (Particles having x between -4 and 10) - 'z' : [0, 100] (Particles having x between 0 and 100) + 'x' : [-4., 10.] (Particles having x between -4 and 10 meters) + 'z' : [0, 100] (Particles having z between 0 and 100 meters) Returns ------- @@ -122,8 +122,8 @@ def get_sigma_gamma_slice(self, dz, t=None, iteration=None, species=None, select : dict, optional Either None or a dictionary of rules to select the particles, of the form - 'x' : [-4., 10.] (Particles having x between -4 and 10) - 'z' : [0, 100] (Particles having x between 0 and 100) + 'x' : [-4., 10.] (Particles having x between -4 and 10 meters) + 'z' : [0, 100] (Particles having z between 0 and 100 meters) plot : bool, optional Whether to plot the requested quantity @@ -160,10 +160,10 @@ def get_sigma_gamma_slice(self, dz, t=None, iteration=None, species=None, if plot: check_matplotlib() iteration = self.iterations[ self._current_i ] - time = self.t[ self._current_i ] + time_s = self.t[ self._current_i ] plt.plot(z_pos, spreads, **kw) plt.title("Slice energy spread at %.1f s (iteration %d)" - % (time, iteration), fontsize=self.plotter.fontsize) + % (time_s, iteration), fontsize=self.plotter.fontsize) plt.xlabel('$z \;(m)$', fontsize=self.plotter.fontsize) plt.ylabel('$\sigma_\gamma (\Delta_z=%s m)$' % dz, fontsize=self.plotter.fontsize) @@ -190,8 +190,8 @@ def get_charge( self, t=None, iteration=None, species=None, select=None ): select : dict, optional Either None or a dictionary of rules to select the particles, of the form - 'x' : [-4., 10.] (Particles having x between -4 and 10) - 'z' : [0, 100] (Particles having x between 0 and 100) + 'x' : [-4., 10.] (Particles having x between -4 and 10 meters) + 'z' : [0, 100] (Particles having z between 0 and 100 meters) Returns ------- @@ -227,8 +227,8 @@ def get_divergence( self, t=None, iteration=None, species=None, select : dict, optional Either None or a dictionary of rules to select the particles, of the form - 'x' : [-4., 10.] (Particles having x between -4 and 10) - 'z' : [0, 100] (Particles having x between 0 and 100) + 'x' : [-4., 10.] (Particles having x between -4 and 10 meters) + 'z' : [0, 100] (Particles having z between 0 and 100 meters) Returns ------- @@ -270,8 +270,8 @@ def get_emittance(self, t=None, iteration=None, species=None, select : dict, optional Either None or a dictionary of rules to select the particles, of the form: - 'x' : [-4., 10.] (Particles having x between -4 and 10); - 'z' : [0, 100] (Particles having x between 0 and 100). + 'x' : [-4., 10.] (Particles having x between -4 and 10 meters) + 'z' : [0, 100] (Particles having z between 0 and 100 meters). kind : string, optional Kind of emittance to be computed. Can be 'normalized' or 'trace'. @@ -386,8 +386,8 @@ def get_current( self, t=None, iteration=None, species=None, select=None, select : dict, optional Either None or a dictionary of rules to select the particles, of the form - 'x' : [-4., 10.] (Particles having x between -4 and 10) - 'z' : [0, 100] (Particles having x between 0 and 100) + 'x' : [-4., 10.] (Particles having x between -4 and 10 meters) + 'z' : [0, 100] (Particles having z between 0 and 100 meters) bins : int, optional Number of bins along the z-axis in which to calculate the current @@ -427,10 +427,10 @@ def get_current( self, t=None, iteration=None, species=None, select=None, if plot: check_matplotlib() iteration = self.iterations[ self._current_i ] - time = self.t[ self._current_i ] + time_s = self.t[ self._current_i ] plt.plot( info.z, current, **kw) plt.title("Current at %.1f s (iteration %d)" - % (time, iteration ), fontsize=self.plotter.fontsize) + % (time_s, iteration ), fontsize=self.plotter.fontsize) plt.xlabel('$z \;(m)$', fontsize=self.plotter.fontsize) plt.ylabel('$I \;(A)$', fontsize=self.plotter.fontsize) # Return the current and bin centers @@ -536,7 +536,7 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', if plot: check_matplotlib() iteration = self.iterations[ self._current_i ] - time = self.t[ self._current_i ] + time_s = self.t[ self._current_i ] if index != 'all': plt.plot( info.z, envelope, **kw) plt.ylabel('$E_%s \;(V/m)$' % pol, @@ -548,7 +548,7 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', plt.ylabel('$%s \;(m)$' % pol, fontsize=self.plotter.fontsize) plt.title("Laser envelope at %.1f s (iteration %d)" - % (time, iteration ), fontsize=self.plotter.fontsize) + % (time_s, iteration ), fontsize=self.plotter.fontsize) plt.xlabel('$z \;(m)$', fontsize=self.plotter.fontsize) # Return the result return( envelope, info ) @@ -743,13 +743,13 @@ def get_spectrum( self, t=None, iteration=None, pol=None, if plot: check_matplotlib() iteration = self.iterations[ self._current_i ] - time = self.t[ self._current_i ] + time_s = self.t[ self._current_i ] plt.plot( spect_info.omega, spectrum, **kw ) plt.xlabel('$\omega \; (rad.s^{-1})$', fontsize=self.plotter.fontsize ) plt.ylabel('Spectrum', fontsize=self.plotter.fontsize ) plt.title("Spectrum at %.1f s (iteration %d)" - % (time, iteration ), fontsize=self.plotter.fontsize) + % (time_s, iteration ), fontsize=self.plotter.fontsize) return( spectrum, spect_info ) def get_a0( self, t=None, iteration=None, pol=None ): @@ -1037,11 +1037,11 @@ def get_spectrogram( self, t=None, iteration=None, pol=None, theta=0, if plot: check_matplotlib() iteration = self.iterations[ self._current_i ] - time = self.t[ self._current_i ] + time_s = self.t[ self._current_i ] plt.imshow( spectrogram, extent=info.imshow_extent, aspect='auto', **kw) plt.title("Spectrogram at %.1f s (iteration %d)" - % (time, iteration ), fontsize=self.plotter.fontsize) + % (time_s, iteration ), fontsize=self.plotter.fontsize) plt.xlabel('$t \;(s)$', fontsize=self.plotter.fontsize ) plt.ylabel('$\omega \;(rad.s^{-1})$', fontsize=self.plotter.fontsize ) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index a61e68ec..6f75c8d4 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -153,7 +153,7 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, select: dict or ParticleTracker object, optional - If `select` is a dictionary: then it lists a set of rules to select the particles, of the form - 'x' : [-4., 10.] (Particles having x between -4 and 10) + 'x' : [-4., 10.] (Particles having x between -4 and 10 meters) 'ux' : [-0.1, 0.1] (Particles having ux between -0.1 and 0.1 mc) 'uz' : [5., None] (Particles with uz above 5 mc) - If `select` is a ParticleTracker object: From 5280b88d6390c1afbbd1c3222896f3079cc62bdd Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Mon, 28 May 2018 08:11:45 -0700 Subject: [PATCH 46/90] Remove the (useless) argument `output` --- opmd_viewer/openpmd_timeseries/main.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index 6f75c8d4..d53d9705 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -113,7 +113,7 @@ def __init__(self, path_to_dir, check_all_files=True): self.plotter = Plotter(self.t, self.iterations) def get_particle(self, var_list=None, species=None, t=None, iteration=None, - select=None, output=True, plot=False, nbins=150, + select=None, plot=False, nbins=150, plot_range=[[None, None], [None, None]], use_field_mesh=True, histogram_deposition='cic', **kw): """ @@ -147,9 +147,6 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, The iteration at which to obtain the data Either `t` or `iteration` should be given by the user. - output : bool, optional - Whether to return the requested quantity - select: dict or ParticleTracker object, optional - If `select` is a dictionary: then it lists a set of rules to select the particles, of the form @@ -343,13 +340,12 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, # Close the file file_handle.close() - # Output - if output: - return(data_list) + # Output the data + return(data_list) def get_field(self, field=None, coord=None, t=None, iteration=None, m='all', theta=0., slicing=0., slicing_dir=None, - output=True, plot=False, + plot=False, plot_range=[[None, None], [None, None]], **kw): """ Extract a given field from an HDF5 file in the openPMD format. @@ -400,9 +396,6 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, Returned array is reduced by 1 dimension per slicing. If slicing is None, the full grid is returned. - output : bool, optional - Whether to return the requested quantity - plot : bool, optional Whether to plot the requested quantity From 4475d01306323e1868d0f9b327e55de11d02d865 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Tue, 5 Jun 2018 17:21:06 -0700 Subject: [PATCH 47/90] Fix bug in slider --- opmd_viewer/openpmd_timeseries/interactive.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/interactive.py b/opmd_viewer/openpmd_timeseries/interactive.py index 2450ce39..10e4cc98 100644 --- a/opmd_viewer/openpmd_timeseries/interactive.py +++ b/opmd_viewer/openpmd_timeseries/interactive.py @@ -118,8 +118,7 @@ def refresh_field(change=None, force=False): slicing_dir = slicing_dir_button.value # Call the method get_field - self.get_field( iteration=self.current_iteration, - output=False, plot=True, + self.get_field( iteration=self.current_iteration, plot=True, field=fieldtype_button.value, coord=coord_button.value, m=convert_to_int(mode_button.value), slicing=slicing_button.value, theta=theta_button.value, @@ -170,7 +169,7 @@ def refresh_ptcl(change=None, force=False): if ptcl_yaxis_button.value == 'None': # 1D histogram self.get_particle( iteration=self.current_iteration, - output=False, var_list=[ptcl_xaxis_button.value], + var_list=[ptcl_xaxis_button.value], select=ptcl_select_widget.to_dict(), species=ptcl_species_button.value, plot=True, nbins=ptcl_bins_button.value, @@ -179,8 +178,8 @@ def refresh_ptcl(change=None, force=False): else: # 2D histogram self.get_particle( iteration=self.current_iteration, - output=False, var_list=[ptcl_xaxis_button.value, - ptcl_yaxis_button.value], + var_list=[ptcl_xaxis_button.value, + ptcl_yaxis_button.value], select=ptcl_select_widget.to_dict(), species=ptcl_species_button.value, plot=True, nbins=ptcl_bins_button.value, From e205b9d89c38fce1f3649eaa6d7f2e90c2dff49b Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Tue, 5 Jun 2018 17:17:13 -0700 Subject: [PATCH 48/90] Add a container for the slice selection --- opmd_viewer/openpmd_timeseries/interactive.py | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/interactive.py b/opmd_viewer/openpmd_timeseries/interactive.py index 10e4cc98..9cf64c79 100644 --- a/opmd_viewer/openpmd_timeseries/interactive.py +++ b/opmd_viewer/openpmd_timeseries/interactive.py @@ -357,12 +357,10 @@ def step_bw(b): axis_labels = self.fields_metadata[field]['axis_labels'] if self.fields_metadata[field]['geometry'] == '3dcartesian': slicing_dir_button = create_toggle_buttons( value='y', - options=axis_labels, - description='Slice normal:') + options=axis_labels ) else: slicing_dir_button = create_toggle_buttons( value='None', - options=['None'] + axis_labels, - description='Slice normal:') + options=['None'] + axis_labels ) slicing_dir_button.observe( refresh_field, 'value', 'change' ) slicing_button = widgets.FloatSlider( min=-1., max=1., value=0.) set_widget_dimensions( slicing_button, width=180 ) @@ -394,14 +392,18 @@ def step_bw(b): # ---------- # Field type container field_widget_list = [fieldtype_button, coord_button] + container_fields = widgets.VBox( children=field_widget_list ) + set_widget_dimensions( container_fields, width=330 ) + # Slicing container + slices_widget_list = [ + add_description("Slice normal:", slicing_dir_button, width=100), + add_description("Slicing:", slicing_button) ] if "thetaMode" in self.avail_geom: # Add widgets specific to azimuthal modes - field_widget_list += [ mode_button, + slices_widget_list += [ mode_button, add_description('Theta:', theta_button)] - field_widget_list += [ slicing_dir_button, - add_description("Slicing:", slicing_button) ] - container_fields = widgets.VBox( children=field_widget_list ) - set_widget_dimensions( container_fields, width=330 ) + container_slicing = widgets.VBox( children=slices_widget_list ) + set_widget_dimensions( container_slicing, width=330 ) # Plotting options container container_fld_cbar = fld_color_button.to_container() container_fld_hrange = fld_hrange_button.to_container() @@ -412,10 +414,11 @@ def step_bw(b): container_fld_hrange ]) set_widget_dimensions( container_fld_plots, width=330 ) # Accordion for the field widgets - accord1 = widgets.Accordion( - children=[container_fields, container_fld_plots]) + accord1 = widgets.Accordion( children=[container_fields, + container_slicing, container_fld_plots]) accord1.set_title(0, 'Field type') - accord1.set_title(1, 'Plotting options') + accord1.set_title(1, 'Slice selection') + accord1.set_title(2, 'Plotting options') # Complete field container container_fld = widgets.VBox( children=[accord1, widgets.HBox( children=[fld_refresh_toggle, fld_refresh_button])]) From 140e767c8c4f3aec9bfa32138f4f14bde5dee478 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 7 Jun 2018 13:26:19 -0700 Subject: [PATCH 49/90] Fix pep8 issue --- opmd_viewer/openpmd_timeseries/interactive.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/opmd_viewer/openpmd_timeseries/interactive.py b/opmd_viewer/openpmd_timeseries/interactive.py index 9cf64c79..0b31813d 100644 --- a/opmd_viewer/openpmd_timeseries/interactive.py +++ b/opmd_viewer/openpmd_timeseries/interactive.py @@ -396,7 +396,8 @@ def step_bw(b): set_widget_dimensions( container_fields, width=330 ) # Slicing container slices_widget_list = [ - add_description("Slice normal:", slicing_dir_button, width=100), + add_description("Slice normal:", + slicing_dir_button, width=100), add_description("Slicing:", slicing_button) ] if "thetaMode" in self.avail_geom: # Add widgets specific to azimuthal modes From 341a743a1a1f91f46fc0e71e74680b5b1df2b199 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 7 Jun 2018 14:18:28 -0700 Subject: [PATCH 50/90] Add documentation --- opmd_viewer/openpmd_timeseries/plotter.py | 42 ++++++++++++++--------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/plotter.py b/opmd_viewer/openpmd_timeseries/plotter.py index 17838d9e..9d255f6a 100644 --- a/opmd_viewer/openpmd_timeseries/plotter.py +++ b/opmd_viewer/openpmd_timeseries/plotter.py @@ -27,41 +27,52 @@ if matplotlib_installed: from matplotlib.ticker import ScalarFormatter - class MyFormatter( ScalarFormatter ): + class PowerOfThreeFormatter( ScalarFormatter ): """ - # TODO + Formatter for matplotlib's axes ticks, + that prints numbers as e.g. 1.5e3, 3.2e6, 0.2e-9, + where the exponent is always a multiple of 3. + + This helps a human reader to quickly identify the closest units + (e.g. nanometer) of the plotted quantity. + + This class derives from `ScalarFormatter`, which + provides a nice `offset` feature. """ def __init__( self, *args, **kwargs ): ScalarFormatter.__init__( self, *args, **kwargs ) + # Do not print the order of magnitude on the side of the axis self.set_scientific(False) + # Reduce the threshold for printing an offset on side of the axis self._offset_threshold = 2 def pprint_val( self, x, pos=None ): """ - # TODO + Function that is called for each tick of an axis. + Returns the string that """ + # Calculate the exponent (power of 3) xp = (x - self.offset) if xp != 0: - log_x = 3*math.floor( math.log10(abs(xp))/3 ) + exponent = 3 * math.floor( math.log10(abs(xp)) / 3 ) else: - log_x = 0 - # Show 2 digits at most after decimal point - mantissa = round( xp*10**(-log_x), 3) - if mantissa !=0 and math.log10(abs(mantissa)) == 3: - log_x += 3 + exponent = 0 + # Show 3 digits at most after decimal point + mantissa = round( xp * 10**(-exponent), 3) + # After rounding the exponent might change (e.g. 0.999 -> 1.) + if mantissa != 0 and math.log10(abs(mantissa)) == 3: + exponent += 3 mantissa /= 1000 string = "{:.3f}".format( mantissa ) - # Limit the string to 3 digits - string = string[:5] if '.' in string: # Remove trailing zeros and ., for integer mantissa string = string.rstrip('0') string = string.rstrip('.') - if log_x != 0: - string += "e{:d}".format( log_x ) + if exponent != 0: + string += "e{:d}".format( exponent ) return string - tick_formatter = MyFormatter() + tick_formatter = PowerOfThreeFormatter() class Plotter(object): @@ -167,7 +178,6 @@ def hist1d(self, q1, w, quantity1, species, current_i, nbins, hist_range, ax.get_xaxis().set_major_formatter( tick_formatter ) ax.get_yaxis().set_major_formatter( tick_formatter ) - def hist2d(self, q1, q2, w, quantity1, quantity2, species, current_i, nbins, hist_range, cmap='Blues', vmin=None, vmax=None, deposition='cic', **kw): @@ -248,7 +258,6 @@ def hist2d(self, q1, q2, w, quantity1, quantity2, species, current_i, ax.get_xaxis().set_major_formatter( tick_formatter ) ax.get_yaxis().set_major_formatter( tick_formatter ) - def show_field_1d( self, F, info, field_label, current_i, plot_range, vmin=None, vmax=None, **kw ): """ @@ -303,7 +312,6 @@ def show_field_1d( self, F, info, field_label, current_i, plot_range, ax.get_xaxis().set_major_formatter( tick_formatter ) ax.get_yaxis().set_major_formatter( tick_formatter ) - def show_field_2d(self, F, info, slicing_dir, m, field_label, geometry, current_i, plot_range, **kw): """ From c5d3196820ebf8a58c10d94064e75b7ccee58f5a Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sat, 9 Jun 2018 08:09:53 -0700 Subject: [PATCH 51/90] Correct position of slice for cylindrical data --- opmd_viewer/openpmd_timeseries/data_reader/field_reader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 30c60264..180a2256 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -192,7 +192,7 @@ def read_field_circ( filename, field_path, slicing, slicing_dir, m=0, F_total[:Nr, :] = (-1) ** m * F[::-1, :] axis_labels = ['r', 'z'] - shape = [Nr, Nz] + shape = [2 * Nr, Nz] grid_spacing = list( group.attrs['gridSpacing'] ) global_offset = list( group.attrs['gridGlobalOffset'] ) From 6e3e4926323efb1a3561bb71c4dfb6a783200c9a Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Wed, 20 Jun 2018 14:45:08 -0700 Subject: [PATCH 52/90] Improve printed time in plot title --- opmd_viewer/addons/pic/lpa_diagnostics.py | 10 +++++----- opmd_viewer/openpmd_timeseries/plotter.py | 18 ++++++------------ 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/opmd_viewer/addons/pic/lpa_diagnostics.py b/opmd_viewer/addons/pic/lpa_diagnostics.py index 47a1d54d..49492ef4 100644 --- a/opmd_viewer/addons/pic/lpa_diagnostics.py +++ b/opmd_viewer/addons/pic/lpa_diagnostics.py @@ -162,7 +162,7 @@ def get_sigma_gamma_slice(self, dz, t=None, iteration=None, species=None, iteration = self.iterations[ self._current_i ] time_s = self.t[ self._current_i ] plt.plot(z_pos, spreads, **kw) - plt.title("Slice energy spread at %.1f s (iteration %d)" + plt.title("Slice energy spread at %.2e s (iteration %d)" % (time_s, iteration), fontsize=self.plotter.fontsize) plt.xlabel('$z \;(m)$', fontsize=self.plotter.fontsize) plt.ylabel('$\sigma_\gamma (\Delta_z=%s m)$' % dz, @@ -429,7 +429,7 @@ def get_current( self, t=None, iteration=None, species=None, select=None, iteration = self.iterations[ self._current_i ] time_s = self.t[ self._current_i ] plt.plot( info.z, current, **kw) - plt.title("Current at %.1f s (iteration %d)" + plt.title("Current at %.2e s (iteration %d)" % (time_s, iteration ), fontsize=self.plotter.fontsize) plt.xlabel('$z \;(m)$', fontsize=self.plotter.fontsize) plt.ylabel('$I \;(A)$', fontsize=self.plotter.fontsize) @@ -547,7 +547,7 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', plt.colorbar() plt.ylabel('$%s \;(m)$' % pol, fontsize=self.plotter.fontsize) - plt.title("Laser envelope at %.1f s (iteration %d)" + plt.title("Laser envelope at %.2e s (iteration %d)" % (time_s, iteration ), fontsize=self.plotter.fontsize) plt.xlabel('$z \;(m)$', fontsize=self.plotter.fontsize) # Return the result @@ -748,7 +748,7 @@ def get_spectrum( self, t=None, iteration=None, pol=None, plt.xlabel('$\omega \; (rad.s^{-1})$', fontsize=self.plotter.fontsize ) plt.ylabel('Spectrum', fontsize=self.plotter.fontsize ) - plt.title("Spectrum at %.1f s (iteration %d)" + plt.title("Spectrum at %.2e s (iteration %d)" % (time_s, iteration ), fontsize=self.plotter.fontsize) return( spectrum, spect_info ) @@ -1040,7 +1040,7 @@ def get_spectrogram( self, t=None, iteration=None, pol=None, theta=0, time_s = self.t[ self._current_i ] plt.imshow( spectrogram, extent=info.imshow_extent, aspect='auto', **kw) - plt.title("Spectrogram at %.1f s (iteration %d)" + plt.title("Spectrogram at %.2e s (iteration %d)" % (time_s, iteration ), fontsize=self.plotter.fontsize) plt.xlabel('$t \;(s)$', fontsize=self.plotter.fontsize ) plt.ylabel('$\omega \;(rad.s^{-1})$', diff --git a/opmd_viewer/openpmd_timeseries/plotter.py b/opmd_viewer/openpmd_timeseries/plotter.py index 9d255f6a..ec93a9d5 100644 --- a/opmd_viewer/openpmd_timeseries/plotter.py +++ b/opmd_viewer/openpmd_timeseries/plotter.py @@ -171,7 +171,7 @@ def hist1d(self, q1, w, quantity1, species, current_i, nbins, hist_range, plt.xlim( hist_range[0] ) plt.ylim( hist_range[1] ) plt.xlabel(quantity1, fontsize=self.fontsize) - plt.title("%s: t = %.0f s (iteration %d)" + plt.title("%s: t = %.2e s (iteration %d)" % (species, time, iteration), fontsize=self.fontsize) # Format the ticks ax = plt.gca() @@ -251,7 +251,7 @@ def hist2d(self, q1, q2, w, quantity1, quantity2, species, current_i, plt.colorbar() plt.xlabel(quantity1, fontsize=self.fontsize) plt.ylabel(quantity2, fontsize=self.fontsize) - plt.title("%s: t = %.1f s (iteration %d)" + plt.title("%s: t = %.2e s (iteration %d)" % (species, time, iteration), fontsize=self.fontsize) # Format the ticks ax = plt.gca() @@ -289,7 +289,7 @@ def show_field_1d( self, F, info, field_label, current_i, plot_range, time = self.t[current_i] # Get the title and labels - plt.title("%s at %.1f s (iteration %d)" % (field_label, + plt.title("%s at %.2e s (iteration %d)" % (field_label, time, iteration), fontsize=self.fontsize) # Add the name of the axes @@ -354,20 +354,14 @@ def show_field_2d(self, F, info, slicing_dir, m, field_label, geometry, # Cylindrical geometry if geometry == "thetaMode": mode = str(m) - plt.title("%s in the mode %s at %.1f s (iteration %d)" + plt.title("%s in the mode %s at %.2e s (iteration %d)" % (field_label, mode, time, iteration), fontsize=self.fontsize) # 2D Cartesian geometry - elif geometry == "2dcartesian": - plt.title("%s at %.1f s (iteration %d)" + else: + plt.title("%s at %.2e s (iteration %d)" % (field_label, time, iteration), fontsize=self.fontsize) - # 3D Cartesian geometry - elif geometry == "3dcartesian": - slice_plane = info.axes[0] + '-' + info.axes[1] - plt.title("%s sliced in %s at %.1f s (iteration %d)" - % (field_label, slice_plane, time, iteration), - fontsize=self.fontsize) # Add the name of the axes plt.xlabel('$%s \;(m)$' % info.axes[1], fontsize=self.fontsize) From 30f54cba7d6abfcc5c67b732ae50cceedd7d3042 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Wed, 8 Aug 2018 20:41:42 -0700 Subject: [PATCH 53/90] Fix axes in cylindrical --- .../openpmd_timeseries/data_reader/field_metainfo.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py b/opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py index a5023b92..bfadf1e5 100644 --- a/opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py +++ b/opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py @@ -77,13 +77,16 @@ def __init__(self, axes, shape, grid_spacing, step = grid_spacing[axis] * grid_unitSI n_points = shape[axis] start = global_offset[axis] * grid_unitSI + position[axis] * step - end = start + (n_points - 1) * step - axis_points = np.linspace(start, end, n_points, endpoint=True) # Create the points below the axis if thetaMode is true if axes[axis] == 'r' and thetaMode: + end = start + (n_points / 2 - 1) * step + axis_points = np.linspace(start, end, n_points / 2, + endpoint=True) axis_points = np.concatenate((-axis_points[::-1], axis_points)) start = -end - n_points = 2 * n_points + else: + end = start + (n_points - 1) * step + axis_points = np.linspace(start, end, n_points, endpoint=True) # Register the results in the object axis_name = axes[axis] setattr(self, axis_name, axis_points) From 1b7cf87fe60f0620c3e43fc0efbe50cd40982953 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Mon, 17 Sep 2018 10:12:13 -0700 Subject: [PATCH 54/90] Fix bug with read_field_1d --- opmd_viewer/openpmd_timeseries/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opmd_viewer/openpmd_timeseries/main.py b/opmd_viewer/openpmd_timeseries/main.py index d53d9705..b029142b 100644 --- a/opmd_viewer/openpmd_timeseries/main.py +++ b/opmd_viewer/openpmd_timeseries/main.py @@ -17,8 +17,8 @@ from .particle_tracker import ParticleTracker from .data_reader.params_reader import read_openPMD_params from .data_reader.particle_reader import read_species_data -from .data_reader.field_reader import read_field_1d, read_field_2d, \ - read_field_circ, read_field_3d, get_grid_parameters +from .data_reader.field_reader import read_field_cartesian, \ + read_field_circ, get_grid_parameters from .data_reader.utilities import join_infile_path from .interactive import InteractiveViewer From b03825991e7a6c9d6b0199d27f4464c7dfc719ce Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sat, 27 Jul 2019 14:23:59 -0700 Subject: [PATCH 55/90] Replace package name from opmd_viewer to openpmd_viewer --- .gitignore | 2 +- .travis.yml | 2 +- CHANGELOG.md | 2 +- CONTRIBUTING.md | 6 +- MANIFEST.in | 6 +- RELEASING.md | 2 +- conda_recipe/meta.yaml | 2 +- {opmd_viewer => openpmd_viewer}/__init__.py | 0 .../__version__.py | 0 .../addons/__init__.py | 0 .../addons/pic/__init__.py | 0 .../addons/pic/lpa_diagnostics.py | 4 +- .../notebook_starter/Template_notebook.ipynb | 2 +- .../notebook_starter/openPMD_notebook | 2 +- .../openpmd_timeseries/__init__.py | 0 .../openpmd_timeseries/cython_function.pyx | 0 .../data_reader/__init__.py | 0 .../data_reader/field_metainfo.py | 0 .../data_reader/field_reader.py | 0 .../data_reader/params_reader.py | 0 .../data_reader/particle_reader.py | 0 .../data_reader/utilities.py | 0 .../openpmd_timeseries/interactive.py | 0 .../openpmd_timeseries/main.py | 0 .../openpmd_timeseries/particle_tracker.py | 0 .../openpmd_timeseries/plotter.py | 0 .../openpmd_timeseries/utilities.py | 0 .../openpmd_timeseries/cython_function.c | 9297 ----------------- ...n_function.cpython-36m-x86_64-linux-gnu.so | Bin 301032 -> 0 bytes setup.py | 10 +- tutorials/1_Introduction-to-the-API.ipynb | 4 +- tutorials/2_Specific-field-geometries.ipynb | 2 +- tutorials/3_Introduction-to-the-GUI.ipynb | 4 +- tutorials/4_Particle_selection.ipynb | 6 +- tutorials/5_Laser-plasma_tools.ipynb | 4 +- 35 files changed, 30 insertions(+), 9327 deletions(-) rename {opmd_viewer => openpmd_viewer}/__init__.py (100%) rename {opmd_viewer => openpmd_viewer}/__version__.py (100%) rename {opmd_viewer => openpmd_viewer}/addons/__init__.py (100%) rename {opmd_viewer => openpmd_viewer}/addons/pic/__init__.py (100%) rename {opmd_viewer => openpmd_viewer}/addons/pic/lpa_diagnostics.py (99%) rename {opmd_viewer => openpmd_viewer}/notebook_starter/Template_notebook.ipynb (96%) rename {opmd_viewer => openpmd_viewer}/notebook_starter/openPMD_notebook (94%) rename {opmd_viewer => openpmd_viewer}/openpmd_timeseries/__init__.py (100%) rename {opmd_viewer => openpmd_viewer}/openpmd_timeseries/cython_function.pyx (100%) rename {opmd_viewer => openpmd_viewer}/openpmd_timeseries/data_reader/__init__.py (100%) rename {opmd_viewer => openpmd_viewer}/openpmd_timeseries/data_reader/field_metainfo.py (100%) rename {opmd_viewer => openpmd_viewer}/openpmd_timeseries/data_reader/field_reader.py (100%) rename {opmd_viewer => openpmd_viewer}/openpmd_timeseries/data_reader/params_reader.py (100%) rename {opmd_viewer => openpmd_viewer}/openpmd_timeseries/data_reader/particle_reader.py (100%) rename {opmd_viewer => openpmd_viewer}/openpmd_timeseries/data_reader/utilities.py (100%) rename {opmd_viewer => openpmd_viewer}/openpmd_timeseries/interactive.py (100%) rename {opmd_viewer => openpmd_viewer}/openpmd_timeseries/main.py (100%) rename {opmd_viewer => openpmd_viewer}/openpmd_timeseries/particle_tracker.py (100%) rename {opmd_viewer => openpmd_viewer}/openpmd_timeseries/plotter.py (100%) rename {opmd_viewer => openpmd_viewer}/openpmd_timeseries/utilities.py (100%) delete mode 100644 opmd_viewer/openpmd_timeseries/cython_function.c delete mode 100755 opmd_viewer/openpmd_timeseries/cython_function.cpython-36m-x86_64-linux-gnu.so diff --git a/.gitignore b/.gitignore index d1ff6ae3..3df2b513 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ *.egg build/ dist/ -opmd_viewer.egg-info/ +openpmd_viewer.egg-info/ .cache/ .eggs/ .vs/ diff --git a/.travis.yml b/.travis.yml index 98fe1e25..9c86d343 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,7 @@ install: before_script : # static code analysis # pyflakes: mainly warnings, unused code, etc. - - python -m pyflakes opmd_viewer + - python -m pyflakes openpmd_viewer script: - "python setup.py test" diff --git a/CHANGELOG.md b/CHANGELOG.md index ee157f4f..890e86f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -115,7 +115,7 @@ This new version includes: - an additional option `use_field_mesh` when plotting the particle. When set to `True`, this option uses information from the field mesh to choose the parameters of the particle histograms (esp. the bins). This is useful in order to avoid plotting/binning artifacts (aliasing) when the particles are evenly spaced. -In addition, the package `opmd_viewer` now has an attribute `__version__`. +In addition, the package `openpmd_viewer` now has an attribute `__version__`. ## 0.3.3 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 30c155af..4416758b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,7 +49,7 @@ git pull git@github.com:openPMD/openPMD-viewer.git dev - Use [pyflakes](https://pypi.python.org/pypi/pyflakes) to detect any potential bug. ``` cd openPMD-viewer/ - pyflakes opmd_viewer + pyflakes openpmd_viewer ``` - Make sure that the tests pass (please install `wget` and `jupyter` before running the tests: `pip install wget jupyter`) ``` @@ -76,10 +76,10 @@ git push -u origin - Features that **modify** or **improve** the `OpenPMDTimeSeries` object should be implemented in the -`opmd_viewer/opempmd_timeseries` folder. Features that **build upon** the +`openpmd_viewer/opempmd_timeseries` folder. Features that **build upon** the `OpenPMDTimeSeries` object to create domain-specific analysis tools (e.g. laser diagnostics for PIC simulations) should be implemented in -the `opmd_viewer/addons` folder. +the `openpmd_viewer/addons` folder. - Document the functions and classes that you write, by using a [docstring](https://www.python.org/dev/peps/pep-0257/). List the diff --git a/MANIFEST.in b/MANIFEST.in index f229beb4..561db4e6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,5 @@ include README.md include requirements.txt -include opmd_viewer/openpmd_timeseries/cython_function.pyx -include opmd_viewer/notebook_starter/openPMD_notebook -include opmd_viewer/notebook_starter/Template_notebook.ipynb +include openpmd_viewer/openpmd_timeseries/cython_function.pyx +include openpmd_viewer/notebook_starter/openPMD_notebook +include openpmd_viewer/notebook_starter/Template_notebook.ipynb diff --git a/RELEASING.md b/RELEASING.md index 588920d8..b9c188c8 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -32,7 +32,7 @@ username = ## Creating a release on Github -- Make sure that the version number in `opmd_viewer/__version__.py` **and** +- Make sure that the version number in `openpmd_viewer/__version__.py` **and** in `conda_recipe/meta.yaml` correspond to the new release, and that the corresponding changes have been documented in `CHANGELOG.md`. diff --git a/conda_recipe/meta.yaml b/conda_recipe/meta.yaml index da1cd0c8..baf41eb9 100644 --- a/conda_recipe/meta.yaml +++ b/conda_recipe/meta.yaml @@ -34,7 +34,7 @@ requirements: test: imports: - - opmd_viewer + - openpmd_viewer about: home: https://github.com/openPMD/openPMD-viewer diff --git a/opmd_viewer/__init__.py b/openpmd_viewer/__init__.py similarity index 100% rename from opmd_viewer/__init__.py rename to openpmd_viewer/__init__.py diff --git a/opmd_viewer/__version__.py b/openpmd_viewer/__version__.py similarity index 100% rename from opmd_viewer/__version__.py rename to openpmd_viewer/__version__.py diff --git a/opmd_viewer/addons/__init__.py b/openpmd_viewer/addons/__init__.py similarity index 100% rename from opmd_viewer/addons/__init__.py rename to openpmd_viewer/addons/__init__.py diff --git a/opmd_viewer/addons/pic/__init__.py b/openpmd_viewer/addons/pic/__init__.py similarity index 100% rename from opmd_viewer/addons/pic/__init__.py rename to openpmd_viewer/addons/pic/__init__.py diff --git a/opmd_viewer/addons/pic/lpa_diagnostics.py b/openpmd_viewer/addons/pic/lpa_diagnostics.py similarity index 99% rename from opmd_viewer/addons/pic/lpa_diagnostics.py rename to openpmd_viewer/addons/pic/lpa_diagnostics.py index 9e6babef..c837cc4e 100644 --- a/opmd_viewer/addons/pic/lpa_diagnostics.py +++ b/openpmd_viewer/addons/pic/lpa_diagnostics.py @@ -10,11 +10,11 @@ # Class that inherits from OpenPMDTimeSeries, and implements # some standard diagnostics (emittance, etc.) -from opmd_viewer import OpenPMDTimeSeries, FieldMetaInformation +from openpmd_viewer import OpenPMDTimeSeries, FieldMetaInformation import numpy as np import scipy.constants as const from scipy.optimize import curve_fit -from opmd_viewer.openpmd_timeseries.plotter import check_matplotlib +from openpmd_viewer.openpmd_timeseries.plotter import check_matplotlib from scipy.signal import hilbert try: import matplotlib.pyplot as plt diff --git a/opmd_viewer/notebook_starter/Template_notebook.ipynb b/openpmd_viewer/notebook_starter/Template_notebook.ipynb similarity index 96% rename from opmd_viewer/notebook_starter/Template_notebook.ipynb rename to openpmd_viewer/notebook_starter/Template_notebook.ipynb index 7906bb3c..e41fa675 100644 --- a/opmd_viewer/notebook_starter/Template_notebook.ipynb +++ b/openpmd_viewer/notebook_starter/Template_notebook.ipynb @@ -20,7 +20,7 @@ "# or `%matplotlib inline` for non-interactive plots\n", "# or `%matplotlib widget` when using JupyterLab (github.com/matplotlib/jupyter-matplotlib)\n", "import matplotlib.pyplot as plt\n", - "from opmd_viewer import OpenPMDTimeSeries" + "from openpmd_viewer import OpenPMDTimeSeries" ] }, { diff --git a/opmd_viewer/notebook_starter/openPMD_notebook b/openpmd_viewer/notebook_starter/openPMD_notebook similarity index 94% rename from opmd_viewer/notebook_starter/openPMD_notebook rename to openpmd_viewer/notebook_starter/openPMD_notebook index 57883b0e..3be388ea 100755 --- a/opmd_viewer/notebook_starter/openPMD_notebook +++ b/openpmd_viewer/notebook_starter/openPMD_notebook @@ -12,7 +12,7 @@ from pkg_resources import resource_string # Use pkg_resources to retrieve the location and contents # of the pre-existing template notebook -notebook_text = resource_string('opmd_viewer', +notebook_text = resource_string('openpmd_viewer', 'notebook_starter/Template_notebook.ipynb') # Create a new notebook in the local directory and copy diff --git a/opmd_viewer/openpmd_timeseries/__init__.py b/openpmd_viewer/openpmd_timeseries/__init__.py similarity index 100% rename from opmd_viewer/openpmd_timeseries/__init__.py rename to openpmd_viewer/openpmd_timeseries/__init__.py diff --git a/opmd_viewer/openpmd_timeseries/cython_function.pyx b/openpmd_viewer/openpmd_timeseries/cython_function.pyx similarity index 100% rename from opmd_viewer/openpmd_timeseries/cython_function.pyx rename to openpmd_viewer/openpmd_timeseries/cython_function.pyx diff --git a/opmd_viewer/openpmd_timeseries/data_reader/__init__.py b/openpmd_viewer/openpmd_timeseries/data_reader/__init__.py similarity index 100% rename from opmd_viewer/openpmd_timeseries/data_reader/__init__.py rename to openpmd_viewer/openpmd_timeseries/data_reader/__init__.py diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py b/openpmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py similarity index 100% rename from opmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py rename to openpmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py diff --git a/opmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py similarity index 100% rename from opmd_viewer/openpmd_timeseries/data_reader/field_reader.py rename to openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py diff --git a/opmd_viewer/openpmd_timeseries/data_reader/params_reader.py b/openpmd_viewer/openpmd_timeseries/data_reader/params_reader.py similarity index 100% rename from opmd_viewer/openpmd_timeseries/data_reader/params_reader.py rename to openpmd_viewer/openpmd_timeseries/data_reader/params_reader.py diff --git a/opmd_viewer/openpmd_timeseries/data_reader/particle_reader.py b/openpmd_viewer/openpmd_timeseries/data_reader/particle_reader.py similarity index 100% rename from opmd_viewer/openpmd_timeseries/data_reader/particle_reader.py rename to openpmd_viewer/openpmd_timeseries/data_reader/particle_reader.py diff --git a/opmd_viewer/openpmd_timeseries/data_reader/utilities.py b/openpmd_viewer/openpmd_timeseries/data_reader/utilities.py similarity index 100% rename from opmd_viewer/openpmd_timeseries/data_reader/utilities.py rename to openpmd_viewer/openpmd_timeseries/data_reader/utilities.py diff --git a/opmd_viewer/openpmd_timeseries/interactive.py b/openpmd_viewer/openpmd_timeseries/interactive.py similarity index 100% rename from opmd_viewer/openpmd_timeseries/interactive.py rename to openpmd_viewer/openpmd_timeseries/interactive.py diff --git a/opmd_viewer/openpmd_timeseries/main.py b/openpmd_viewer/openpmd_timeseries/main.py similarity index 100% rename from opmd_viewer/openpmd_timeseries/main.py rename to openpmd_viewer/openpmd_timeseries/main.py diff --git a/opmd_viewer/openpmd_timeseries/particle_tracker.py b/openpmd_viewer/openpmd_timeseries/particle_tracker.py similarity index 100% rename from opmd_viewer/openpmd_timeseries/particle_tracker.py rename to openpmd_viewer/openpmd_timeseries/particle_tracker.py diff --git a/opmd_viewer/openpmd_timeseries/plotter.py b/openpmd_viewer/openpmd_timeseries/plotter.py similarity index 100% rename from opmd_viewer/openpmd_timeseries/plotter.py rename to openpmd_viewer/openpmd_timeseries/plotter.py diff --git a/opmd_viewer/openpmd_timeseries/utilities.py b/openpmd_viewer/openpmd_timeseries/utilities.py similarity index 100% rename from opmd_viewer/openpmd_timeseries/utilities.py rename to openpmd_viewer/openpmd_timeseries/utilities.py diff --git a/opmd_viewer/openpmd_timeseries/cython_function.c b/opmd_viewer/openpmd_timeseries/cython_function.c deleted file mode 100644 index 4f9fc0fa..00000000 --- a/opmd_viewer/openpmd_timeseries/cython_function.c +++ /dev/null @@ -1,9297 +0,0 @@ -/* Generated by Cython 0.27.3 */ - -/* BEGIN: Cython Metadata -{ - "distutils": { - "depends": [], - "name": "opmd_viewer.openpmd_timeseries.cython_function", - "sources": [ - "opmd_viewer/openpmd_timeseries/cython_function.pyx" - ] - }, - "module_name": "opmd_viewer.openpmd_timeseries.cython_function" -} -END: Cython Metadata */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#ifndef Py_PYTHON_H - #error Python headers needed to compile C extensions, please install development version of Python. -#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) - #error Cython requires Python 2.6+ or Python 3.3+. -#else -#define CYTHON_ABI "0_27_3" -#define CYTHON_FUTURE_DIVISION 0 -#include -#ifndef offsetof - #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) -#endif -#if !defined(WIN32) && !defined(MS_WINDOWS) - #ifndef __stdcall - #define __stdcall - #endif - #ifndef __cdecl - #define __cdecl - #endif - #ifndef __fastcall - #define __fastcall - #endif -#endif -#ifndef DL_IMPORT - #define DL_IMPORT(t) t -#endif -#ifndef DL_EXPORT - #define DL_EXPORT(t) t -#endif -#define __PYX_COMMA , -#ifndef HAVE_LONG_LONG - #if PY_VERSION_HEX >= 0x02070000 - #define HAVE_LONG_LONG - #endif -#endif -#ifndef PY_LONG_LONG - #define PY_LONG_LONG LONG_LONG -#endif -#ifndef Py_HUGE_VAL - #define Py_HUGE_VAL HUGE_VAL -#endif -#ifdef PYPY_VERSION - #define CYTHON_COMPILING_IN_PYPY 1 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #undef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 0 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #if PY_VERSION_HEX < 0x03050000 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #undef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #undef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 1 - #undef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 0 - #undef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 0 - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 -#elif defined(PYSTON_VERSION) - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 1 - #define CYTHON_COMPILING_IN_CPYTHON 0 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #undef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 0 - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #undef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 0 - #undef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 0 - #undef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT 0 - #undef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE 0 -#else - #define CYTHON_COMPILING_IN_PYPY 0 - #define CYTHON_COMPILING_IN_PYSTON 0 - #define CYTHON_COMPILING_IN_CPYTHON 1 - #ifndef CYTHON_USE_TYPE_SLOTS - #define CYTHON_USE_TYPE_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYTYPE_LOOKUP - #define CYTHON_USE_PYTYPE_LOOKUP 0 - #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) - #define CYTHON_USE_PYTYPE_LOOKUP 1 - #endif - #if PY_MAJOR_VERSION < 3 - #undef CYTHON_USE_ASYNC_SLOTS - #define CYTHON_USE_ASYNC_SLOTS 0 - #elif !defined(CYTHON_USE_ASYNC_SLOTS) - #define CYTHON_USE_ASYNC_SLOTS 1 - #endif - #if PY_VERSION_HEX < 0x02070000 - #undef CYTHON_USE_PYLONG_INTERNALS - #define CYTHON_USE_PYLONG_INTERNALS 0 - #elif !defined(CYTHON_USE_PYLONG_INTERNALS) - #define CYTHON_USE_PYLONG_INTERNALS 1 - #endif - #ifndef CYTHON_USE_PYLIST_INTERNALS - #define CYTHON_USE_PYLIST_INTERNALS 1 - #endif - #ifndef CYTHON_USE_UNICODE_INTERNALS - #define CYTHON_USE_UNICODE_INTERNALS 1 - #endif - #if PY_VERSION_HEX < 0x030300F0 - #undef CYTHON_USE_UNICODE_WRITER - #define CYTHON_USE_UNICODE_WRITER 0 - #elif !defined(CYTHON_USE_UNICODE_WRITER) - #define CYTHON_USE_UNICODE_WRITER 1 - #endif - #ifndef CYTHON_AVOID_BORROWED_REFS - #define CYTHON_AVOID_BORROWED_REFS 0 - #endif - #ifndef CYTHON_ASSUME_SAFE_MACROS - #define CYTHON_ASSUME_SAFE_MACROS 1 - #endif - #ifndef CYTHON_UNPACK_METHODS - #define CYTHON_UNPACK_METHODS 1 - #endif - #ifndef CYTHON_FAST_THREAD_STATE - #define CYTHON_FAST_THREAD_STATE 1 - #endif - #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL 1 - #endif - #ifndef CYTHON_PEP489_MULTI_PHASE_INIT - #define CYTHON_PEP489_MULTI_PHASE_INIT (0 && PY_VERSION_HEX >= 0x03050000) - #endif - #ifndef CYTHON_USE_TP_FINALIZE - #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) - #endif -#endif -#if !defined(CYTHON_FAST_PYCCALL) -#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) -#endif -#if CYTHON_USE_PYLONG_INTERNALS - #include "longintrepr.h" - #undef SHIFT - #undef BASE - #undef MASK -#endif -#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) - #define Py_OptimizeFlag 0 -#endif -#define __PYX_BUILD_PY_SSIZE_T "n" -#define CYTHON_FORMAT_SSIZE_T "z" -#if PY_MAJOR_VERSION < 3 - #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) - #define __Pyx_DefaultClassType PyClass_Type -#else - #define __Pyx_BUILTIN_MODULE_NAME "builtins" - #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ - PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) - #define __Pyx_DefaultClassType PyType_Type -#endif -#ifndef Py_TPFLAGS_CHECKTYPES - #define Py_TPFLAGS_CHECKTYPES 0 -#endif -#ifndef Py_TPFLAGS_HAVE_INDEX - #define Py_TPFLAGS_HAVE_INDEX 0 -#endif -#ifndef Py_TPFLAGS_HAVE_NEWBUFFER - #define Py_TPFLAGS_HAVE_NEWBUFFER 0 -#endif -#ifndef Py_TPFLAGS_HAVE_FINALIZE - #define Py_TPFLAGS_HAVE_FINALIZE 0 -#endif -#if PY_VERSION_HEX < 0x030700A0 || !defined(METH_FASTCALL) - #ifndef METH_FASTCALL - #define METH_FASTCALL 0x80 - #endif - typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject **args, Py_ssize_t nargs); - typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject **args, - Py_ssize_t nargs, PyObject *kwnames); -#else - #define __Pyx_PyCFunctionFast _PyCFunctionFast - #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords -#endif -#if CYTHON_FAST_PYCCALL -#define __Pyx_PyFastCFunction_Check(func)\ - ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS))))) -#else -#define __Pyx_PyFastCFunction_Check(func) 0 -#endif -#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#elif PY_VERSION_HEX >= 0x03060000 - #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() -#elif PY_VERSION_HEX >= 0x03000000 - #define __Pyx_PyThreadState_Current PyThreadState_GET() -#else - #define __Pyx_PyThreadState_Current _PyThreadState_Current -#endif -#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) -#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) -#else -#define __Pyx_PyDict_NewPresized(n) PyDict_New() -#endif -#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION - #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) -#else - #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) - #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) -#endif -#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) - #define CYTHON_PEP393_ENABLED 1 - #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ - 0 : _PyUnicode_Ready((PyObject *)(op))) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) - #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) - #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) - #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) -#else - #define CYTHON_PEP393_ENABLED 0 - #define PyUnicode_1BYTE_KIND 1 - #define PyUnicode_2BYTE_KIND 2 - #define PyUnicode_4BYTE_KIND 4 - #define __Pyx_PyUnicode_READY(op) (0) - #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) - #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) - #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) - #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) - #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) - #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) - #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) - #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) -#endif -#if CYTHON_COMPILING_IN_PYPY - #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) -#else - #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) - #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ - PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) - #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) - #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) - #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) -#endif -#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) - #define PyObject_Malloc(s) PyMem_Malloc(s) - #define PyObject_Free(p) PyMem_Free(p) - #define PyObject_Realloc(p) PyMem_Realloc(p) -#endif -#if CYTHON_COMPILING_IN_PYSTON - #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) -#else - #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) - #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) -#endif -#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) -#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) -#else - #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) -#endif -#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) - #define PyObject_ASCII(o) PyObject_Repr(o) -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBaseString_Type PyUnicode_Type - #define PyStringObject PyUnicodeObject - #define PyString_Type PyUnicode_Type - #define PyString_Check PyUnicode_Check - #define PyString_CheckExact PyUnicode_CheckExact -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) - #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) -#else - #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) - #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) -#endif -#ifndef PySet_CheckExact - #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) -#endif -#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) -#if PY_MAJOR_VERSION >= 3 - #define PyIntObject PyLongObject - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask - #define PyNumber_Int PyNumber_Long -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBoolObject PyLongObject -#endif -#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY - #ifndef PyUnicode_InternFromString - #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) - #endif -#endif -#if PY_VERSION_HEX < 0x030200A4 - typedef long Py_hash_t; - #define __Pyx_PyInt_FromHash_t PyInt_FromLong - #define __Pyx_PyInt_AsHash_t PyInt_AsLong -#else - #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t - #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t -#endif -#if PY_MAJOR_VERSION >= 3 - #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func)) -#else - #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) -#endif -#ifndef __has_attribute - #define __has_attribute(x) 0 -#endif -#ifndef __has_cpp_attribute - #define __has_cpp_attribute(x) 0 -#endif -#if CYTHON_USE_ASYNC_SLOTS - #if PY_VERSION_HEX >= 0x030500B1 - #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods - #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) - #else - #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) - #endif -#else - #define __Pyx_PyType_AsAsync(obj) NULL -#endif -#ifndef __Pyx_PyAsyncMethodsStruct - typedef struct { - unaryfunc am_await; - unaryfunc am_aiter; - unaryfunc am_anext; - } __Pyx_PyAsyncMethodsStruct; -#endif -#ifndef CYTHON_RESTRICT - #if defined(__GNUC__) - #define CYTHON_RESTRICT __restrict__ - #elif defined(_MSC_VER) && _MSC_VER >= 1400 - #define CYTHON_RESTRICT __restrict - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_RESTRICT restrict - #else - #define CYTHON_RESTRICT - #endif -#endif -#ifndef CYTHON_UNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) -# define CYTHON_UNUSED __attribute__ ((__unused__)) -# else -# define CYTHON_UNUSED -# endif -#endif -#ifndef CYTHON_MAYBE_UNUSED_VAR -# if defined(__cplusplus) - template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } -# else -# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) -# endif -#endif -#ifndef CYTHON_NCP_UNUSED -# if CYTHON_COMPILING_IN_CPYTHON -# define CYTHON_NCP_UNUSED -# else -# define CYTHON_NCP_UNUSED CYTHON_UNUSED -# endif -#endif -#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) -#ifdef _MSC_VER - #ifndef _MSC_STDINT_H_ - #if _MSC_VER < 1300 - typedef unsigned char uint8_t; - typedef unsigned int uint32_t; - #else - typedef unsigned __int8 uint8_t; - typedef unsigned __int32 uint32_t; - #endif - #endif -#else - #include -#endif -#ifndef CYTHON_FALLTHROUGH - #if defined(__cplusplus) && __cplusplus >= 201103L - #if __has_cpp_attribute(fallthrough) - #define CYTHON_FALLTHROUGH [[fallthrough]] - #elif __has_cpp_attribute(clang::fallthrough) - #define CYTHON_FALLTHROUGH [[clang::fallthrough]] - #elif __has_cpp_attribute(gnu::fallthrough) - #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] - #endif - #endif - #ifndef CYTHON_FALLTHROUGH - #if __has_attribute(fallthrough) - #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) - #else - #define CYTHON_FALLTHROUGH - #endif - #endif - #if defined(__clang__ ) && defined(__apple_build_version__) - #if __apple_build_version__ < 7000000 - #undef CYTHON_FALLTHROUGH - #define CYTHON_FALLTHROUGH - #endif - #endif -#endif - -#ifndef CYTHON_INLINE - #if defined(__clang__) - #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) - #elif defined(__GNUC__) - #define CYTHON_INLINE __inline__ - #elif defined(_MSC_VER) - #define CYTHON_INLINE __inline - #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define CYTHON_INLINE inline - #else - #define CYTHON_INLINE - #endif -#endif - -#if defined(WIN32) || defined(MS_WINDOWS) - #define _USE_MATH_DEFINES -#endif -#include -#ifdef NAN -#define __PYX_NAN() ((float) NAN) -#else -static CYTHON_INLINE float __PYX_NAN() { - float value; - memset(&value, 0xFF, sizeof(value)); - return value; -} -#endif -#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) -#define __Pyx_truncl trunc -#else -#define __Pyx_truncl truncl -#endif - - -#define __PYX_ERR(f_index, lineno, Ln_error) \ -{ \ - __pyx_filename = __pyx_f[f_index]; __pyx_lineno = lineno; __pyx_clineno = __LINE__; goto Ln_error; \ -} - -#ifndef __PYX_EXTERN_C - #ifdef __cplusplus - #define __PYX_EXTERN_C extern "C" - #else - #define __PYX_EXTERN_C extern - #endif -#endif - -#define __PYX_HAVE__opmd_viewer__openpmd_timeseries__cython_function -#define __PYX_HAVE_API__opmd_viewer__openpmd_timeseries__cython_function -#include -#include -#include "numpy/arrayobject.h" -#include "numpy/ufuncobject.h" -#include -#include "pythread.h" -#ifdef _OPENMP -#include -#endif /* _OPENMP */ - -#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) -#define CYTHON_WITHOUT_ASSERTIONS -#endif - -typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; - const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; - -#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 -#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0 -#define __PYX_DEFAULT_STRING_ENCODING "" -#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString -#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#define __Pyx_uchar_cast(c) ((unsigned char)c) -#define __Pyx_long_cast(x) ((long)x) -#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ - (sizeof(type) < sizeof(Py_ssize_t)) ||\ - (sizeof(type) > sizeof(Py_ssize_t) &&\ - likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX) &&\ - (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ - v == (type)PY_SSIZE_T_MIN))) ||\ - (sizeof(type) == sizeof(Py_ssize_t) &&\ - (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ - v == (type)PY_SSIZE_T_MAX))) ) -#if defined (__cplusplus) && __cplusplus >= 201103L - #include - #define __Pyx_sst_abs(value) std::abs(value) -#elif SIZEOF_INT >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) abs(value) -#elif SIZEOF_LONG >= SIZEOF_SIZE_T - #define __Pyx_sst_abs(value) labs(value) -#elif defined (_MSC_VER) - #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - #define __Pyx_sst_abs(value) llabs(value) -#elif defined (__GNUC__) - #define __Pyx_sst_abs(value) __builtin_llabs(value) -#else - #define __Pyx_sst_abs(value) ((value<0) ? -value : value) -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); -#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) -#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize -#else - #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString - #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize -#endif -#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) -#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) -#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) -#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) -#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) -#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) -#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) -static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { - const Py_UNICODE *u_end = u; - while (*u_end++) ; - return (size_t)(u_end - u - 1); -} -#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) -#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode -#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode -#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) -#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) -#define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False)) -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); -#define __Pyx_PySequence_Tuple(obj)\ - (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); -#if CYTHON_ASSUME_SAFE_MACROS -#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) -#else -#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) -#endif -#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) -#if PY_MAJOR_VERSION >= 3 -#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) -#else -#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) -#endif -#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII -static int __Pyx_sys_getdefaultencoding_not_ascii; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - PyObject* ascii_chars_u = NULL; - PyObject* ascii_chars_b = NULL; - const char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - if (strcmp(default_encoding_c, "ascii") == 0) { - __Pyx_sys_getdefaultencoding_not_ascii = 0; - } else { - char ascii_chars[128]; - int c; - for (c = 0; c < 128; c++) { - ascii_chars[c] = c; - } - __Pyx_sys_getdefaultencoding_not_ascii = 1; - ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); - if (!ascii_chars_u) goto bad; - ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); - if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { - PyErr_Format( - PyExc_ValueError, - "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", - default_encoding_c); - goto bad; - } - Py_DECREF(ascii_chars_u); - Py_DECREF(ascii_chars_b); - } - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - Py_XDECREF(ascii_chars_u); - Py_XDECREF(ascii_chars_b); - return -1; -} -#endif -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) -#else -#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) -#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -static char* __PYX_DEFAULT_STRING_ENCODING; -static int __Pyx_init_sys_getdefaultencoding_params(void) { - PyObject* sys; - PyObject* default_encoding = NULL; - char* default_encoding_c; - sys = PyImport_ImportModule("sys"); - if (!sys) goto bad; - default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); - Py_DECREF(sys); - if (!default_encoding) goto bad; - default_encoding_c = PyBytes_AsString(default_encoding); - if (!default_encoding_c) goto bad; - __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); - if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; - strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); - Py_DECREF(default_encoding); - return 0; -bad: - Py_XDECREF(default_encoding); - return -1; -} -#endif -#endif - - -/* Test for GCC > 2.95 */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) - #define likely(x) __builtin_expect(!!(x), 1) - #define unlikely(x) __builtin_expect(!!(x), 0) -#else /* !__GNUC__ or GCC < 2.95 */ - #define likely(x) (x) - #define unlikely(x) (x) -#endif /* __GNUC__ */ -static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } - -static PyObject *__pyx_m = NULL; -static PyObject *__pyx_d; -static PyObject *__pyx_b; -static PyObject *__pyx_cython_runtime; -static PyObject *__pyx_empty_tuple; -static PyObject *__pyx_empty_bytes; -static PyObject *__pyx_empty_unicode; -static int __pyx_lineno; -static int __pyx_clineno = 0; -static const char * __pyx_cfilenm= __FILE__; -static const char *__pyx_filename; - -/* Header.proto */ -#if !defined(CYTHON_CCOMPLEX) - #if defined(__cplusplus) - #define CYTHON_CCOMPLEX 1 - #elif defined(_Complex_I) - #define CYTHON_CCOMPLEX 1 - #else - #define CYTHON_CCOMPLEX 0 - #endif -#endif -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - #include - #else - #include - #endif -#endif -#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) - #undef _Complex_I - #define _Complex_I 1.0fj -#endif - - -static const char *__pyx_f[] = { - "opmd_viewer/openpmd_timeseries/cython_function.pyx", - "__init__.pxd", - "type.pxd", - "bool.pxd", - "complex.pxd", -}; -/* BufferFormatStructs.proto */ -#define IS_UNSIGNED(type) (((type) -1) > 0) -struct __Pyx_StructField_; -#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0) -typedef struct { - const char* name; - struct __Pyx_StructField_* fields; - size_t size; - size_t arraysize[8]; - int ndim; - char typegroup; - char is_unsigned; - int flags; -} __Pyx_TypeInfo; -typedef struct __Pyx_StructField_ { - __Pyx_TypeInfo* type; - const char* name; - size_t offset; -} __Pyx_StructField; -typedef struct { - __Pyx_StructField* field; - size_t parent_offset; -} __Pyx_BufFmt_StackElem; -typedef struct { - __Pyx_StructField root; - __Pyx_BufFmt_StackElem* head; - size_t fmt_offset; - size_t new_count, enc_count; - size_t struct_alignment; - int is_complex; - char enc_type; - char new_packmode; - char enc_packmode; - char is_valid_array; -} __Pyx_BufFmt_Context; - - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":743 - * # in Cython to enable them only on the right systems. - * - * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< - * ctypedef npy_int16 int16_t - * ctypedef npy_int32 int32_t - */ -typedef npy_int8 __pyx_t_5numpy_int8_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":744 - * - * ctypedef npy_int8 int8_t - * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< - * ctypedef npy_int32 int32_t - * ctypedef npy_int64 int64_t - */ -typedef npy_int16 __pyx_t_5numpy_int16_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":745 - * ctypedef npy_int8 int8_t - * ctypedef npy_int16 int16_t - * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< - * ctypedef npy_int64 int64_t - * #ctypedef npy_int96 int96_t - */ -typedef npy_int32 __pyx_t_5numpy_int32_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":746 - * ctypedef npy_int16 int16_t - * ctypedef npy_int32 int32_t - * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< - * #ctypedef npy_int96 int96_t - * #ctypedef npy_int128 int128_t - */ -typedef npy_int64 __pyx_t_5numpy_int64_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":750 - * #ctypedef npy_int128 int128_t - * - * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< - * ctypedef npy_uint16 uint16_t - * ctypedef npy_uint32 uint32_t - */ -typedef npy_uint8 __pyx_t_5numpy_uint8_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":751 - * - * ctypedef npy_uint8 uint8_t - * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< - * ctypedef npy_uint32 uint32_t - * ctypedef npy_uint64 uint64_t - */ -typedef npy_uint16 __pyx_t_5numpy_uint16_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":752 - * ctypedef npy_uint8 uint8_t - * ctypedef npy_uint16 uint16_t - * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< - * ctypedef npy_uint64 uint64_t - * #ctypedef npy_uint96 uint96_t - */ -typedef npy_uint32 __pyx_t_5numpy_uint32_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":753 - * ctypedef npy_uint16 uint16_t - * ctypedef npy_uint32 uint32_t - * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< - * #ctypedef npy_uint96 uint96_t - * #ctypedef npy_uint128 uint128_t - */ -typedef npy_uint64 __pyx_t_5numpy_uint64_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":757 - * #ctypedef npy_uint128 uint128_t - * - * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< - * ctypedef npy_float64 float64_t - * #ctypedef npy_float80 float80_t - */ -typedef npy_float32 __pyx_t_5numpy_float32_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":758 - * - * ctypedef npy_float32 float32_t - * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< - * #ctypedef npy_float80 float80_t - * #ctypedef npy_float128 float128_t - */ -typedef npy_float64 __pyx_t_5numpy_float64_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":767 - * # The int types are mapped a bit surprising -- - * # numpy.int corresponds to 'l' and numpy.long to 'q' - * ctypedef npy_long int_t # <<<<<<<<<<<<<< - * ctypedef npy_longlong long_t - * ctypedef npy_longlong longlong_t - */ -typedef npy_long __pyx_t_5numpy_int_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":768 - * # numpy.int corresponds to 'l' and numpy.long to 'q' - * ctypedef npy_long int_t - * ctypedef npy_longlong long_t # <<<<<<<<<<<<<< - * ctypedef npy_longlong longlong_t - * - */ -typedef npy_longlong __pyx_t_5numpy_long_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":769 - * ctypedef npy_long int_t - * ctypedef npy_longlong long_t - * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< - * - * ctypedef npy_ulong uint_t - */ -typedef npy_longlong __pyx_t_5numpy_longlong_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":771 - * ctypedef npy_longlong longlong_t - * - * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<< - * ctypedef npy_ulonglong ulong_t - * ctypedef npy_ulonglong ulonglong_t - */ -typedef npy_ulong __pyx_t_5numpy_uint_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":772 - * - * ctypedef npy_ulong uint_t - * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<< - * ctypedef npy_ulonglong ulonglong_t - * - */ -typedef npy_ulonglong __pyx_t_5numpy_ulong_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":773 - * ctypedef npy_ulong uint_t - * ctypedef npy_ulonglong ulong_t - * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< - * - * ctypedef npy_intp intp_t - */ -typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":775 - * ctypedef npy_ulonglong ulonglong_t - * - * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< - * ctypedef npy_uintp uintp_t - * - */ -typedef npy_intp __pyx_t_5numpy_intp_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":776 - * - * ctypedef npy_intp intp_t - * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< - * - * ctypedef npy_double float_t - */ -typedef npy_uintp __pyx_t_5numpy_uintp_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":778 - * ctypedef npy_uintp uintp_t - * - * ctypedef npy_double float_t # <<<<<<<<<<<<<< - * ctypedef npy_double double_t - * ctypedef npy_longdouble longdouble_t - */ -typedef npy_double __pyx_t_5numpy_float_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":779 - * - * ctypedef npy_double float_t - * ctypedef npy_double double_t # <<<<<<<<<<<<<< - * ctypedef npy_longdouble longdouble_t - * - */ -typedef npy_double __pyx_t_5numpy_double_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":780 - * ctypedef npy_double float_t - * ctypedef npy_double double_t - * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< - * - * ctypedef npy_cfloat cfloat_t - */ -typedef npy_longdouble __pyx_t_5numpy_longdouble_t; -/* Declarations.proto */ -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - typedef ::std::complex< float > __pyx_t_float_complex; - #else - typedef float _Complex __pyx_t_float_complex; - #endif -#else - typedef struct { float real, imag; } __pyx_t_float_complex; -#endif -static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float); - -/* Declarations.proto */ -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - typedef ::std::complex< double > __pyx_t_double_complex; - #else - typedef double _Complex __pyx_t_double_complex; - #endif -#else - typedef struct { double real, imag; } __pyx_t_double_complex; -#endif -static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double); - - -/*--- Type declarations ---*/ - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":782 - * ctypedef npy_longdouble longdouble_t - * - * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<< - * ctypedef npy_cdouble cdouble_t - * ctypedef npy_clongdouble clongdouble_t - */ -typedef npy_cfloat __pyx_t_5numpy_cfloat_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":783 - * - * ctypedef npy_cfloat cfloat_t - * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<< - * ctypedef npy_clongdouble clongdouble_t - * - */ -typedef npy_cdouble __pyx_t_5numpy_cdouble_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":784 - * ctypedef npy_cfloat cfloat_t - * ctypedef npy_cdouble cdouble_t - * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<< - * - * ctypedef npy_cdouble complex_t - */ -typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t; - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":786 - * ctypedef npy_clongdouble clongdouble_t - * - * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew1(a): - */ -typedef npy_cdouble __pyx_t_5numpy_complex_t; - -/* --- Runtime support code (head) --- */ -/* Refnanny.proto */ -#ifndef CYTHON_REFNANNY - #define CYTHON_REFNANNY 0 -#endif -#if CYTHON_REFNANNY - typedef struct { - void (*INCREF)(void*, PyObject*, int); - void (*DECREF)(void*, PyObject*, int); - void (*GOTREF)(void*, PyObject*, int); - void (*GIVEREF)(void*, PyObject*, int); - void* (*SetupContext)(const char*, int, const char*); - void (*FinishContext)(void**); - } __Pyx_RefNannyAPIStruct; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; - static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); - #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; -#ifdef WITH_THREAD - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - if (acquire_gil) {\ - PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - PyGILState_Release(__pyx_gilstate_save);\ - } else {\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ - } -#else - #define __Pyx_RefNannySetupContext(name, acquire_gil)\ - __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) -#endif - #define __Pyx_RefNannyFinishContext()\ - __Pyx_RefNanny->FinishContext(&__pyx_refnanny) - #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) - #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) - #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) - #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) - #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) -#else - #define __Pyx_RefNannyDeclarations - #define __Pyx_RefNannySetupContext(name, acquire_gil) - #define __Pyx_RefNannyFinishContext() - #define __Pyx_INCREF(r) Py_INCREF(r) - #define __Pyx_DECREF(r) Py_DECREF(r) - #define __Pyx_GOTREF(r) - #define __Pyx_GIVEREF(r) - #define __Pyx_XINCREF(r) Py_XINCREF(r) - #define __Pyx_XDECREF(r) Py_XDECREF(r) - #define __Pyx_XGOTREF(r) - #define __Pyx_XGIVEREF(r) -#endif -#define __Pyx_XDECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_XDECREF(tmp);\ - } while (0) -#define __Pyx_DECREF_SET(r, v) do {\ - PyObject *tmp = (PyObject *) r;\ - r = v; __Pyx_DECREF(tmp);\ - } while (0) -#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) -#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) - -/* PyObjectGetAttrStr.proto */ -#if CYTHON_USE_TYPE_SLOTS -static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { - PyTypeObject* tp = Py_TYPE(obj); - if (likely(tp->tp_getattro)) - return tp->tp_getattro(obj, attr_name); -#if PY_MAJOR_VERSION < 3 - if (likely(tp->tp_getattr)) - return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); -#endif - return PyObject_GetAttr(obj, attr_name); -} -#else -#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) -#endif - -/* GetBuiltinName.proto */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name); - -/* RaiseArgTupleInvalid.proto */ -static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, - Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); - -/* RaiseDoubleKeywords.proto */ -static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); - -/* ParseKeywords.proto */ -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ - PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ - const char* function_name); - -/* ArgTypeTest.proto */ -#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ - ((likely((Py_TYPE(obj) == type) | (none_allowed && (obj == Py_None)))) ? 1 :\ - __Pyx__ArgTypeTest(obj, type, name, exact)) -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); - -/* IsLittleEndian.proto */ -static CYTHON_INLINE int __Pyx_Is_Little_Endian(void); - -/* BufferFormatCheck.proto */ -static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts); -static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, - __Pyx_BufFmt_StackElem* stack, - __Pyx_TypeInfo* type); - -/* BufferGetAndValidate.proto */ -#define __Pyx_GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)\ - ((obj == Py_None || obj == NULL) ?\ - (__Pyx_ZeroBuffer(buf), 0) :\ - __Pyx__GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack)) -static int __Pyx__GetBufferAndValidate(Py_buffer* buf, PyObject* obj, - __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); -static void __Pyx_ZeroBuffer(Py_buffer* buf); -static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); -static Py_ssize_t __Pyx_minusones[] = { -1, -1, -1, -1, -1, -1, -1, -1 }; -static Py_ssize_t __Pyx_zeros[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -#define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0) -/* PyThreadStateGet.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; -#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; -#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type -#else -#define __Pyx_PyThreadState_declare -#define __Pyx_PyThreadState_assign -#define __Pyx_PyErr_Occurred() PyErr_Occurred() -#endif - -/* PyErrFetchRestore.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) -#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) -#else -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#endif -#else -#define __Pyx_PyErr_Clear() PyErr_Clear() -#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) -#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) -#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) -#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) -#endif - -/* GetModuleGlobalName.proto */ -static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); - -/* PyObjectCall.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); -#else -#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) -#endif - -/* GetItemInt.proto */ -#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ - (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ - __Pyx_GetItemInt_Generic(o, to_py_func(i)))) -#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ - (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - int wraparound, int boundscheck); -static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, - int is_list, int wraparound, int boundscheck); - -/* SetItemInt.proto */ -#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ - (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ - __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) :\ - (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) :\ - __Pyx_SetItemInt_Generic(o, to_py_func(i), v))) -static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v); -static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, - int is_list, int wraparound, int boundscheck); - -/* RaiseException.proto */ -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); - -/* DictGetItem.proto */ -#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY -static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { - PyObject *value; - value = PyDict_GetItemWithError(d, key); - if (unlikely(!value)) { - if (!PyErr_Occurred()) { - PyObject* args = PyTuple_Pack(1, key); - if (likely(args)) - PyErr_SetObject(PyExc_KeyError, args); - Py_XDECREF(args); - } - return NULL; - } - Py_INCREF(value); - return value; -} -#else - #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) -#endif - -/* RaiseTooManyValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); - -/* RaiseNeedMoreValuesToUnpack.proto */ -static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); - -/* RaiseNoneIterError.proto */ -static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); - -/* ExtTypeTest.proto */ -static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); - -/* SaveResetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); -#else -#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) -#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) -#endif - -/* PyErrExceptionMatches.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) -static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); -#else -#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) -#endif - -/* GetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); -#endif - -/* Import.proto */ -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); - -/* CLineInTraceback.proto */ -#ifdef CYTHON_CLINE_IN_TRACEBACK -#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) -#else -static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); -#endif - -/* CodeObjectCache.proto */ -typedef struct { - PyCodeObject* code_object; - int code_line; -} __Pyx_CodeObjectCacheEntry; -struct __Pyx_CodeObjectCache { - int count; - int max_count; - __Pyx_CodeObjectCacheEntry* entries; -}; -static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; -static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); -static PyCodeObject *__pyx_find_code_object(int code_line); -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); - -/* AddTraceback.proto */ -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename); - -/* BufferStructDeclare.proto */ -typedef struct { - Py_ssize_t shape, strides, suboffsets; -} __Pyx_Buf_DimInfo; -typedef struct { - size_t refcount; - Py_buffer pybuffer; -} __Pyx_Buffer; -typedef struct { - __Pyx_Buffer *rcbuffer; - char *data; - __Pyx_Buf_DimInfo diminfo[8]; -} __Pyx_LocalBuf_ND; - -#if PY_MAJOR_VERSION < 3 - static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); - static void __Pyx_ReleaseBuffer(Py_buffer *view); -#else - #define __Pyx_GetBuffer PyObject_GetBuffer - #define __Pyx_ReleaseBuffer PyBuffer_Release -#endif - - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); - -/* RealImag.proto */ -#if CYTHON_CCOMPLEX - #ifdef __cplusplus - #define __Pyx_CREAL(z) ((z).real()) - #define __Pyx_CIMAG(z) ((z).imag()) - #else - #define __Pyx_CREAL(z) (__real__(z)) - #define __Pyx_CIMAG(z) (__imag__(z)) - #endif -#else - #define __Pyx_CREAL(z) ((z).real) - #define __Pyx_CIMAG(z) ((z).imag) -#endif -#if defined(__cplusplus) && CYTHON_CCOMPLEX\ - && (defined(_WIN32) || defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )) || __cplusplus >= 201103) - #define __Pyx_SET_CREAL(z,x) ((z).real(x)) - #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) -#else - #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) - #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) -#endif - -/* Arithmetic.proto */ -#if CYTHON_CCOMPLEX - #define __Pyx_c_eq_float(a, b) ((a)==(b)) - #define __Pyx_c_sum_float(a, b) ((a)+(b)) - #define __Pyx_c_diff_float(a, b) ((a)-(b)) - #define __Pyx_c_prod_float(a, b) ((a)*(b)) - #define __Pyx_c_quot_float(a, b) ((a)/(b)) - #define __Pyx_c_neg_float(a) (-(a)) - #ifdef __cplusplus - #define __Pyx_c_is_zero_float(z) ((z)==(float)0) - #define __Pyx_c_conj_float(z) (::std::conj(z)) - #if 1 - #define __Pyx_c_abs_float(z) (::std::abs(z)) - #define __Pyx_c_pow_float(a, b) (::std::pow(a, b)) - #endif - #else - #define __Pyx_c_is_zero_float(z) ((z)==0) - #define __Pyx_c_conj_float(z) (conjf(z)) - #if 1 - #define __Pyx_c_abs_float(z) (cabsf(z)) - #define __Pyx_c_pow_float(a, b) (cpowf(a, b)) - #endif - #endif -#else - static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex, __pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex); - static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex); - #if 1 - static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex); - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex, __pyx_t_float_complex); - #endif -#endif - -/* Arithmetic.proto */ -#if CYTHON_CCOMPLEX - #define __Pyx_c_eq_double(a, b) ((a)==(b)) - #define __Pyx_c_sum_double(a, b) ((a)+(b)) - #define __Pyx_c_diff_double(a, b) ((a)-(b)) - #define __Pyx_c_prod_double(a, b) ((a)*(b)) - #define __Pyx_c_quot_double(a, b) ((a)/(b)) - #define __Pyx_c_neg_double(a) (-(a)) - #ifdef __cplusplus - #define __Pyx_c_is_zero_double(z) ((z)==(double)0) - #define __Pyx_c_conj_double(z) (::std::conj(z)) - #if 1 - #define __Pyx_c_abs_double(z) (::std::abs(z)) - #define __Pyx_c_pow_double(a, b) (::std::pow(a, b)) - #endif - #else - #define __Pyx_c_is_zero_double(z) ((z)==0) - #define __Pyx_c_conj_double(z) (conj(z)) - #if 1 - #define __Pyx_c_abs_double(z) (cabs(z)) - #define __Pyx_c_pow_double(a, b) (cpow(a, b)) - #endif - #endif -#else - static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex, __pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex); - static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex); - #if 1 - static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex); - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex, __pyx_t_double_complex); - #endif -#endif - -/* CIntToPy.proto */ -static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value); - -/* CIntFromPy.proto */ -static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); - -/* CIntFromPy.proto */ -static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); - -/* FastTypeChecks.proto */ -#if CYTHON_COMPILING_IN_CPYTHON -#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); -#else -#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) -#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) -#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) -#endif - -/* CheckBinaryVersion.proto */ -static int __Pyx_check_binary_version(void); - -/* PyIdentifierFromString.proto */ -#if !defined(__Pyx_PyIdentifier_FromString) -#if PY_MAJOR_VERSION < 3 - #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s) -#else - #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s) -#endif -#endif - -/* ModuleImport.proto */ -static PyObject *__Pyx_ImportModule(const char *name); - -/* TypeImport.proto */ -static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict); - -/* InitStrings.proto */ -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); - - -/* Module declarations from 'cpython.buffer' */ - -/* Module declarations from 'libc.string' */ - -/* Module declarations from 'libc.stdio' */ - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.type' */ -static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; - -/* Module declarations from 'cpython.version' */ - -/* Module declarations from 'cpython.exc' */ - -/* Module declarations from 'cpython.module' */ - -/* Module declarations from 'cpython.mem' */ - -/* Module declarations from 'cpython.tuple' */ - -/* Module declarations from 'cpython.list' */ - -/* Module declarations from 'cpython.sequence' */ - -/* Module declarations from 'cpython.mapping' */ - -/* Module declarations from 'cpython.iterator' */ - -/* Module declarations from 'cpython.number' */ - -/* Module declarations from 'cpython.int' */ - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.bool' */ -static PyTypeObject *__pyx_ptype_7cpython_4bool_bool = 0; - -/* Module declarations from 'cpython.long' */ - -/* Module declarations from 'cpython.float' */ - -/* Module declarations from '__builtin__' */ - -/* Module declarations from 'cpython.complex' */ -static PyTypeObject *__pyx_ptype_7cpython_7complex_complex = 0; - -/* Module declarations from 'cpython.string' */ - -/* Module declarations from 'cpython.unicode' */ - -/* Module declarations from 'cpython.dict' */ - -/* Module declarations from 'cpython.instance' */ - -/* Module declarations from 'cpython.function' */ - -/* Module declarations from 'cpython.method' */ - -/* Module declarations from 'cpython.weakref' */ - -/* Module declarations from 'cpython.getargs' */ - -/* Module declarations from 'cpython.pythread' */ - -/* Module declarations from 'cpython.pystate' */ - -/* Module declarations from 'cpython.cobject' */ - -/* Module declarations from 'cpython.oldbuffer' */ - -/* Module declarations from 'cpython.set' */ - -/* Module declarations from 'cpython.bytes' */ - -/* Module declarations from 'cpython.pycapsule' */ - -/* Module declarations from 'cpython' */ - -/* Module declarations from 'cpython.object' */ - -/* Module declarations from 'cpython.ref' */ - -/* Module declarations from 'numpy' */ - -/* Module declarations from 'numpy' */ -static PyTypeObject *__pyx_ptype_5numpy_dtype = 0; -static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0; -static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0; -static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0; -static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0; -static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/ - -/* Module declarations from 'cython' */ - -/* Module declarations from 'libc.math' */ - -/* Module declarations from 'opmd_viewer.openpmd_timeseries.cython_function' */ -static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t = { "int64_t", NULL, sizeof(__pyx_t_5numpy_int64_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int64_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int64_t), 0 }; -static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t = { "uint64_t", NULL, sizeof(__pyx_t_5numpy_uint64_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_uint64_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_uint64_t), 0 }; -static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t = { "float64_t", NULL, sizeof(__pyx_t_5numpy_float64_t), { 0 }, 0, 'R', 0, 0 }; -#define __Pyx_MODULE_NAME "opmd_viewer.openpmd_timeseries.cython_function" -extern int __pyx_module_is_main_opmd_viewer__openpmd_timeseries__cython_function; -int __pyx_module_is_main_opmd_viewer__openpmd_timeseries__cython_function = 0; - -/* Implementation of 'opmd_viewer.openpmd_timeseries.cython_function' */ -static PyObject *__pyx_builtin_xrange; -static PyObject *__pyx_builtin_ValueError; -static PyObject *__pyx_builtin_range; -static PyObject *__pyx_builtin_RuntimeError; -static PyObject *__pyx_builtin_ImportError; -static const char __pyx_k_N[] = "N"; -static const char __pyx_k_i[] = "i"; -static const char __pyx_k_w[] = "w"; -static const char __pyx_k_np[] = "np"; -static const char __pyx_k_q1[] = "q1"; -static const char __pyx_k_q2[] = "q2"; -static const char __pyx_k_pid[] = "pid"; -static const char __pyx_k_main[] = "__main__"; -static const char __pyx_k_test[] = "__test__"; -static const char __pyx_k_S_low[] = "S_low"; -static const char __pyx_k_dtype[] = "dtype"; -static const char __pyx_k_nbins[] = "nbins"; -static const char __pyx_k_numpy[] = "numpy"; -static const char __pyx_k_range[] = "range"; -static const char __pyx_k_zeros[] = "zeros"; -static const char __pyx_k_S1_low[] = "S1_low"; -static const char __pyx_k_S2_low[] = "S2_low"; -static const char __pyx_k_i_fill[] = "i_fill"; -static const char __pyx_k_import[] = "__import__"; -static const char __pyx_k_n_ptcl[] = "n_ptcl"; -static const char __pyx_k_xrange[] = "xrange"; -static const char __pyx_k_float64[] = "float64"; -static const char __pyx_k_nbins_1[] = "nbins_1"; -static const char __pyx_k_nbins_2[] = "nbins_2"; -static const char __pyx_k_q1_cell[] = "q1_cell"; -static const char __pyx_k_q2_cell[] = "q2_cell"; -static const char __pyx_k_bins_end[] = "bins_end"; -static const char __pyx_k_i_select[] = "i_select"; -static const char __pyx_k_hist_data[] = "hist_data"; -static const char __pyx_k_i_low_bin[] = "i_low_bin"; -static const char __pyx_k_N_selected[] = "N_selected"; -static const char __pyx_k_ValueError[] = "ValueError"; -static const char __pyx_k_bins_end_1[] = "bins_end_1"; -static const char __pyx_k_bins_end_2[] = "bins_end_2"; -static const char __pyx_k_bins_start[] = "bins_start"; -static const char __pyx_k_i1_low_bin[] = "i1_low_bin"; -static const char __pyx_k_i2_low_bin[] = "i2_low_bin"; -static const char __pyx_k_ImportError[] = "ImportError"; -static const char __pyx_k_bin_spacing[] = "bin_spacing"; -static const char __pyx_k_inv_spacing[] = "inv_spacing"; -static const char __pyx_k_RuntimeError[] = "RuntimeError"; -static const char __pyx_k_bins_start_1[] = "bins_start_1"; -static const char __pyx_k_bins_start_2[] = "bins_start_2"; -static const char __pyx_k_selected_pid[] = "selected_pid"; -static const char __pyx_k_bin_spacing_1[] = "bin_spacing_1"; -static const char __pyx_k_bin_spacing_2[] = "bin_spacing_2"; -static const char __pyx_k_inv_spacing_1[] = "inv_spacing_1"; -static const char __pyx_k_inv_spacing_2[] = "inv_spacing_2"; -static const char __pyx_k_histogram_cic_1d[] = "histogram_cic_1d"; -static const char __pyx_k_histogram_cic_2d[] = "histogram_cic_2d"; -static const char __pyx_k_original_indices[] = "original_indices"; -static const char __pyx_k_selected_indices[] = "selected_indices"; -static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; -static const char __pyx_k_extract_indices_cython[] = "extract_indices_cython"; -static const char __pyx_k_preserve_particle_index[] = "preserve_particle_index"; -static const char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous"; -static const char __pyx_k_numpy_core_multiarray_failed_to[] = "numpy.core.multiarray failed to import"; -static const char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)"; -static const char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd"; -static const char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported"; -static const char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous"; -static const char __pyx_k_numpy_core_umath_failed_to_impor[] = "numpy.core.umath failed to import"; -static const char __pyx_k_opmd_viewer_openpmd_timeseries_c[] = "opmd_viewer/openpmd_timeseries/cython_function.pyx"; -static const char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short."; -static const char __pyx_k_opmd_viewer_openpmd_timeseries_c_2[] = "opmd_viewer.openpmd_timeseries.cython_function"; -static PyObject *__pyx_kp_u_Format_string_allocated_too_shor; -static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2; -static PyObject *__pyx_n_s_ImportError; -static PyObject *__pyx_n_s_N; -static PyObject *__pyx_n_s_N_selected; -static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor; -static PyObject *__pyx_n_s_RuntimeError; -static PyObject *__pyx_n_s_S1_low; -static PyObject *__pyx_n_s_S2_low; -static PyObject *__pyx_n_s_S_low; -static PyObject *__pyx_n_s_ValueError; -static PyObject *__pyx_n_s_bin_spacing; -static PyObject *__pyx_n_s_bin_spacing_1; -static PyObject *__pyx_n_s_bin_spacing_2; -static PyObject *__pyx_n_s_bins_end; -static PyObject *__pyx_n_s_bins_end_1; -static PyObject *__pyx_n_s_bins_end_2; -static PyObject *__pyx_n_s_bins_start; -static PyObject *__pyx_n_s_bins_start_1; -static PyObject *__pyx_n_s_bins_start_2; -static PyObject *__pyx_n_s_cline_in_traceback; -static PyObject *__pyx_n_s_dtype; -static PyObject *__pyx_n_s_extract_indices_cython; -static PyObject *__pyx_n_s_float64; -static PyObject *__pyx_n_s_hist_data; -static PyObject *__pyx_n_s_histogram_cic_1d; -static PyObject *__pyx_n_s_histogram_cic_2d; -static PyObject *__pyx_n_s_i; -static PyObject *__pyx_n_s_i1_low_bin; -static PyObject *__pyx_n_s_i2_low_bin; -static PyObject *__pyx_n_s_i_fill; -static PyObject *__pyx_n_s_i_low_bin; -static PyObject *__pyx_n_s_i_select; -static PyObject *__pyx_n_s_import; -static PyObject *__pyx_n_s_inv_spacing; -static PyObject *__pyx_n_s_inv_spacing_1; -static PyObject *__pyx_n_s_inv_spacing_2; -static PyObject *__pyx_n_s_main; -static PyObject *__pyx_n_s_n_ptcl; -static PyObject *__pyx_n_s_nbins; -static PyObject *__pyx_n_s_nbins_1; -static PyObject *__pyx_n_s_nbins_2; -static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous; -static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou; -static PyObject *__pyx_n_s_np; -static PyObject *__pyx_n_s_numpy; -static PyObject *__pyx_kp_s_numpy_core_multiarray_failed_to; -static PyObject *__pyx_kp_s_numpy_core_umath_failed_to_impor; -static PyObject *__pyx_kp_s_opmd_viewer_openpmd_timeseries_c; -static PyObject *__pyx_n_s_opmd_viewer_openpmd_timeseries_c_2; -static PyObject *__pyx_n_s_original_indices; -static PyObject *__pyx_n_s_pid; -static PyObject *__pyx_n_s_preserve_particle_index; -static PyObject *__pyx_n_s_q1; -static PyObject *__pyx_n_s_q1_cell; -static PyObject *__pyx_n_s_q2; -static PyObject *__pyx_n_s_q2_cell; -static PyObject *__pyx_n_s_range; -static PyObject *__pyx_n_s_selected_indices; -static PyObject *__pyx_n_s_selected_pid; -static PyObject *__pyx_n_s_test; -static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd; -static PyObject *__pyx_n_s_w; -static PyObject *__pyx_n_s_xrange; -static PyObject *__pyx_n_s_zeros; -static PyObject *__pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_extract_indices_cython(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_original_indices, PyArrayObject *__pyx_v_selected_indices, PyArrayObject *__pyx_v_pid, PyArrayObject *__pyx_v_selected_pid, PyBoolObject *__pyx_v_preserve_particle_index); /* proto */ -static PyObject *__pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_2histogram_cic_1d(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_q1, PyArrayObject *__pyx_v_w, int __pyx_v_nbins, double __pyx_v_bins_start, double __pyx_v_bins_end); /* proto */ -static PyObject *__pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_4histogram_cic_2d(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_q1, PyArrayObject *__pyx_v_q2, PyArrayObject *__pyx_v_w, int __pyx_v_nbins_1, double __pyx_v_bins_start_1, double __pyx_v_bins_end_1, int __pyx_v_nbins_2, double __pyx_v_bins_start_2, double __pyx_v_bins_end_2); /* proto */ -static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ -static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */ -static PyObject *__pyx_tuple_; -static PyObject *__pyx_tuple__2; -static PyObject *__pyx_tuple__3; -static PyObject *__pyx_tuple__4; -static PyObject *__pyx_tuple__5; -static PyObject *__pyx_tuple__6; -static PyObject *__pyx_tuple__7; -static PyObject *__pyx_tuple__8; -static PyObject *__pyx_tuple__9; -static PyObject *__pyx_tuple__10; -static PyObject *__pyx_tuple__12; -static PyObject *__pyx_tuple__14; -static PyObject *__pyx_codeobj__11; -static PyObject *__pyx_codeobj__13; -static PyObject *__pyx_codeobj__15; - -/* "opmd_viewer/openpmd_timeseries/cython_function.pyx":9 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * def extract_indices_cython( # <<<<<<<<<<<<<< - * np.ndarray[np.int64_t, ndim=1] original_indices, - * np.ndarray[np.int64_t, ndim=1] selected_indices, - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_1extract_indices_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_11opmd_viewer_18openpmd_timeseries_15cython_function_extract_indices_cython[] = "\n Go through the sorted arrays `pid` and `selected_pid`, and record\n the indices (of the array `pid`) where they match, by storing them\n in the array `selected_indices` (this array is thus modified in-place)\n\n Return the number of elements that were filled in `selected_indices`\n "; -static PyMethodDef __pyx_mdef_11opmd_viewer_18openpmd_timeseries_15cython_function_1extract_indices_cython = {"extract_indices_cython", (PyCFunction)__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_1extract_indices_cython, METH_VARARGS|METH_KEYWORDS, __pyx_doc_11opmd_viewer_18openpmd_timeseries_15cython_function_extract_indices_cython}; -static PyObject *__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_1extract_indices_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyArrayObject *__pyx_v_original_indices = 0; - PyArrayObject *__pyx_v_selected_indices = 0; - PyArrayObject *__pyx_v_pid = 0; - PyArrayObject *__pyx_v_selected_pid = 0; - PyBoolObject *__pyx_v_preserve_particle_index = 0; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("extract_indices_cython (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_original_indices,&__pyx_n_s_selected_indices,&__pyx_n_s_pid,&__pyx_n_s_selected_pid,&__pyx_n_s_preserve_particle_index,0}; - PyObject* values[5] = {0,0,0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_original_indices)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_selected_indices)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("extract_indices_cython", 1, 5, 5, 1); __PYX_ERR(0, 9, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_pid)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("extract_indices_cython", 1, 5, 5, 2); __PYX_ERR(0, 9, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_selected_pid)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("extract_indices_cython", 1, 5, 5, 3); __PYX_ERR(0, 9, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 4: - if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_preserve_particle_index)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("extract_indices_cython", 1, 5, 5, 4); __PYX_ERR(0, 9, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "extract_indices_cython") < 0)) __PYX_ERR(0, 9, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 5) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - } - __pyx_v_original_indices = ((PyArrayObject *)values[0]); - __pyx_v_selected_indices = ((PyArrayObject *)values[1]); - __pyx_v_pid = ((PyArrayObject *)values[2]); - __pyx_v_selected_pid = ((PyArrayObject *)values[3]); - __pyx_v_preserve_particle_index = ((PyBoolObject *)values[4]); - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("extract_indices_cython", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 9, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("opmd_viewer.openpmd_timeseries.cython_function.extract_indices_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_original_indices), __pyx_ptype_5numpy_ndarray, 1, "original_indices", 0))) __PYX_ERR(0, 10, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_selected_indices), __pyx_ptype_5numpy_ndarray, 1, "selected_indices", 0))) __PYX_ERR(0, 11, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_pid), __pyx_ptype_5numpy_ndarray, 1, "pid", 0))) __PYX_ERR(0, 12, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_selected_pid), __pyx_ptype_5numpy_ndarray, 1, "selected_pid", 0))) __PYX_ERR(0, 13, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_preserve_particle_index), __pyx_ptype_7cpython_4bool_bool, 1, "preserve_particle_index", 0))) __PYX_ERR(0, 14, __pyx_L1_error) - __pyx_r = __pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_extract_indices_cython(__pyx_self, __pyx_v_original_indices, __pyx_v_selected_indices, __pyx_v_pid, __pyx_v_selected_pid, __pyx_v_preserve_particle_index); - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_extract_indices_cython(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_original_indices, PyArrayObject *__pyx_v_selected_indices, PyArrayObject *__pyx_v_pid, PyArrayObject *__pyx_v_selected_pid, PyBoolObject *__pyx_v_preserve_particle_index) { - unsigned int __pyx_v_i; - unsigned int __pyx_v_i_select; - unsigned int __pyx_v_i_fill; - unsigned int __pyx_v_N; - unsigned int __pyx_v_N_selected; - __Pyx_LocalBuf_ND __pyx_pybuffernd_original_indices; - __Pyx_Buffer __pyx_pybuffer_original_indices; - __Pyx_LocalBuf_ND __pyx_pybuffernd_pid; - __Pyx_Buffer __pyx_pybuffer_pid; - __Pyx_LocalBuf_ND __pyx_pybuffernd_selected_indices; - __Pyx_Buffer __pyx_pybuffer_selected_indices; - __Pyx_LocalBuf_ND __pyx_pybuffernd_selected_pid; - __Pyx_Buffer __pyx_pybuffer_selected_pid; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - size_t __pyx_t_3; - size_t __pyx_t_4; - size_t __pyx_t_5; - size_t __pyx_t_6; - size_t __pyx_t_7; - size_t __pyx_t_8; - size_t __pyx_t_9; - size_t __pyx_t_10; - size_t __pyx_t_11; - PyObject *__pyx_t_12 = NULL; - __Pyx_RefNannySetupContext("extract_indices_cython", 0); - __pyx_pybuffer_original_indices.pybuffer.buf = NULL; - __pyx_pybuffer_original_indices.refcount = 0; - __pyx_pybuffernd_original_indices.data = NULL; - __pyx_pybuffernd_original_indices.rcbuffer = &__pyx_pybuffer_original_indices; - __pyx_pybuffer_selected_indices.pybuffer.buf = NULL; - __pyx_pybuffer_selected_indices.refcount = 0; - __pyx_pybuffernd_selected_indices.data = NULL; - __pyx_pybuffernd_selected_indices.rcbuffer = &__pyx_pybuffer_selected_indices; - __pyx_pybuffer_pid.pybuffer.buf = NULL; - __pyx_pybuffer_pid.refcount = 0; - __pyx_pybuffernd_pid.data = NULL; - __pyx_pybuffernd_pid.rcbuffer = &__pyx_pybuffer_pid; - __pyx_pybuffer_selected_pid.pybuffer.buf = NULL; - __pyx_pybuffer_selected_pid.refcount = 0; - __pyx_pybuffernd_selected_pid.data = NULL; - __pyx_pybuffernd_selected_pid.rcbuffer = &__pyx_pybuffer_selected_pid; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_original_indices.rcbuffer->pybuffer, (PyObject*)__pyx_v_original_indices, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 9, __pyx_L1_error) - } - __pyx_pybuffernd_original_indices.diminfo[0].strides = __pyx_pybuffernd_original_indices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_original_indices.diminfo[0].shape = __pyx_pybuffernd_original_indices.rcbuffer->pybuffer.shape[0]; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_selected_indices.rcbuffer->pybuffer, (PyObject*)__pyx_v_selected_indices, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 9, __pyx_L1_error) - } - __pyx_pybuffernd_selected_indices.diminfo[0].strides = __pyx_pybuffernd_selected_indices.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_selected_indices.diminfo[0].shape = __pyx_pybuffernd_selected_indices.rcbuffer->pybuffer.shape[0]; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_pid.rcbuffer->pybuffer, (PyObject*)__pyx_v_pid, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 9, __pyx_L1_error) - } - __pyx_pybuffernd_pid.diminfo[0].strides = __pyx_pybuffernd_pid.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_pid.diminfo[0].shape = __pyx_pybuffernd_pid.rcbuffer->pybuffer.shape[0]; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_selected_pid.rcbuffer->pybuffer, (PyObject*)__pyx_v_selected_pid, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 9, __pyx_L1_error) - } - __pyx_pybuffernd_selected_pid.diminfo[0].strides = __pyx_pybuffernd_selected_pid.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_selected_pid.diminfo[0].shape = __pyx_pybuffernd_selected_pid.rcbuffer->pybuffer.shape[0]; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":22 - * Return the number of elements that were filled in `selected_indices` - * """ - * cdef unsigned int i = 0 # <<<<<<<<<<<<<< - * cdef unsigned int i_select = 0 - * cdef unsigned int i_fill = 0 - */ - __pyx_v_i = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":23 - * """ - * cdef unsigned int i = 0 - * cdef unsigned int i_select = 0 # <<<<<<<<<<<<<< - * cdef unsigned int i_fill = 0 - * cdef unsigned int N = pid.shape[0] - */ - __pyx_v_i_select = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":24 - * cdef unsigned int i = 0 - * cdef unsigned int i_select = 0 - * cdef unsigned int i_fill = 0 # <<<<<<<<<<<<<< - * cdef unsigned int N = pid.shape[0] - * cdef unsigned int N_selected = selected_pid.shape[0] - */ - __pyx_v_i_fill = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":25 - * cdef unsigned int i_select = 0 - * cdef unsigned int i_fill = 0 - * cdef unsigned int N = pid.shape[0] # <<<<<<<<<<<<<< - * cdef unsigned int N_selected = selected_pid.shape[0] - * - */ - __pyx_v_N = (__pyx_v_pid->dimensions[0]); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":26 - * cdef unsigned int i_fill = 0 - * cdef unsigned int N = pid.shape[0] - * cdef unsigned int N_selected = selected_pid.shape[0] # <<<<<<<<<<<<<< - * - * # Go through both sorted arrays (pid and selected_pid) and match them. - */ - __pyx_v_N_selected = (__pyx_v_selected_pid->dimensions[0]); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":31 - * # i.e. whenever the same number appears in both arrays, - * # record the corresponding original index in selected_indices - * while i < N and i_select < N_selected: # <<<<<<<<<<<<<< - * - * if pid[i] < selected_pid[i_select]: - */ - while (1) { - __pyx_t_2 = ((__pyx_v_i < __pyx_v_N) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L5_bool_binop_done; - } - __pyx_t_2 = ((__pyx_v_i_select < __pyx_v_N_selected) != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L5_bool_binop_done:; - if (!__pyx_t_1) break; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":33 - * while i < N and i_select < N_selected: - * - * if pid[i] < selected_pid[i_select]: # <<<<<<<<<<<<<< - * i += 1 - * elif pid[i] == selected_pid[i_select]: - */ - __pyx_t_3 = __pyx_v_i; - __pyx_t_4 = __pyx_v_i_select; - __pyx_t_1 = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_pid.rcbuffer->pybuffer.buf, __pyx_t_3, __pyx_pybuffernd_pid.diminfo[0].strides)) < (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_selected_pid.rcbuffer->pybuffer.buf, __pyx_t_4, __pyx_pybuffernd_selected_pid.diminfo[0].strides))) != 0); - if (__pyx_t_1) { - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":34 - * - * if pid[i] < selected_pid[i_select]: - * i += 1 # <<<<<<<<<<<<<< - * elif pid[i] == selected_pid[i_select]: - * selected_indices[i_fill] = original_indices[i] - */ - __pyx_v_i = (__pyx_v_i + 1); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":33 - * while i < N and i_select < N_selected: - * - * if pid[i] < selected_pid[i_select]: # <<<<<<<<<<<<<< - * i += 1 - * elif pid[i] == selected_pid[i_select]: - */ - goto __pyx_L7; - } - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":35 - * if pid[i] < selected_pid[i_select]: - * i += 1 - * elif pid[i] == selected_pid[i_select]: # <<<<<<<<<<<<<< - * selected_indices[i_fill] = original_indices[i] - * i_fill += 1 - */ - __pyx_t_5 = __pyx_v_i; - __pyx_t_6 = __pyx_v_i_select; - __pyx_t_1 = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_pid.rcbuffer->pybuffer.buf, __pyx_t_5, __pyx_pybuffernd_pid.diminfo[0].strides)) == (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_selected_pid.rcbuffer->pybuffer.buf, __pyx_t_6, __pyx_pybuffernd_selected_pid.diminfo[0].strides))) != 0); - if (__pyx_t_1) { - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":36 - * i += 1 - * elif pid[i] == selected_pid[i_select]: - * selected_indices[i_fill] = original_indices[i] # <<<<<<<<<<<<<< - * i_fill += 1 - * i_select += 1 - */ - __pyx_t_7 = __pyx_v_i; - __pyx_t_8 = __pyx_v_i_fill; - *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_selected_indices.rcbuffer->pybuffer.buf, __pyx_t_8, __pyx_pybuffernd_selected_indices.diminfo[0].strides) = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_original_indices.rcbuffer->pybuffer.buf, __pyx_t_7, __pyx_pybuffernd_original_indices.diminfo[0].strides)); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":37 - * elif pid[i] == selected_pid[i_select]: - * selected_indices[i_fill] = original_indices[i] - * i_fill += 1 # <<<<<<<<<<<<<< - * i_select += 1 - * elif pid[i] > selected_pid[i_select]: - */ - __pyx_v_i_fill = (__pyx_v_i_fill + 1); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":38 - * selected_indices[i_fill] = original_indices[i] - * i_fill += 1 - * i_select += 1 # <<<<<<<<<<<<<< - * elif pid[i] > selected_pid[i_select]: - * i_select += 1 - */ - __pyx_v_i_select = (__pyx_v_i_select + 1); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":35 - * if pid[i] < selected_pid[i_select]: - * i += 1 - * elif pid[i] == selected_pid[i_select]: # <<<<<<<<<<<<<< - * selected_indices[i_fill] = original_indices[i] - * i_fill += 1 - */ - goto __pyx_L7; - } - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":39 - * i_fill += 1 - * i_select += 1 - * elif pid[i] > selected_pid[i_select]: # <<<<<<<<<<<<<< - * i_select += 1 - * if preserve_particle_index: - */ - __pyx_t_9 = __pyx_v_i; - __pyx_t_10 = __pyx_v_i_select; - __pyx_t_1 = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_pid.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_pid.diminfo[0].strides)) > (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_selected_pid.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_selected_pid.diminfo[0].strides))) != 0); - if (__pyx_t_1) { - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":40 - * i_select += 1 - * elif pid[i] > selected_pid[i_select]: - * i_select += 1 # <<<<<<<<<<<<<< - * if preserve_particle_index: - * # Fill the index, to indicate that the particle is absent - */ - __pyx_v_i_select = (__pyx_v_i_select + 1); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":41 - * elif pid[i] > selected_pid[i_select]: - * i_select += 1 - * if preserve_particle_index: # <<<<<<<<<<<<<< - * # Fill the index, to indicate that the particle is absent - * selected_indices[i_fill] = -1 - */ - __pyx_t_1 = __Pyx_PyObject_IsTrue(((PyObject *)__pyx_v_preserve_particle_index)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 41, __pyx_L1_error) - if (__pyx_t_1) { - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":43 - * if preserve_particle_index: - * # Fill the index, to indicate that the particle is absent - * selected_indices[i_fill] = -1 # <<<<<<<<<<<<<< - * i_fill += 1 - * - */ - __pyx_t_11 = __pyx_v_i_fill; - *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_selected_indices.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_selected_indices.diminfo[0].strides) = -1LL; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":44 - * # Fill the index, to indicate that the particle is absent - * selected_indices[i_fill] = -1 - * i_fill += 1 # <<<<<<<<<<<<<< - * - * return( i_fill ) - */ - __pyx_v_i_fill = (__pyx_v_i_fill + 1); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":41 - * elif pid[i] > selected_pid[i_select]: - * i_select += 1 - * if preserve_particle_index: # <<<<<<<<<<<<<< - * # Fill the index, to indicate that the particle is absent - * selected_indices[i_fill] = -1 - */ - } - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":39 - * i_fill += 1 - * i_select += 1 - * elif pid[i] > selected_pid[i_select]: # <<<<<<<<<<<<<< - * i_select += 1 - * if preserve_particle_index: - */ - } - __pyx_L7:; - } - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":46 - * i_fill += 1 - * - * return( i_fill ) # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_12 = __Pyx_PyInt_From_unsigned_int(__pyx_v_i_fill); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 46, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_12); - __pyx_r = __pyx_t_12; - __pyx_t_12 = 0; - goto __pyx_L0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":9 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * def extract_indices_cython( # <<<<<<<<<<<<<< - * np.ndarray[np.int64_t, ndim=1] original_indices, - * np.ndarray[np.int64_t, ndim=1] selected_indices, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_12); - { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_original_indices.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_pid.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_selected_indices.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_selected_pid.rcbuffer->pybuffer); - __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("opmd_viewer.openpmd_timeseries.cython_function.extract_indices_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - goto __pyx_L2; - __pyx_L0:; - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_original_indices.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_pid.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_selected_indices.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_selected_pid.rcbuffer->pybuffer); - __pyx_L2:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "opmd_viewer/openpmd_timeseries/cython_function.pyx":51 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * def histogram_cic_1d( # <<<<<<<<<<<<<< - * np.ndarray[np.float64_t, ndim=1] q1, - * np.ndarray[np.float64_t, ndim=1] w, - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_3histogram_cic_1d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_11opmd_viewer_18openpmd_timeseries_15cython_function_2histogram_cic_1d[] = "\n Return an 1D histogram of the values in `q1` weighted by `w`,\n consisting of `nbins` evenly-spaced bins between `bins_start`\n and `bins_end`. Contribution to each bins is determined by the\n CIC weighting scheme (i.e. linear weights).\n "; -static PyMethodDef __pyx_mdef_11opmd_viewer_18openpmd_timeseries_15cython_function_3histogram_cic_1d = {"histogram_cic_1d", (PyCFunction)__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_3histogram_cic_1d, METH_VARARGS|METH_KEYWORDS, __pyx_doc_11opmd_viewer_18openpmd_timeseries_15cython_function_2histogram_cic_1d}; -static PyObject *__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_3histogram_cic_1d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyArrayObject *__pyx_v_q1 = 0; - PyArrayObject *__pyx_v_w = 0; - int __pyx_v_nbins; - double __pyx_v_bins_start; - double __pyx_v_bins_end; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("histogram_cic_1d (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_q1,&__pyx_n_s_w,&__pyx_n_s_nbins,&__pyx_n_s_bins_start,&__pyx_n_s_bins_end,0}; - PyObject* values[5] = {0,0,0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_q1)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_w)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("histogram_cic_1d", 1, 5, 5, 1); __PYX_ERR(0, 51, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_nbins)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("histogram_cic_1d", 1, 5, 5, 2); __PYX_ERR(0, 51, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bins_start)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("histogram_cic_1d", 1, 5, 5, 3); __PYX_ERR(0, 51, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 4: - if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bins_end)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("histogram_cic_1d", 1, 5, 5, 4); __PYX_ERR(0, 51, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "histogram_cic_1d") < 0)) __PYX_ERR(0, 51, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 5) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - } - __pyx_v_q1 = ((PyArrayObject *)values[0]); - __pyx_v_w = ((PyArrayObject *)values[1]); - __pyx_v_nbins = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_nbins == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 54, __pyx_L3_error) - __pyx_v_bins_start = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_bins_start == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 54, __pyx_L3_error) - __pyx_v_bins_end = __pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_bins_end == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 54, __pyx_L3_error) - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("histogram_cic_1d", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 51, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("opmd_viewer.openpmd_timeseries.cython_function.histogram_cic_1d", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_q1), __pyx_ptype_5numpy_ndarray, 1, "q1", 0))) __PYX_ERR(0, 52, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w), __pyx_ptype_5numpy_ndarray, 1, "w", 0))) __PYX_ERR(0, 53, __pyx_L1_error) - __pyx_r = __pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_2histogram_cic_1d(__pyx_self, __pyx_v_q1, __pyx_v_w, __pyx_v_nbins, __pyx_v_bins_start, __pyx_v_bins_end); - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_2histogram_cic_1d(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_q1, PyArrayObject *__pyx_v_w, int __pyx_v_nbins, double __pyx_v_bins_start, double __pyx_v_bins_end) { - double __pyx_v_bin_spacing; - double __pyx_v_inv_spacing; - int __pyx_v_n_ptcl; - int __pyx_v_i_low_bin; - double __pyx_v_q1_cell; - double __pyx_v_S_low; - PyObject *__pyx_v_hist_data = NULL; - int __pyx_v_i; - __Pyx_LocalBuf_ND __pyx_pybuffernd_q1; - __Pyx_Buffer __pyx_pybuffer_q1; - __Pyx_LocalBuf_ND __pyx_pybuffernd_w; - __Pyx_Buffer __pyx_pybuffer_w; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - double __pyx_t_1; - Py_ssize_t __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - int __pyx_t_9; - Py_ssize_t __pyx_t_10; - int __pyx_t_11; - int __pyx_t_12; - int __pyx_t_13; - Py_ssize_t __pyx_t_14; - long __pyx_t_15; - Py_ssize_t __pyx_t_16; - __Pyx_RefNannySetupContext("histogram_cic_1d", 0); - __pyx_pybuffer_q1.pybuffer.buf = NULL; - __pyx_pybuffer_q1.refcount = 0; - __pyx_pybuffernd_q1.data = NULL; - __pyx_pybuffernd_q1.rcbuffer = &__pyx_pybuffer_q1; - __pyx_pybuffer_w.pybuffer.buf = NULL; - __pyx_pybuffer_w.refcount = 0; - __pyx_pybuffernd_w.data = NULL; - __pyx_pybuffernd_w.rcbuffer = &__pyx_pybuffer_w; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_q1.rcbuffer->pybuffer, (PyObject*)__pyx_v_q1, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 51, __pyx_L1_error) - } - __pyx_pybuffernd_q1.diminfo[0].strides = __pyx_pybuffernd_q1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_q1.diminfo[0].shape = __pyx_pybuffernd_q1.rcbuffer->pybuffer.shape[0]; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_w.rcbuffer->pybuffer, (PyObject*)__pyx_v_w, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 51, __pyx_L1_error) - } - __pyx_pybuffernd_w.diminfo[0].strides = __pyx_pybuffernd_w.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_w.diminfo[0].shape = __pyx_pybuffernd_w.rcbuffer->pybuffer.shape[0]; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":62 - * """ - * # Define various scalars - * cdef double bin_spacing = (bins_end-bins_start)/nbins # <<<<<<<<<<<<<< - * cdef double inv_spacing = 1./bin_spacing - * cdef int n_ptcl = len(w) - */ - __pyx_t_1 = (__pyx_v_bins_end - __pyx_v_bins_start); - if (unlikely(__pyx_v_nbins == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "float division"); - __PYX_ERR(0, 62, __pyx_L1_error) - } - __pyx_v_bin_spacing = (__pyx_t_1 / __pyx_v_nbins); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":63 - * # Define various scalars - * cdef double bin_spacing = (bins_end-bins_start)/nbins - * cdef double inv_spacing = 1./bin_spacing # <<<<<<<<<<<<<< - * cdef int n_ptcl = len(w) - * cdef int i_low_bin - */ - if (unlikely(__pyx_v_bin_spacing == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "float division"); - __PYX_ERR(0, 63, __pyx_L1_error) - } - __pyx_v_inv_spacing = (1. / __pyx_v_bin_spacing); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":64 - * cdef double bin_spacing = (bins_end-bins_start)/nbins - * cdef double inv_spacing = 1./bin_spacing - * cdef int n_ptcl = len(w) # <<<<<<<<<<<<<< - * cdef int i_low_bin - * cdef double q1_cell - */ - __pyx_t_2 = PyObject_Length(((PyObject *)__pyx_v_w)); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 64, __pyx_L1_error) - __pyx_v_n_ptcl = __pyx_t_2; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":70 - * - * # Allocate array for histogrammed data - * hist_data = np.zeros( nbins, dtype=np.float64 ) # <<<<<<<<<<<<<< - * - * # Go through particle array and bin the data - */ - __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_zeros); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_nbins); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); - __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_7) < 0) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 70, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_hist_data = __pyx_t_7; - __pyx_t_7 = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":73 - * - * # Go through particle array and bin the data - * for i in xrange(n_ptcl): # <<<<<<<<<<<<<< - * # Calculate the index of lower bin to which this particle contributes - * q1_cell = (q1[i] - bins_start) * inv_spacing - */ - __pyx_t_8 = __pyx_v_n_ptcl; - for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { - __pyx_v_i = __pyx_t_9; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":75 - * for i in xrange(n_ptcl): - * # Calculate the index of lower bin to which this particle contributes - * q1_cell = (q1[i] - bins_start) * inv_spacing # <<<<<<<<<<<<<< - * i_low_bin = floor( q1_cell ) - * # Calculate corresponding CIC shape and deposit the weight - */ - __pyx_t_10 = __pyx_v_i; - __pyx_v_q1_cell = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_q1.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_q1.diminfo[0].strides)) - __pyx_v_bins_start) * __pyx_v_inv_spacing); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":76 - * # Calculate the index of lower bin to which this particle contributes - * q1_cell = (q1[i] - bins_start) * inv_spacing - * i_low_bin = floor( q1_cell ) # <<<<<<<<<<<<<< - * # Calculate corresponding CIC shape and deposit the weight - * S_low = 1. - (q1_cell - i_low_bin) - */ - __pyx_v_i_low_bin = ((int)floor(__pyx_v_q1_cell)); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":78 - * i_low_bin = floor( q1_cell ) - * # Calculate corresponding CIC shape and deposit the weight - * S_low = 1. - (q1_cell - i_low_bin) # <<<<<<<<<<<<<< - * if (i_low_bin >= 0) and (i_low_bin < nbins): - * hist_data[ i_low_bin ] += w[i] * S_low - */ - __pyx_v_S_low = (1. - (__pyx_v_q1_cell - __pyx_v_i_low_bin)); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":79 - * # Calculate corresponding CIC shape and deposit the weight - * S_low = 1. - (q1_cell - i_low_bin) - * if (i_low_bin >= 0) and (i_low_bin < nbins): # <<<<<<<<<<<<<< - * hist_data[ i_low_bin ] += w[i] * S_low - * if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): - */ - __pyx_t_12 = ((__pyx_v_i_low_bin >= 0) != 0); - if (__pyx_t_12) { - } else { - __pyx_t_11 = __pyx_t_12; - goto __pyx_L6_bool_binop_done; - } - __pyx_t_12 = ((__pyx_v_i_low_bin < __pyx_v_nbins) != 0); - __pyx_t_11 = __pyx_t_12; - __pyx_L6_bool_binop_done:; - if (__pyx_t_11) { - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":80 - * S_low = 1. - (q1_cell - i_low_bin) - * if (i_low_bin >= 0) and (i_low_bin < nbins): - * hist_data[ i_low_bin ] += w[i] * S_low # <<<<<<<<<<<<<< - * if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): - * hist_data[ i_low_bin + 1 ] += w[i] * (1. - S_low) - */ - __pyx_t_13 = __pyx_v_i_low_bin; - __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_hist_data, __pyx_t_13, int, 1, __Pyx_PyInt_From_int, 0, 0, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 80, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_14 = __pyx_v_i; - __pyx_t_3 = PyFloat_FromDouble(((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_w.diminfo[0].strides)) * __pyx_v_S_low)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 80, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = PyNumber_InPlaceAdd(__pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 80, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(__Pyx_SetItemInt(__pyx_v_hist_data, __pyx_t_13, __pyx_t_5, int, 1, __Pyx_PyInt_From_int, 0, 0, 0) < 0)) __PYX_ERR(0, 80, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":79 - * # Calculate corresponding CIC shape and deposit the weight - * S_low = 1. - (q1_cell - i_low_bin) - * if (i_low_bin >= 0) and (i_low_bin < nbins): # <<<<<<<<<<<<<< - * hist_data[ i_low_bin ] += w[i] * S_low - * if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): - */ - } - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":81 - * if (i_low_bin >= 0) and (i_low_bin < nbins): - * hist_data[ i_low_bin ] += w[i] * S_low - * if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): # <<<<<<<<<<<<<< - * hist_data[ i_low_bin + 1 ] += w[i] * (1. - S_low) - * - */ - __pyx_t_12 = (((__pyx_v_i_low_bin + 1) >= 0) != 0); - if (__pyx_t_12) { - } else { - __pyx_t_11 = __pyx_t_12; - goto __pyx_L9_bool_binop_done; - } - __pyx_t_12 = (((__pyx_v_i_low_bin + 1) < __pyx_v_nbins) != 0); - __pyx_t_11 = __pyx_t_12; - __pyx_L9_bool_binop_done:; - if (__pyx_t_11) { - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":82 - * hist_data[ i_low_bin ] += w[i] * S_low - * if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): - * hist_data[ i_low_bin + 1 ] += w[i] * (1. - S_low) # <<<<<<<<<<<<<< - * - * return( hist_data ) - */ - __pyx_t_15 = (__pyx_v_i_low_bin + 1); - __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_hist_data, __pyx_t_15, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 82, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_16 = __pyx_v_i; - __pyx_t_3 = PyFloat_FromDouble(((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_w.diminfo[0].strides)) * (1. - __pyx_v_S_low))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 82, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_7 = PyNumber_InPlaceAdd(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 82, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(__Pyx_SetItemInt(__pyx_v_hist_data, __pyx_t_15, __pyx_t_7, long, 1, __Pyx_PyInt_From_long, 0, 0, 0) < 0)) __PYX_ERR(0, 82, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":81 - * if (i_low_bin >= 0) and (i_low_bin < nbins): - * hist_data[ i_low_bin ] += w[i] * S_low - * if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): # <<<<<<<<<<<<<< - * hist_data[ i_low_bin + 1 ] += w[i] * (1. - S_low) - * - */ - } - } - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":84 - * hist_data[ i_low_bin + 1 ] += w[i] * (1. - S_low) - * - * return( hist_data ) # <<<<<<<<<<<<<< - * - * - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_hist_data); - __pyx_r = __pyx_v_hist_data; - goto __pyx_L0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":51 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * def histogram_cic_1d( # <<<<<<<<<<<<<< - * np.ndarray[np.float64_t, ndim=1] q1, - * np.ndarray[np.float64_t, ndim=1] w, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_q1.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_w.rcbuffer->pybuffer); - __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("opmd_viewer.openpmd_timeseries.cython_function.histogram_cic_1d", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - goto __pyx_L2; - __pyx_L0:; - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_q1.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_w.rcbuffer->pybuffer); - __pyx_L2:; - __Pyx_XDECREF(__pyx_v_hist_data); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "opmd_viewer/openpmd_timeseries/cython_function.pyx":89 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * def histogram_cic_2d( # <<<<<<<<<<<<<< - * np.ndarray[np.float64_t, ndim=1] q1, - * np.ndarray[np.float64_t, ndim=1] q2, - */ - -/* Python wrapper */ -static PyObject *__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_5histogram_cic_2d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_11opmd_viewer_18openpmd_timeseries_15cython_function_4histogram_cic_2d[] = "\n Return an 2D histogram of the values in `q1` and `q2` weighted by `w`,\n consisting of `nbins_1` bins in the first dimension and `nbins_2` bins\n in the second dimension.\n Contribution to each bins is determined by the\n CIC weighting scheme (i.e. linear weights).\n "; -static PyMethodDef __pyx_mdef_11opmd_viewer_18openpmd_timeseries_15cython_function_5histogram_cic_2d = {"histogram_cic_2d", (PyCFunction)__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_5histogram_cic_2d, METH_VARARGS|METH_KEYWORDS, __pyx_doc_11opmd_viewer_18openpmd_timeseries_15cython_function_4histogram_cic_2d}; -static PyObject *__pyx_pw_11opmd_viewer_18openpmd_timeseries_15cython_function_5histogram_cic_2d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyArrayObject *__pyx_v_q1 = 0; - PyArrayObject *__pyx_v_q2 = 0; - PyArrayObject *__pyx_v_w = 0; - int __pyx_v_nbins_1; - double __pyx_v_bins_start_1; - double __pyx_v_bins_end_1; - int __pyx_v_nbins_2; - double __pyx_v_bins_start_2; - double __pyx_v_bins_end_2; - PyObject *__pyx_r = 0; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("histogram_cic_2d (wrapper)", 0); - { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_q1,&__pyx_n_s_q2,&__pyx_n_s_w,&__pyx_n_s_nbins_1,&__pyx_n_s_bins_start_1,&__pyx_n_s_bins_end_1,&__pyx_n_s_nbins_2,&__pyx_n_s_bins_start_2,&__pyx_n_s_bins_end_2,0}; - PyObject* values[9] = {0,0,0,0,0,0,0,0,0}; - if (unlikely(__pyx_kwds)) { - Py_ssize_t kw_args; - const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); - switch (pos_args) { - case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); - CYTHON_FALLTHROUGH; - case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); - CYTHON_FALLTHROUGH; - case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); - CYTHON_FALLTHROUGH; - case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); - CYTHON_FALLTHROUGH; - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - CYTHON_FALLTHROUGH; - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - CYTHON_FALLTHROUGH; - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - CYTHON_FALLTHROUGH; - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - CYTHON_FALLTHROUGH; - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - CYTHON_FALLTHROUGH; - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - kw_args = PyDict_Size(__pyx_kwds); - switch (pos_args) { - case 0: - if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_q1)) != 0)) kw_args--; - else goto __pyx_L5_argtuple_error; - CYTHON_FALLTHROUGH; - case 1: - if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_q2)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 1); __PYX_ERR(0, 89, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 2: - if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_w)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 2); __PYX_ERR(0, 89, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 3: - if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_nbins_1)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 3); __PYX_ERR(0, 89, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 4: - if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bins_start_1)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 4); __PYX_ERR(0, 89, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 5: - if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bins_end_1)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 5); __PYX_ERR(0, 89, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 6: - if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_nbins_2)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 6); __PYX_ERR(0, 89, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 7: - if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bins_start_2)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 7); __PYX_ERR(0, 89, __pyx_L3_error) - } - CYTHON_FALLTHROUGH; - case 8: - if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_bins_end_2)) != 0)) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, 8); __PYX_ERR(0, 89, __pyx_L3_error) - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "histogram_cic_2d") < 0)) __PYX_ERR(0, 89, __pyx_L3_error) - } - } else if (PyTuple_GET_SIZE(__pyx_args) != 9) { - goto __pyx_L5_argtuple_error; - } else { - values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - values[5] = PyTuple_GET_ITEM(__pyx_args, 5); - values[6] = PyTuple_GET_ITEM(__pyx_args, 6); - values[7] = PyTuple_GET_ITEM(__pyx_args, 7); - values[8] = PyTuple_GET_ITEM(__pyx_args, 8); - } - __pyx_v_q1 = ((PyArrayObject *)values[0]); - __pyx_v_q2 = ((PyArrayObject *)values[1]); - __pyx_v_w = ((PyArrayObject *)values[2]); - __pyx_v_nbins_1 = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_nbins_1 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 93, __pyx_L3_error) - __pyx_v_bins_start_1 = __pyx_PyFloat_AsDouble(values[4]); if (unlikely((__pyx_v_bins_start_1 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 93, __pyx_L3_error) - __pyx_v_bins_end_1 = __pyx_PyFloat_AsDouble(values[5]); if (unlikely((__pyx_v_bins_end_1 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 93, __pyx_L3_error) - __pyx_v_nbins_2 = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_nbins_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 94, __pyx_L3_error) - __pyx_v_bins_start_2 = __pyx_PyFloat_AsDouble(values[7]); if (unlikely((__pyx_v_bins_start_2 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 94, __pyx_L3_error) - __pyx_v_bins_end_2 = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_bins_end_2 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 94, __pyx_L3_error) - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("histogram_cic_2d", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 89, __pyx_L3_error) - __pyx_L3_error:; - __Pyx_AddTraceback("opmd_viewer.openpmd_timeseries.cython_function.histogram_cic_2d", __pyx_clineno, __pyx_lineno, __pyx_filename); - __Pyx_RefNannyFinishContext(); - return NULL; - __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_q1), __pyx_ptype_5numpy_ndarray, 1, "q1", 0))) __PYX_ERR(0, 90, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_q2), __pyx_ptype_5numpy_ndarray, 1, "q2", 0))) __PYX_ERR(0, 91, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_w), __pyx_ptype_5numpy_ndarray, 1, "w", 0))) __PYX_ERR(0, 92, __pyx_L1_error) - __pyx_r = __pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_4histogram_cic_2d(__pyx_self, __pyx_v_q1, __pyx_v_q2, __pyx_v_w, __pyx_v_nbins_1, __pyx_v_bins_start_1, __pyx_v_bins_end_1, __pyx_v_nbins_2, __pyx_v_bins_start_2, __pyx_v_bins_end_2); - - /* function exit code */ - goto __pyx_L0; - __pyx_L1_error:; - __pyx_r = NULL; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyObject *__pyx_pf_11opmd_viewer_18openpmd_timeseries_15cython_function_4histogram_cic_2d(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_q1, PyArrayObject *__pyx_v_q2, PyArrayObject *__pyx_v_w, int __pyx_v_nbins_1, double __pyx_v_bins_start_1, double __pyx_v_bins_end_1, int __pyx_v_nbins_2, double __pyx_v_bins_start_2, double __pyx_v_bins_end_2) { - double __pyx_v_bin_spacing_1; - double __pyx_v_inv_spacing_1; - double __pyx_v_bin_spacing_2; - double __pyx_v_inv_spacing_2; - int __pyx_v_n_ptcl; - int __pyx_v_i1_low_bin; - int __pyx_v_i2_low_bin; - double __pyx_v_q1_cell; - double __pyx_v_q2_cell; - double __pyx_v_S1_low; - double __pyx_v_S2_low; - PyObject *__pyx_v_hist_data = NULL; - int __pyx_v_i; - __Pyx_LocalBuf_ND __pyx_pybuffernd_q1; - __Pyx_Buffer __pyx_pybuffer_q1; - __Pyx_LocalBuf_ND __pyx_pybuffernd_q2; - __Pyx_Buffer __pyx_pybuffer_q2; - __Pyx_LocalBuf_ND __pyx_pybuffernd_w; - __Pyx_Buffer __pyx_pybuffer_w; - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - double __pyx_t_1; - Py_ssize_t __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - int __pyx_t_8; - int __pyx_t_9; - Py_ssize_t __pyx_t_10; - Py_ssize_t __pyx_t_11; - int __pyx_t_12; - int __pyx_t_13; - Py_ssize_t __pyx_t_14; - Py_ssize_t __pyx_t_15; - Py_ssize_t __pyx_t_16; - Py_ssize_t __pyx_t_17; - __Pyx_RefNannySetupContext("histogram_cic_2d", 0); - __pyx_pybuffer_q1.pybuffer.buf = NULL; - __pyx_pybuffer_q1.refcount = 0; - __pyx_pybuffernd_q1.data = NULL; - __pyx_pybuffernd_q1.rcbuffer = &__pyx_pybuffer_q1; - __pyx_pybuffer_q2.pybuffer.buf = NULL; - __pyx_pybuffer_q2.refcount = 0; - __pyx_pybuffernd_q2.data = NULL; - __pyx_pybuffernd_q2.rcbuffer = &__pyx_pybuffer_q2; - __pyx_pybuffer_w.pybuffer.buf = NULL; - __pyx_pybuffer_w.refcount = 0; - __pyx_pybuffernd_w.data = NULL; - __pyx_pybuffernd_w.rcbuffer = &__pyx_pybuffer_w; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_q1.rcbuffer->pybuffer, (PyObject*)__pyx_v_q1, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 89, __pyx_L1_error) - } - __pyx_pybuffernd_q1.diminfo[0].strides = __pyx_pybuffernd_q1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_q1.diminfo[0].shape = __pyx_pybuffernd_q1.rcbuffer->pybuffer.shape[0]; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_q2.rcbuffer->pybuffer, (PyObject*)__pyx_v_q2, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 89, __pyx_L1_error) - } - __pyx_pybuffernd_q2.diminfo[0].strides = __pyx_pybuffernd_q2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_q2.diminfo[0].shape = __pyx_pybuffernd_q2.rcbuffer->pybuffer.shape[0]; - { - __Pyx_BufFmt_StackElem __pyx_stack[1]; - if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_w.rcbuffer->pybuffer, (PyObject*)__pyx_v_w, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 89, __pyx_L1_error) - } - __pyx_pybuffernd_w.diminfo[0].strides = __pyx_pybuffernd_w.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_w.diminfo[0].shape = __pyx_pybuffernd_w.rcbuffer->pybuffer.shape[0]; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":103 - * """ - * # Define various scalars - * cdef double bin_spacing_1 = (bins_end_1-bins_start_1)/nbins_1 # <<<<<<<<<<<<<< - * cdef double inv_spacing_1 = 1./bin_spacing_1 - * cdef double bin_spacing_2 = (bins_end_2-bins_start_2)/nbins_2 - */ - __pyx_t_1 = (__pyx_v_bins_end_1 - __pyx_v_bins_start_1); - if (unlikely(__pyx_v_nbins_1 == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "float division"); - __PYX_ERR(0, 103, __pyx_L1_error) - } - __pyx_v_bin_spacing_1 = (__pyx_t_1 / __pyx_v_nbins_1); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":104 - * # Define various scalars - * cdef double bin_spacing_1 = (bins_end_1-bins_start_1)/nbins_1 - * cdef double inv_spacing_1 = 1./bin_spacing_1 # <<<<<<<<<<<<<< - * cdef double bin_spacing_2 = (bins_end_2-bins_start_2)/nbins_2 - * cdef double inv_spacing_2 = 1./bin_spacing_2 - */ - if (unlikely(__pyx_v_bin_spacing_1 == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "float division"); - __PYX_ERR(0, 104, __pyx_L1_error) - } - __pyx_v_inv_spacing_1 = (1. / __pyx_v_bin_spacing_1); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":105 - * cdef double bin_spacing_1 = (bins_end_1-bins_start_1)/nbins_1 - * cdef double inv_spacing_1 = 1./bin_spacing_1 - * cdef double bin_spacing_2 = (bins_end_2-bins_start_2)/nbins_2 # <<<<<<<<<<<<<< - * cdef double inv_spacing_2 = 1./bin_spacing_2 - * cdef int n_ptcl = len(w) - */ - __pyx_t_1 = (__pyx_v_bins_end_2 - __pyx_v_bins_start_2); - if (unlikely(__pyx_v_nbins_2 == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "float division"); - __PYX_ERR(0, 105, __pyx_L1_error) - } - __pyx_v_bin_spacing_2 = (__pyx_t_1 / __pyx_v_nbins_2); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":106 - * cdef double inv_spacing_1 = 1./bin_spacing_1 - * cdef double bin_spacing_2 = (bins_end_2-bins_start_2)/nbins_2 - * cdef double inv_spacing_2 = 1./bin_spacing_2 # <<<<<<<<<<<<<< - * cdef int n_ptcl = len(w) - * cdef int i1_low_bin, i2_low_bin - */ - if (unlikely(__pyx_v_bin_spacing_2 == 0)) { - PyErr_SetString(PyExc_ZeroDivisionError, "float division"); - __PYX_ERR(0, 106, __pyx_L1_error) - } - __pyx_v_inv_spacing_2 = (1. / __pyx_v_bin_spacing_2); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":107 - * cdef double bin_spacing_2 = (bins_end_2-bins_start_2)/nbins_2 - * cdef double inv_spacing_2 = 1./bin_spacing_2 - * cdef int n_ptcl = len(w) # <<<<<<<<<<<<<< - * cdef int i1_low_bin, i2_low_bin - * cdef double q1_cell, q2_cell - */ - __pyx_t_2 = PyObject_Length(((PyObject *)__pyx_v_w)); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 107, __pyx_L1_error) - __pyx_v_n_ptcl = __pyx_t_2; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":113 - * - * # Allocate array for histogrammed data - * hist_data = np.zeros( (nbins_1, nbins_2), dtype=np.float64 ) # <<<<<<<<<<<<<< - * - * # Go through particle array and bin the data - */ - __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_zeros); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_nbins_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_nbins_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_3); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_5); - __pyx_t_3 = 0; - __pyx_t_5 = 0; - __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_6); - __pyx_t_6 = 0; - __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) __PYX_ERR(0, 113, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 113, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_v_hist_data = __pyx_t_7; - __pyx_t_7 = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":116 - * - * # Go through particle array and bin the data - * for i in xrange(n_ptcl): # <<<<<<<<<<<<<< - * - * # Calculate the index of lower bin to which this particle contributes - */ - __pyx_t_8 = __pyx_v_n_ptcl; - for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { - __pyx_v_i = __pyx_t_9; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":119 - * - * # Calculate the index of lower bin to which this particle contributes - * q1_cell = (q1[i] - bins_start_1) * inv_spacing_1 # <<<<<<<<<<<<<< - * q2_cell = (q2[i] - bins_start_2) * inv_spacing_2 - * i1_low_bin = floor( q1_cell ) - */ - __pyx_t_10 = __pyx_v_i; - __pyx_v_q1_cell = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_q1.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_q1.diminfo[0].strides)) - __pyx_v_bins_start_1) * __pyx_v_inv_spacing_1); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":120 - * # Calculate the index of lower bin to which this particle contributes - * q1_cell = (q1[i] - bins_start_1) * inv_spacing_1 - * q2_cell = (q2[i] - bins_start_2) * inv_spacing_2 # <<<<<<<<<<<<<< - * i1_low_bin = floor( q1_cell ) - * i2_low_bin = floor( q2_cell ) - */ - __pyx_t_11 = __pyx_v_i; - __pyx_v_q2_cell = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_q2.rcbuffer->pybuffer.buf, __pyx_t_11, __pyx_pybuffernd_q2.diminfo[0].strides)) - __pyx_v_bins_start_2) * __pyx_v_inv_spacing_2); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":121 - * q1_cell = (q1[i] - bins_start_1) * inv_spacing_1 - * q2_cell = (q2[i] - bins_start_2) * inv_spacing_2 - * i1_low_bin = floor( q1_cell ) # <<<<<<<<<<<<<< - * i2_low_bin = floor( q2_cell ) - * - */ - __pyx_v_i1_low_bin = ((int)floor(__pyx_v_q1_cell)); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":122 - * q2_cell = (q2[i] - bins_start_2) * inv_spacing_2 - * i1_low_bin = floor( q1_cell ) - * i2_low_bin = floor( q2_cell ) # <<<<<<<<<<<<<< - * - * # Calculate corresponding CIC shape and deposit the weight - */ - __pyx_v_i2_low_bin = ((int)floor(__pyx_v_q2_cell)); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":125 - * - * # Calculate corresponding CIC shape and deposit the weight - * S1_low = 1. - (q1_cell - i1_low_bin) # <<<<<<<<<<<<<< - * S2_low = 1. - (q2_cell - i2_low_bin) - * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): - */ - __pyx_v_S1_low = (1. - (__pyx_v_q1_cell - __pyx_v_i1_low_bin)); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":126 - * # Calculate corresponding CIC shape and deposit the weight - * S1_low = 1. - (q1_cell - i1_low_bin) - * S2_low = 1. - (q2_cell - i2_low_bin) # <<<<<<<<<<<<<< - * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - */ - __pyx_v_S2_low = (1. - (__pyx_v_q2_cell - __pyx_v_i2_low_bin)); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":127 - * S1_low = 1. - (q1_cell - i1_low_bin) - * S2_low = 1. - (q2_cell - i2_low_bin) - * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): # <<<<<<<<<<<<<< - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low - */ - __pyx_t_13 = ((__pyx_v_i1_low_bin >= 0) != 0); - if (__pyx_t_13) { - } else { - __pyx_t_12 = __pyx_t_13; - goto __pyx_L6_bool_binop_done; - } - __pyx_t_13 = ((__pyx_v_i1_low_bin < __pyx_v_nbins_1) != 0); - __pyx_t_12 = __pyx_t_13; - __pyx_L6_bool_binop_done:; - if (__pyx_t_12) { - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":128 - * S2_low = 1. - (q2_cell - i2_low_bin) - * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): # <<<<<<<<<<<<<< - * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): - */ - __pyx_t_13 = ((__pyx_v_i2_low_bin >= 0) != 0); - if (__pyx_t_13) { - } else { - __pyx_t_12 = __pyx_t_13; - goto __pyx_L9_bool_binop_done; - } - __pyx_t_13 = ((__pyx_v_i2_low_bin < __pyx_v_nbins_2) != 0); - __pyx_t_12 = __pyx_t_13; - __pyx_L9_bool_binop_done:; - if (__pyx_t_12) { - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":129 - * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low # <<<<<<<<<<<<<< - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): - * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) - */ - __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_i1_low_bin); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_i2_low_bin); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_6); - __pyx_t_7 = 0; - __pyx_t_6 = 0; - __pyx_t_6 = PyObject_GetItem(__pyx_v_hist_data, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_14 = __pyx_v_i; - __pyx_t_7 = PyFloat_FromDouble((((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_w.diminfo[0].strides)) * __pyx_v_S1_low) * __pyx_v_S2_low)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_hist_data, __pyx_t_5, __pyx_t_4) < 0)) __PYX_ERR(0, 129, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":128 - * S2_low = 1. - (q2_cell - i2_low_bin) - * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): # <<<<<<<<<<<<<< - * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): - */ - } - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":130 - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): # <<<<<<<<<<<<<< - * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) - * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): - */ - __pyx_t_13 = (((__pyx_v_i2_low_bin + 1) >= 0) != 0); - if (__pyx_t_13) { - } else { - __pyx_t_12 = __pyx_t_13; - goto __pyx_L12_bool_binop_done; - } - __pyx_t_13 = (((__pyx_v_i2_low_bin + 1) < __pyx_v_nbins_2) != 0); - __pyx_t_12 = __pyx_t_13; - __pyx_L12_bool_binop_done:; - if (__pyx_t_12) { - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":131 - * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): - * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) # <<<<<<<<<<<<<< - * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - */ - __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_i1_low_bin); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 131, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_4 = __Pyx_PyInt_From_long((__pyx_v_i2_low_bin + 1)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 131, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 131, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4); - __pyx_t_5 = 0; - __pyx_t_4 = 0; - __pyx_t_4 = PyObject_GetItem(__pyx_v_hist_data, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 131, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_15 = __pyx_v_i; - __pyx_t_5 = PyFloat_FromDouble((((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_w.diminfo[0].strides)) * __pyx_v_S1_low) * (1. - __pyx_v_S2_low))); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 131, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 131, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_hist_data, __pyx_t_7, __pyx_t_6) < 0)) __PYX_ERR(0, 131, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":130 - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): # <<<<<<<<<<<<<< - * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) - * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): - */ - } - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":127 - * S1_low = 1. - (q1_cell - i1_low_bin) - * S2_low = 1. - (q2_cell - i2_low_bin) - * if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): # <<<<<<<<<<<<<< - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - * hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low - */ - } - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":132 - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): - * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) - * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): # <<<<<<<<<<<<<< - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low - */ - __pyx_t_13 = (((__pyx_v_i1_low_bin + 1) >= 0) != 0); - if (__pyx_t_13) { - } else { - __pyx_t_12 = __pyx_t_13; - goto __pyx_L15_bool_binop_done; - } - __pyx_t_13 = (((__pyx_v_i1_low_bin + 1) < __pyx_v_nbins_1) != 0); - __pyx_t_12 = __pyx_t_13; - __pyx_L15_bool_binop_done:; - if (__pyx_t_12) { - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":133 - * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) - * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): # <<<<<<<<<<<<<< - * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): - */ - __pyx_t_13 = ((__pyx_v_i2_low_bin >= 0) != 0); - if (__pyx_t_13) { - } else { - __pyx_t_12 = __pyx_t_13; - goto __pyx_L18_bool_binop_done; - } - __pyx_t_13 = ((__pyx_v_i2_low_bin < __pyx_v_nbins_2) != 0); - __pyx_t_12 = __pyx_t_13; - __pyx_L18_bool_binop_done:; - if (__pyx_t_12) { - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":134 - * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low # <<<<<<<<<<<<<< - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): - * hist_data[ i1_low_bin+1, i2_low_bin+1 ] += w[i]*(1.-S1_low)*(1.-S2_low) - */ - __pyx_t_7 = __Pyx_PyInt_From_long((__pyx_v_i1_low_bin + 1)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 134, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_i2_low_bin); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 134, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 134, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GIVEREF(__pyx_t_7); - PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_6); - __pyx_t_7 = 0; - __pyx_t_6 = 0; - __pyx_t_6 = PyObject_GetItem(__pyx_v_hist_data, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 134, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_16 = __pyx_v_i; - __pyx_t_7 = PyFloat_FromDouble((((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_w.diminfo[0].strides)) * (1. - __pyx_v_S1_low)) * __pyx_v_S2_low)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 134, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 134, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_hist_data, __pyx_t_5, __pyx_t_4) < 0)) __PYX_ERR(0, 134, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":133 - * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) - * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): # <<<<<<<<<<<<<< - * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): - */ - } - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":135 - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): # <<<<<<<<<<<<<< - * hist_data[ i1_low_bin+1, i2_low_bin+1 ] += w[i]*(1.-S1_low)*(1.-S2_low) - * - */ - __pyx_t_13 = (((__pyx_v_i2_low_bin + 1) >= 0) != 0); - if (__pyx_t_13) { - } else { - __pyx_t_12 = __pyx_t_13; - goto __pyx_L21_bool_binop_done; - } - __pyx_t_13 = (((__pyx_v_i2_low_bin + 1) < __pyx_v_nbins_2) != 0); - __pyx_t_12 = __pyx_t_13; - __pyx_L21_bool_binop_done:; - if (__pyx_t_12) { - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":136 - * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): - * hist_data[ i1_low_bin+1, i2_low_bin+1 ] += w[i]*(1.-S1_low)*(1.-S2_low) # <<<<<<<<<<<<<< - * - * return( hist_data ) - */ - __pyx_t_5 = __Pyx_PyInt_From_long((__pyx_v_i1_low_bin + 1)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_4 = __Pyx_PyInt_From_long((__pyx_v_i2_low_bin + 1)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_GIVEREF(__pyx_t_5); - PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); - __Pyx_GIVEREF(__pyx_t_4); - PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4); - __pyx_t_5 = 0; - __pyx_t_4 = 0; - __pyx_t_4 = PyObject_GetItem(__pyx_v_hist_data, __pyx_t_7); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_17 = __pyx_v_i; - __pyx_t_5 = PyFloat_FromDouble((((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_w.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_w.diminfo[0].strides)) * (1. - __pyx_v_S1_low)) * (1. - __pyx_v_S2_low))); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - __pyx_t_6 = PyNumber_InPlaceAdd(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(PyObject_SetItem(__pyx_v_hist_data, __pyx_t_7, __pyx_t_6) < 0)) __PYX_ERR(0, 136, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":135 - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): # <<<<<<<<<<<<<< - * hist_data[ i1_low_bin+1, i2_low_bin+1 ] += w[i]*(1.-S1_low)*(1.-S2_low) - * - */ - } - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":132 - * if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): - * hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) - * if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): # <<<<<<<<<<<<<< - * if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - * hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low - */ - } - } - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":138 - * hist_data[ i1_low_bin+1, i2_low_bin+1 ] += w[i]*(1.-S1_low)*(1.-S2_low) - * - * return( hist_data ) # <<<<<<<<<<<<<< - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_v_hist_data); - __pyx_r = __pyx_v_hist_data; - goto __pyx_L0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":89 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * def histogram_cic_2d( # <<<<<<<<<<<<<< - * np.ndarray[np.float64_t, ndim=1] q1, - * np.ndarray[np.float64_t, ndim=1] q2, - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - { PyObject *__pyx_type, *__pyx_value, *__pyx_tb; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_q1.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_q2.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_w.rcbuffer->pybuffer); - __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("opmd_viewer.openpmd_timeseries.cython_function.histogram_cic_2d", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - goto __pyx_L2; - __pyx_L0:; - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_q1.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_q2.rcbuffer->pybuffer); - __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_w.rcbuffer->pybuffer); - __pyx_L2:; - __Pyx_XDECREF(__pyx_v_hist_data); - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":214 - * # experimental exception made for __getbuffer__ and __releasebuffer__ - * # -- the details of this may change. - * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< - * # This implementation of getbuffer is geared towards Cython - * # requirements, and does not yet fullfill the PEP. - */ - -/* Python wrapper */ -static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/ -static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_r; - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0); - __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) { - int __pyx_v_copy_shape; - int __pyx_v_i; - int __pyx_v_ndim; - int __pyx_v_endian_detector; - int __pyx_v_little_endian; - int __pyx_v_t; - char *__pyx_v_f; - PyArray_Descr *__pyx_v_descr = 0; - int __pyx_v_offset; - int __pyx_v_hasfields; - int __pyx_r; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - int __pyx_t_5; - PyObject *__pyx_t_6 = NULL; - char *__pyx_t_7; - __Pyx_RefNannySetupContext("__getbuffer__", 0); - if (__pyx_v_info != NULL) { - __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(__pyx_v_info->obj); - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":220 - * # of flags - * - * if info == NULL: return # <<<<<<<<<<<<<< - * - * cdef int copy_shape, i, ndim - */ - __pyx_t_1 = ((__pyx_v_info == NULL) != 0); - if (__pyx_t_1) { - __pyx_r = 0; - goto __pyx_L0; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":223 - * - * cdef int copy_shape, i, ndim - * cdef int endian_detector = 1 # <<<<<<<<<<<<<< - * cdef bint little_endian = ((&endian_detector)[0] != 0) - * - */ - __pyx_v_endian_detector = 1; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":224 - * cdef int copy_shape, i, ndim - * cdef int endian_detector = 1 - * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< - * - * ndim = PyArray_NDIM(self) - */ - __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":226 - * cdef bint little_endian = ((&endian_detector)[0] != 0) - * - * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<< - * - * if sizeof(npy_intp) != sizeof(Py_ssize_t): - */ - __pyx_v_ndim = PyArray_NDIM(__pyx_v_self); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":228 - * ndim = PyArray_NDIM(self) - * - * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< - * copy_shape = 1 - * else: - */ - __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); - if (__pyx_t_1) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":229 - * - * if sizeof(npy_intp) != sizeof(Py_ssize_t): - * copy_shape = 1 # <<<<<<<<<<<<<< - * else: - * copy_shape = 0 - */ - __pyx_v_copy_shape = 1; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":228 - * ndim = PyArray_NDIM(self) - * - * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< - * copy_shape = 1 - * else: - */ - goto __pyx_L4; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":231 - * copy_shape = 1 - * else: - * copy_shape = 0 # <<<<<<<<<<<<<< - * - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) - */ - /*else*/ { - __pyx_v_copy_shape = 0; - } - __pyx_L4:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":233 - * copy_shape = 0 - * - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< - * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): - * raise ValueError(u"ndarray is not C contiguous") - */ - __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L6_bool_binop_done; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":234 - * - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) - * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): # <<<<<<<<<<<<<< - * raise ValueError(u"ndarray is not C contiguous") - * - */ - __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L6_bool_binop_done:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":233 - * copy_shape = 0 - * - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< - * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): - * raise ValueError(u"ndarray is not C contiguous") - */ - if (__pyx_t_1) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":235 - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) - * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): - * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< - * - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 235, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 235, __pyx_L1_error) - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":233 - * copy_shape = 0 - * - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< - * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): - * raise ValueError(u"ndarray is not C contiguous") - */ - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":237 - * raise ValueError(u"ndarray is not C contiguous") - * - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< - * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): - * raise ValueError(u"ndarray is not Fortran contiguous") - */ - __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L9_bool_binop_done; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":238 - * - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) - * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): # <<<<<<<<<<<<<< - * raise ValueError(u"ndarray is not Fortran contiguous") - * - */ - __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L9_bool_binop_done:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":237 - * raise ValueError(u"ndarray is not C contiguous") - * - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< - * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): - * raise ValueError(u"ndarray is not Fortran contiguous") - */ - if (__pyx_t_1) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":239 - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) - * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): - * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< - * - * info.buf = PyArray_DATA(self) - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 239, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 239, __pyx_L1_error) - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":237 - * raise ValueError(u"ndarray is not C contiguous") - * - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< - * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): - * raise ValueError(u"ndarray is not Fortran contiguous") - */ - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":241 - * raise ValueError(u"ndarray is not Fortran contiguous") - * - * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<< - * info.ndim = ndim - * if copy_shape: - */ - __pyx_v_info->buf = PyArray_DATA(__pyx_v_self); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":242 - * - * info.buf = PyArray_DATA(self) - * info.ndim = ndim # <<<<<<<<<<<<<< - * if copy_shape: - * # Allocate new buffer for strides and shape info. - */ - __pyx_v_info->ndim = __pyx_v_ndim; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":243 - * info.buf = PyArray_DATA(self) - * info.ndim = ndim - * if copy_shape: # <<<<<<<<<<<<<< - * # Allocate new buffer for strides and shape info. - * # This is allocated as one block, strides first. - */ - __pyx_t_1 = (__pyx_v_copy_shape != 0); - if (__pyx_t_1) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":246 - * # Allocate new buffer for strides and shape info. - * # This is allocated as one block, strides first. - * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) # <<<<<<<<<<<<<< - * info.shape = info.strides + ndim - * for i in range(ndim): - */ - __pyx_v_info->strides = ((Py_ssize_t *)PyObject_Malloc((((sizeof(Py_ssize_t)) * 2) * ((size_t)__pyx_v_ndim)))); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":247 - * # This is allocated as one block, strides first. - * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) - * info.shape = info.strides + ndim # <<<<<<<<<<<<<< - * for i in range(ndim): - * info.strides[i] = PyArray_STRIDES(self)[i] - */ - __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":248 - * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) - * info.shape = info.strides + ndim - * for i in range(ndim): # <<<<<<<<<<<<<< - * info.strides[i] = PyArray_STRIDES(self)[i] - * info.shape[i] = PyArray_DIMS(self)[i] - */ - __pyx_t_4 = __pyx_v_ndim; - for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) { - __pyx_v_i = __pyx_t_5; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":249 - * info.shape = info.strides + ndim - * for i in range(ndim): - * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<< - * info.shape[i] = PyArray_DIMS(self)[i] - * else: - */ - (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":250 - * for i in range(ndim): - * info.strides[i] = PyArray_STRIDES(self)[i] - * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<< - * else: - * info.strides = PyArray_STRIDES(self) - */ - (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]); - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":243 - * info.buf = PyArray_DATA(self) - * info.ndim = ndim - * if copy_shape: # <<<<<<<<<<<<<< - * # Allocate new buffer for strides and shape info. - * # This is allocated as one block, strides first. - */ - goto __pyx_L11; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":252 - * info.shape[i] = PyArray_DIMS(self)[i] - * else: - * info.strides = PyArray_STRIDES(self) # <<<<<<<<<<<<<< - * info.shape = PyArray_DIMS(self) - * info.suboffsets = NULL - */ - /*else*/ { - __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self)); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":253 - * else: - * info.strides = PyArray_STRIDES(self) - * info.shape = PyArray_DIMS(self) # <<<<<<<<<<<<<< - * info.suboffsets = NULL - * info.itemsize = PyArray_ITEMSIZE(self) - */ - __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self)); - } - __pyx_L11:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":254 - * info.strides = PyArray_STRIDES(self) - * info.shape = PyArray_DIMS(self) - * info.suboffsets = NULL # <<<<<<<<<<<<<< - * info.itemsize = PyArray_ITEMSIZE(self) - * info.readonly = not PyArray_ISWRITEABLE(self) - */ - __pyx_v_info->suboffsets = NULL; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":255 - * info.shape = PyArray_DIMS(self) - * info.suboffsets = NULL - * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<< - * info.readonly = not PyArray_ISWRITEABLE(self) - * - */ - __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":256 - * info.suboffsets = NULL - * info.itemsize = PyArray_ITEMSIZE(self) - * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<< - * - * cdef int t - */ - __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0)); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":259 - * - * cdef int t - * cdef char* f = NULL # <<<<<<<<<<<<<< - * cdef dtype descr = self.descr - * cdef int offset - */ - __pyx_v_f = NULL; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":260 - * cdef int t - * cdef char* f = NULL - * cdef dtype descr = self.descr # <<<<<<<<<<<<<< - * cdef int offset - * - */ - __pyx_t_3 = ((PyObject *)__pyx_v_self->descr); - __Pyx_INCREF(__pyx_t_3); - __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3); - __pyx_t_3 = 0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":263 - * cdef int offset - * - * cdef bint hasfields = PyDataType_HASFIELDS(descr) # <<<<<<<<<<<<<< - * - * if not hasfields and not copy_shape: - */ - __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":265 - * cdef bint hasfields = PyDataType_HASFIELDS(descr) - * - * if not hasfields and not copy_shape: # <<<<<<<<<<<<<< - * # do not call releasebuffer - * info.obj = None - */ - __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L15_bool_binop_done; - } - __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L15_bool_binop_done:; - if (__pyx_t_1) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":267 - * if not hasfields and not copy_shape: - * # do not call releasebuffer - * info.obj = None # <<<<<<<<<<<<<< - * else: - * # need to call releasebuffer - */ - __Pyx_INCREF(Py_None); - __Pyx_GIVEREF(Py_None); - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); - __pyx_v_info->obj = Py_None; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":265 - * cdef bint hasfields = PyDataType_HASFIELDS(descr) - * - * if not hasfields and not copy_shape: # <<<<<<<<<<<<<< - * # do not call releasebuffer - * info.obj = None - */ - goto __pyx_L14; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":270 - * else: - * # need to call releasebuffer - * info.obj = self # <<<<<<<<<<<<<< - * - * if not hasfields: - */ - /*else*/ { - __Pyx_INCREF(((PyObject *)__pyx_v_self)); - __Pyx_GIVEREF(((PyObject *)__pyx_v_self)); - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); - __pyx_v_info->obj = ((PyObject *)__pyx_v_self); - } - __pyx_L14:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":272 - * info.obj = self - * - * if not hasfields: # <<<<<<<<<<<<<< - * t = descr.type_num - * if ((descr.byteorder == c'>' and little_endian) or - */ - __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0); - if (__pyx_t_1) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":273 - * - * if not hasfields: - * t = descr.type_num # <<<<<<<<<<<<<< - * if ((descr.byteorder == c'>' and little_endian) or - * (descr.byteorder == c'<' and not little_endian)): - */ - __pyx_t_4 = __pyx_v_descr->type_num; - __pyx_v_t = __pyx_t_4; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":274 - * if not hasfields: - * t = descr.type_num - * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (descr.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0); - if (!__pyx_t_2) { - goto __pyx_L20_next_or; - } else { - } - __pyx_t_2 = (__pyx_v_little_endian != 0); - if (!__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L19_bool_binop_done; - } - __pyx_L20_next_or:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":275 - * t = descr.type_num - * if ((descr.byteorder == c'>' and little_endian) or - * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< - * raise ValueError(u"Non-native byte order not supported") - * if t == NPY_BYTE: f = "b" - */ - __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0); - if (__pyx_t_2) { - } else { - __pyx_t_1 = __pyx_t_2; - goto __pyx_L19_bool_binop_done; - } - __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0); - __pyx_t_1 = __pyx_t_2; - __pyx_L19_bool_binop_done:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":274 - * if not hasfields: - * t = descr.type_num - * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (descr.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - if (__pyx_t_1) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":276 - * if ((descr.byteorder == c'>' and little_endian) or - * (descr.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< - * if t == NPY_BYTE: f = "b" - * elif t == NPY_UBYTE: f = "B" - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 276, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 276, __pyx_L1_error) - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":274 - * if not hasfields: - * t = descr.type_num - * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (descr.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":277 - * (descr.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<< - * elif t == NPY_UBYTE: f = "B" - * elif t == NPY_SHORT: f = "h" - */ - switch (__pyx_v_t) { - case NPY_BYTE: - __pyx_v_f = ((char *)"b"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":278 - * raise ValueError(u"Non-native byte order not supported") - * if t == NPY_BYTE: f = "b" - * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<< - * elif t == NPY_SHORT: f = "h" - * elif t == NPY_USHORT: f = "H" - */ - case NPY_UBYTE: - __pyx_v_f = ((char *)"B"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":279 - * if t == NPY_BYTE: f = "b" - * elif t == NPY_UBYTE: f = "B" - * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<< - * elif t == NPY_USHORT: f = "H" - * elif t == NPY_INT: f = "i" - */ - case NPY_SHORT: - __pyx_v_f = ((char *)"h"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":280 - * elif t == NPY_UBYTE: f = "B" - * elif t == NPY_SHORT: f = "h" - * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<< - * elif t == NPY_INT: f = "i" - * elif t == NPY_UINT: f = "I" - */ - case NPY_USHORT: - __pyx_v_f = ((char *)"H"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":281 - * elif t == NPY_SHORT: f = "h" - * elif t == NPY_USHORT: f = "H" - * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<< - * elif t == NPY_UINT: f = "I" - * elif t == NPY_LONG: f = "l" - */ - case NPY_INT: - __pyx_v_f = ((char *)"i"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":282 - * elif t == NPY_USHORT: f = "H" - * elif t == NPY_INT: f = "i" - * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<< - * elif t == NPY_LONG: f = "l" - * elif t == NPY_ULONG: f = "L" - */ - case NPY_UINT: - __pyx_v_f = ((char *)"I"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":283 - * elif t == NPY_INT: f = "i" - * elif t == NPY_UINT: f = "I" - * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<< - * elif t == NPY_ULONG: f = "L" - * elif t == NPY_LONGLONG: f = "q" - */ - case NPY_LONG: - __pyx_v_f = ((char *)"l"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":284 - * elif t == NPY_UINT: f = "I" - * elif t == NPY_LONG: f = "l" - * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<< - * elif t == NPY_LONGLONG: f = "q" - * elif t == NPY_ULONGLONG: f = "Q" - */ - case NPY_ULONG: - __pyx_v_f = ((char *)"L"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":285 - * elif t == NPY_LONG: f = "l" - * elif t == NPY_ULONG: f = "L" - * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<< - * elif t == NPY_ULONGLONG: f = "Q" - * elif t == NPY_FLOAT: f = "f" - */ - case NPY_LONGLONG: - __pyx_v_f = ((char *)"q"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":286 - * elif t == NPY_ULONG: f = "L" - * elif t == NPY_LONGLONG: f = "q" - * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<< - * elif t == NPY_FLOAT: f = "f" - * elif t == NPY_DOUBLE: f = "d" - */ - case NPY_ULONGLONG: - __pyx_v_f = ((char *)"Q"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":287 - * elif t == NPY_LONGLONG: f = "q" - * elif t == NPY_ULONGLONG: f = "Q" - * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<< - * elif t == NPY_DOUBLE: f = "d" - * elif t == NPY_LONGDOUBLE: f = "g" - */ - case NPY_FLOAT: - __pyx_v_f = ((char *)"f"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":288 - * elif t == NPY_ULONGLONG: f = "Q" - * elif t == NPY_FLOAT: f = "f" - * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<< - * elif t == NPY_LONGDOUBLE: f = "g" - * elif t == NPY_CFLOAT: f = "Zf" - */ - case NPY_DOUBLE: - __pyx_v_f = ((char *)"d"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":289 - * elif t == NPY_FLOAT: f = "f" - * elif t == NPY_DOUBLE: f = "d" - * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<< - * elif t == NPY_CFLOAT: f = "Zf" - * elif t == NPY_CDOUBLE: f = "Zd" - */ - case NPY_LONGDOUBLE: - __pyx_v_f = ((char *)"g"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":290 - * elif t == NPY_DOUBLE: f = "d" - * elif t == NPY_LONGDOUBLE: f = "g" - * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<< - * elif t == NPY_CDOUBLE: f = "Zd" - * elif t == NPY_CLONGDOUBLE: f = "Zg" - */ - case NPY_CFLOAT: - __pyx_v_f = ((char *)"Zf"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":291 - * elif t == NPY_LONGDOUBLE: f = "g" - * elif t == NPY_CFLOAT: f = "Zf" - * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<< - * elif t == NPY_CLONGDOUBLE: f = "Zg" - * elif t == NPY_OBJECT: f = "O" - */ - case NPY_CDOUBLE: - __pyx_v_f = ((char *)"Zd"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":292 - * elif t == NPY_CFLOAT: f = "Zf" - * elif t == NPY_CDOUBLE: f = "Zd" - * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<< - * elif t == NPY_OBJECT: f = "O" - * else: - */ - case NPY_CLONGDOUBLE: - __pyx_v_f = ((char *)"Zg"); - break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":293 - * elif t == NPY_CDOUBLE: f = "Zd" - * elif t == NPY_CLONGDOUBLE: f = "Zg" - * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<< - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) - */ - case NPY_OBJECT: - __pyx_v_f = ((char *)"O"); - break; - default: - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":295 - * elif t == NPY_OBJECT: f = "O" - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< - * info.format = f - * return - */ - __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 295, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 295, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 295, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_GIVEREF(__pyx_t_6); - PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6); - __pyx_t_6 = 0; - __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 295, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_Raise(__pyx_t_6, 0, 0, 0); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __PYX_ERR(1, 295, __pyx_L1_error) - break; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":296 - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) - * info.format = f # <<<<<<<<<<<<<< - * return - * else: - */ - __pyx_v_info->format = __pyx_v_f; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":297 - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) - * info.format = f - * return # <<<<<<<<<<<<<< - * else: - * info.format = PyObject_Malloc(_buffer_format_string_len) - */ - __pyx_r = 0; - goto __pyx_L0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":272 - * info.obj = self - * - * if not hasfields: # <<<<<<<<<<<<<< - * t = descr.type_num - * if ((descr.byteorder == c'>' and little_endian) or - */ - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":299 - * return - * else: - * info.format = PyObject_Malloc(_buffer_format_string_len) # <<<<<<<<<<<<<< - * info.format[0] = c'^' # Native data types, manual alignment - * offset = 0 - */ - /*else*/ { - __pyx_v_info->format = ((char *)PyObject_Malloc(0xFF)); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":300 - * else: - * info.format = PyObject_Malloc(_buffer_format_string_len) - * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<< - * offset = 0 - * f = _util_dtypestring(descr, info.format + 1, - */ - (__pyx_v_info->format[0]) = '^'; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":301 - * info.format = PyObject_Malloc(_buffer_format_string_len) - * info.format[0] = c'^' # Native data types, manual alignment - * offset = 0 # <<<<<<<<<<<<<< - * f = _util_dtypestring(descr, info.format + 1, - * info.format + _buffer_format_string_len, - */ - __pyx_v_offset = 0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":302 - * info.format[0] = c'^' # Native data types, manual alignment - * offset = 0 - * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<< - * info.format + _buffer_format_string_len, - * &offset) - */ - __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 0xFF), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == ((char *)NULL))) __PYX_ERR(1, 302, __pyx_L1_error) - __pyx_v_f = __pyx_t_7; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":305 - * info.format + _buffer_format_string_len, - * &offset) - * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<< - * - * def __releasebuffer__(ndarray self, Py_buffer* info): - */ - (__pyx_v_f[0]) = '\x00'; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":214 - * # experimental exception made for __getbuffer__ and __releasebuffer__ - * # -- the details of this may change. - * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< - * # This implementation of getbuffer is geared towards Cython - * # requirements, and does not yet fullfill the PEP. - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) { - __Pyx_GOTREF(__pyx_v_info->obj); - __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL; - } - goto __pyx_L2; - __pyx_L0:; - if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) { - __Pyx_GOTREF(Py_None); - __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL; - } - __pyx_L2:; - __Pyx_XDECREF((PyObject *)__pyx_v_descr); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":307 - * f[0] = c'\0' # Terminate format string - * - * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< - * if PyArray_HASFIELDS(self): - * PyObject_Free(info.format) - */ - -/* Python wrapper */ -static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/ -static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0); - __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info)); - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) { - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("__releasebuffer__", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":308 - * - * def __releasebuffer__(ndarray self, Py_buffer* info): - * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< - * PyObject_Free(info.format) - * if sizeof(npy_intp) != sizeof(Py_ssize_t): - */ - __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0); - if (__pyx_t_1) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":309 - * def __releasebuffer__(ndarray self, Py_buffer* info): - * if PyArray_HASFIELDS(self): - * PyObject_Free(info.format) # <<<<<<<<<<<<<< - * if sizeof(npy_intp) != sizeof(Py_ssize_t): - * PyObject_Free(info.strides) - */ - PyObject_Free(__pyx_v_info->format); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":308 - * - * def __releasebuffer__(ndarray self, Py_buffer* info): - * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< - * PyObject_Free(info.format) - * if sizeof(npy_intp) != sizeof(Py_ssize_t): - */ - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":310 - * if PyArray_HASFIELDS(self): - * PyObject_Free(info.format) - * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< - * PyObject_Free(info.strides) - * # info.shape was stored after info.strides in the same block - */ - __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); - if (__pyx_t_1) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":311 - * PyObject_Free(info.format) - * if sizeof(npy_intp) != sizeof(Py_ssize_t): - * PyObject_Free(info.strides) # <<<<<<<<<<<<<< - * # info.shape was stored after info.strides in the same block - * - */ - PyObject_Free(__pyx_v_info->strides); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":310 - * if PyArray_HASFIELDS(self): - * PyObject_Free(info.format) - * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< - * PyObject_Free(info.strides) - * # info.shape was stored after info.strides in the same block - */ - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":307 - * f[0] = c'\0' # Terminate format string - * - * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< - * if PyArray_HASFIELDS(self): - * PyObject_Free(info.format) - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":788 - * ctypedef npy_cdouble complex_t - * - * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(1, a) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":789 - * - * cdef inline object PyArray_MultiIterNew1(a): - * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew2(a, b): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 789, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":788 - * ctypedef npy_cdouble complex_t - * - * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(1, a) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":791 - * return PyArray_MultiIterNew(1, a) - * - * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(2, a, b) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":792 - * - * cdef inline object PyArray_MultiIterNew2(a, b): - * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 792, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":791 - * return PyArray_MultiIterNew(1, a) - * - * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(2, a, b) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":794 - * return PyArray_MultiIterNew(2, a, b) - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(3, a, b, c) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":795 - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): - * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 795, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":794 - * return PyArray_MultiIterNew(2, a, b) - * - * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(3, a, b, c) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":797 - * return PyArray_MultiIterNew(3, a, b, c) - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(4, a, b, c, d) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":798 - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): - * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 798, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":797 - * return PyArray_MultiIterNew(3, a, b, c) - * - * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(4, a, b, c, d) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":800 - * return PyArray_MultiIterNew(4, a, b, c, d) - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":801 - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): - * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< - * - * cdef inline tuple PyDataType_SHAPE(dtype d): - */ - __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 801, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __pyx_r = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":800 - * return PyArray_MultiIterNew(4, a, b, c, d) - * - * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = 0; - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":803 - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__pyx_v_d) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("PyDataType_SHAPE", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":804 - * - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< - * return d.subarray.shape - * else: - */ - __pyx_t_1 = (PyDataType_HASSUBARRAY(__pyx_v_d) != 0); - if (__pyx_t_1) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":805 - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape # <<<<<<<<<<<<<< - * else: - * return () - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject*)__pyx_v_d->subarray->shape)); - __pyx_r = ((PyObject*)__pyx_v_d->subarray->shape); - goto __pyx_L0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":804 - * - * cdef inline tuple PyDataType_SHAPE(dtype d): - * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< - * return d.subarray.shape - * else: - */ - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":807 - * return d.subarray.shape - * else: - * return () # <<<<<<<<<<<<<< - * - * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(__pyx_empty_tuple); - __pyx_r = __pyx_empty_tuple; - goto __pyx_L0; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":803 - * return PyArray_MultiIterNew(5, a, b, c, d, e) - * - * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< - * if PyDataType_HASSUBARRAY(d): - * return d.subarray.shape - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":809 - * return () - * - * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< - * # Recursive utility function used in __getbuffer__ to get format - * # string. The new location in the format string is returned. - */ - -static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) { - PyArray_Descr *__pyx_v_child = 0; - int __pyx_v_endian_detector; - int __pyx_v_little_endian; - PyObject *__pyx_v_fields = 0; - PyObject *__pyx_v_childname = NULL; - PyObject *__pyx_v_new_offset = NULL; - PyObject *__pyx_v_t = NULL; - char *__pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - Py_ssize_t __pyx_t_2; - PyObject *__pyx_t_3 = NULL; - PyObject *__pyx_t_4 = NULL; - int __pyx_t_5; - int __pyx_t_6; - int __pyx_t_7; - long __pyx_t_8; - char *__pyx_t_9; - __Pyx_RefNannySetupContext("_util_dtypestring", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":814 - * - * cdef dtype child - * cdef int endian_detector = 1 # <<<<<<<<<<<<<< - * cdef bint little_endian = ((&endian_detector)[0] != 0) - * cdef tuple fields - */ - __pyx_v_endian_detector = 1; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":815 - * cdef dtype child - * cdef int endian_detector = 1 - * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< - * cdef tuple fields - * - */ - __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":818 - * cdef tuple fields - * - * for childname in descr.names: # <<<<<<<<<<<<<< - * fields = descr.fields[childname] - * child, new_offset = fields - */ - if (unlikely(__pyx_v_descr->names == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); - __PYX_ERR(1, 818, __pyx_L1_error) - } - __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; - for (;;) { - if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break; - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(1, 818, __pyx_L1_error) - #else - __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 818, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - #endif - __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3); - __pyx_t_3 = 0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":819 - * - * for childname in descr.names: - * fields = descr.fields[childname] # <<<<<<<<<<<<<< - * child, new_offset = fields - * - */ - if (unlikely(__pyx_v_descr->fields == Py_None)) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); - __PYX_ERR(1, 819, __pyx_L1_error) - } - __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 819, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) __PYX_ERR(1, 819, __pyx_L1_error) - __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3)); - __pyx_t_3 = 0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":820 - * for childname in descr.names: - * fields = descr.fields[childname] - * child, new_offset = fields # <<<<<<<<<<<<<< - * - * if (end - f) - (new_offset - offset[0]) < 15: - */ - if (likely(__pyx_v_fields != Py_None)) { - PyObject* sequence = __pyx_v_fields; - #if !CYTHON_COMPILING_IN_PYPY - Py_ssize_t size = Py_SIZE(sequence); - #else - Py_ssize_t size = PySequence_Size(sequence); - #endif - if (unlikely(size != 2)) { - if (size > 2) __Pyx_RaiseTooManyValuesError(2); - else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); - __PYX_ERR(1, 820, __pyx_L1_error) - } - #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); - __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); - __Pyx_INCREF(__pyx_t_3); - __Pyx_INCREF(__pyx_t_4); - #else - __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 820, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 820, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - #endif - } else { - __Pyx_RaiseNoneNotIterableError(); __PYX_ERR(1, 820, __pyx_L1_error) - } - if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) __PYX_ERR(1, 820, __pyx_L1_error) - __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3)); - __pyx_t_3 = 0; - __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4); - __pyx_t_4 = 0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":822 - * child, new_offset = fields - * - * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - */ - __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 822, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 822, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 822, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0); - if (__pyx_t_6) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":823 - * - * if (end - f) - (new_offset - offset[0]) < 15: - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< - * - * if ((child.byteorder == c'>' and little_endian) or - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 823, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 823, __pyx_L1_error) - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":822 - * child, new_offset = fields - * - * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - */ - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":825 - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0); - if (!__pyx_t_7) { - goto __pyx_L8_next_or; - } else { - } - __pyx_t_7 = (__pyx_v_little_endian != 0); - if (!__pyx_t_7) { - } else { - __pyx_t_6 = __pyx_t_7; - goto __pyx_L7_bool_binop_done; - } - __pyx_L8_next_or:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":826 - * - * if ((child.byteorder == c'>' and little_endian) or - * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< - * raise ValueError(u"Non-native byte order not supported") - * # One could encode it in the format string and have Cython - */ - __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0); - if (__pyx_t_7) { - } else { - __pyx_t_6 = __pyx_t_7; - goto __pyx_L7_bool_binop_done; - } - __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0); - __pyx_t_6 = __pyx_t_7; - __pyx_L7_bool_binop_done:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":825 - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - if (__pyx_t_6) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":827 - * if ((child.byteorder == c'>' and little_endian) or - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< - * # One could encode it in the format string and have Cython - * # complain instead, BUT: < and > in format strings also imply - */ - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 827, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 827, __pyx_L1_error) - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":825 - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") - * - * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") - */ - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":837 - * - * # Output padding bytes - * while offset[0] < new_offset: # <<<<<<<<<<<<<< - * f[0] = 120 # "x"; pad byte - * f += 1 - */ - while (1) { - __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 837, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 837, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 837, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (!__pyx_t_6) break; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":838 - * # Output padding bytes - * while offset[0] < new_offset: - * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<< - * f += 1 - * offset[0] += 1 - */ - (__pyx_v_f[0]) = 0x78; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":839 - * while offset[0] < new_offset: - * f[0] = 120 # "x"; pad byte - * f += 1 # <<<<<<<<<<<<<< - * offset[0] += 1 - * - */ - __pyx_v_f = (__pyx_v_f + 1); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":840 - * f[0] = 120 # "x"; pad byte - * f += 1 - * offset[0] += 1 # <<<<<<<<<<<<<< - * - * offset[0] += child.itemsize - */ - __pyx_t_8 = 0; - (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1); - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":842 - * offset[0] += 1 - * - * offset[0] += child.itemsize # <<<<<<<<<<<<<< - * - * if not PyDataType_HASFIELDS(child): - */ - __pyx_t_8 = 0; - (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":844 - * offset[0] += child.itemsize - * - * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< - * t = child.type_num - * if end - f < 5: - */ - __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0); - if (__pyx_t_6) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":845 - * - * if not PyDataType_HASFIELDS(child): - * t = child.type_num # <<<<<<<<<<<<<< - * if end - f < 5: - * raise RuntimeError(u"Format string allocated too short.") - */ - __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 845, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4); - __pyx_t_4 = 0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":846 - * if not PyDataType_HASFIELDS(child): - * t = child.type_num - * if end - f < 5: # <<<<<<<<<<<<<< - * raise RuntimeError(u"Format string allocated too short.") - * - */ - __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0); - if (__pyx_t_6) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":847 - * t = child.type_num - * if end - f < 5: - * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< - * - * # Until ticket #99 is fixed, use integers to avoid warnings - */ - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 847, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_Raise(__pyx_t_4, 0, 0, 0); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __PYX_ERR(1, 847, __pyx_L1_error) - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":846 - * if not PyDataType_HASFIELDS(child): - * t = child.type_num - * if end - f < 5: # <<<<<<<<<<<<<< - * raise RuntimeError(u"Format string allocated too short.") - * - */ - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":850 - * - * # Until ticket #99 is fixed, use integers to avoid warnings - * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<< - * elif t == NPY_UBYTE: f[0] = 66 #"B" - * elif t == NPY_SHORT: f[0] = 104 #"h" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_BYTE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 850, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 850, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 850, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 98; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":851 - * # Until ticket #99 is fixed, use integers to avoid warnings - * if t == NPY_BYTE: f[0] = 98 #"b" - * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<< - * elif t == NPY_SHORT: f[0] = 104 #"h" - * elif t == NPY_USHORT: f[0] = 72 #"H" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UBYTE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 851, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 851, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 851, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 66; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":852 - * if t == NPY_BYTE: f[0] = 98 #"b" - * elif t == NPY_UBYTE: f[0] = 66 #"B" - * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<< - * elif t == NPY_USHORT: f[0] = 72 #"H" - * elif t == NPY_INT: f[0] = 105 #"i" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_SHORT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 852, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 852, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 852, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x68; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":853 - * elif t == NPY_UBYTE: f[0] = 66 #"B" - * elif t == NPY_SHORT: f[0] = 104 #"h" - * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<< - * elif t == NPY_INT: f[0] = 105 #"i" - * elif t == NPY_UINT: f[0] = 73 #"I" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_USHORT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 853, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 853, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 853, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 72; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":854 - * elif t == NPY_SHORT: f[0] = 104 #"h" - * elif t == NPY_USHORT: f[0] = 72 #"H" - * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<< - * elif t == NPY_UINT: f[0] = 73 #"I" - * elif t == NPY_LONG: f[0] = 108 #"l" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_INT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 854, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 854, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 854, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x69; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":855 - * elif t == NPY_USHORT: f[0] = 72 #"H" - * elif t == NPY_INT: f[0] = 105 #"i" - * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<< - * elif t == NPY_LONG: f[0] = 108 #"l" - * elif t == NPY_ULONG: f[0] = 76 #"L" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UINT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 855, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 855, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 855, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 73; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":856 - * elif t == NPY_INT: f[0] = 105 #"i" - * elif t == NPY_UINT: f[0] = 73 #"I" - * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<< - * elif t == NPY_ULONG: f[0] = 76 #"L" - * elif t == NPY_LONGLONG: f[0] = 113 #"q" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 856, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 856, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 856, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x6C; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":857 - * elif t == NPY_UINT: f[0] = 73 #"I" - * elif t == NPY_LONG: f[0] = 108 #"l" - * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<< - * elif t == NPY_LONGLONG: f[0] = 113 #"q" - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 857, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 857, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 857, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 76; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":858 - * elif t == NPY_LONG: f[0] = 108 #"l" - * elif t == NPY_ULONG: f[0] = 76 #"L" - * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<< - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" - * elif t == NPY_FLOAT: f[0] = 102 #"f" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 858, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 858, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 858, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x71; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":859 - * elif t == NPY_ULONG: f[0] = 76 #"L" - * elif t == NPY_LONGLONG: f[0] = 113 #"q" - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<< - * elif t == NPY_FLOAT: f[0] = 102 #"f" - * elif t == NPY_DOUBLE: f[0] = 100 #"d" - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 859, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 859, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 859, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 81; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":860 - * elif t == NPY_LONGLONG: f[0] = 113 #"q" - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" - * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<< - * elif t == NPY_DOUBLE: f[0] = 100 #"d" - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_FLOAT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 860, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 860, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 860, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x66; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":861 - * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" - * elif t == NPY_FLOAT: f[0] = 102 #"f" - * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<< - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 861, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 861, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 861, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x64; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":862 - * elif t == NPY_FLOAT: f[0] = 102 #"f" - * elif t == NPY_DOUBLE: f[0] = 100 #"d" - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<< - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 862, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 862, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 862, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 0x67; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":863 - * elif t == NPY_DOUBLE: f[0] = 100 #"d" - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<< - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd - * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 863, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 863, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 863, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 90; - (__pyx_v_f[1]) = 0x66; - __pyx_v_f = (__pyx_v_f + 1); - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":864 - * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<< - * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg - * elif t == NPY_OBJECT: f[0] = 79 #"O" - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 864, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 864, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 864, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 90; - (__pyx_v_f[1]) = 0x64; - __pyx_v_f = (__pyx_v_f + 1); - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":865 - * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd - * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<< - * elif t == NPY_OBJECT: f[0] = 79 #"O" - * else: - */ - __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 865, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 865, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 865, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 90; - (__pyx_v_f[1]) = 0x67; - __pyx_v_f = (__pyx_v_f + 1); - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":866 - * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd - * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg - * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<< - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) - */ - __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_OBJECT); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 866, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 866, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(1, 866, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (__pyx_t_6) { - (__pyx_v_f[0]) = 79; - goto __pyx_L15; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":868 - * elif t == NPY_OBJECT: f[0] = 79 #"O" - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< - * f += 1 - * else: - */ - /*else*/ { - __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 868, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 868, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __Pyx_GIVEREF(__pyx_t_3); - PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); - __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 868, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_Raise(__pyx_t_3, 0, 0, 0); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __PYX_ERR(1, 868, __pyx_L1_error) - } - __pyx_L15:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":869 - * else: - * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) - * f += 1 # <<<<<<<<<<<<<< - * else: - * # Cython ignores struct boundary information ("T{...}"), - */ - __pyx_v_f = (__pyx_v_f + 1); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":844 - * offset[0] += child.itemsize - * - * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< - * t = child.type_num - * if end - f < 5: - */ - goto __pyx_L13; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":873 - * # Cython ignores struct boundary information ("T{...}"), - * # so don't output it - * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<< - * return f - * - */ - /*else*/ { - __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == ((char *)NULL))) __PYX_ERR(1, 873, __pyx_L1_error) - __pyx_v_f = __pyx_t_9; - } - __pyx_L13:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":818 - * cdef tuple fields - * - * for childname in descr.names: # <<<<<<<<<<<<<< - * fields = descr.fields[childname] - * child, new_offset = fields - */ - } - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":874 - * # so don't output it - * f = _util_dtypestring(child, f, end, offset) - * return f # <<<<<<<<<<<<<< - * - * - */ - __pyx_r = __pyx_v_f; - goto __pyx_L0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":809 - * return () - * - * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< - * # Recursive utility function used in __getbuffer__ to get format - * # string. The new location in the format string is returned. - */ - - /* function exit code */ - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - __Pyx_XDECREF(__pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = NULL; - __pyx_L0:; - __Pyx_XDECREF((PyObject *)__pyx_v_child); - __Pyx_XDECREF(__pyx_v_fields); - __Pyx_XDECREF(__pyx_v_childname); - __Pyx_XDECREF(__pyx_v_new_offset); - __Pyx_XDECREF(__pyx_v_t); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":990 - * - * - * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< - * cdef PyObject* baseptr - * if base is None: - */ - -static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) { - PyObject *__pyx_v_baseptr; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - int __pyx_t_2; - __Pyx_RefNannySetupContext("set_array_base", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":992 - * cdef inline void set_array_base(ndarray arr, object base): - * cdef PyObject* baseptr - * if base is None: # <<<<<<<<<<<<<< - * baseptr = NULL - * else: - */ - __pyx_t_1 = (__pyx_v_base == Py_None); - __pyx_t_2 = (__pyx_t_1 != 0); - if (__pyx_t_2) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":993 - * cdef PyObject* baseptr - * if base is None: - * baseptr = NULL # <<<<<<<<<<<<<< - * else: - * Py_INCREF(base) # important to do this before decref below! - */ - __pyx_v_baseptr = NULL; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":992 - * cdef inline void set_array_base(ndarray arr, object base): - * cdef PyObject* baseptr - * if base is None: # <<<<<<<<<<<<<< - * baseptr = NULL - * else: - */ - goto __pyx_L3; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":995 - * baseptr = NULL - * else: - * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<< - * baseptr = base - * Py_XDECREF(arr.base) - */ - /*else*/ { - Py_INCREF(__pyx_v_base); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":996 - * else: - * Py_INCREF(base) # important to do this before decref below! - * baseptr = base # <<<<<<<<<<<<<< - * Py_XDECREF(arr.base) - * arr.base = baseptr - */ - __pyx_v_baseptr = ((PyObject *)__pyx_v_base); - } - __pyx_L3:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":997 - * Py_INCREF(base) # important to do this before decref below! - * baseptr = base - * Py_XDECREF(arr.base) # <<<<<<<<<<<<<< - * arr.base = baseptr - * - */ - Py_XDECREF(__pyx_v_arr->base); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":998 - * baseptr = base - * Py_XDECREF(arr.base) - * arr.base = baseptr # <<<<<<<<<<<<<< - * - * cdef inline object get_array_base(ndarray arr): - */ - __pyx_v_arr->base = __pyx_v_baseptr; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":990 - * - * - * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< - * cdef PyObject* baseptr - * if base is None: - */ - - /* function exit code */ - __Pyx_RefNannyFinishContext(); -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1000 - * arr.base = baseptr - * - * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< - * if arr.base is NULL: - * return None - */ - -static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) { - PyObject *__pyx_r = NULL; - __Pyx_RefNannyDeclarations - int __pyx_t_1; - __Pyx_RefNannySetupContext("get_array_base", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1001 - * - * cdef inline object get_array_base(ndarray arr): - * if arr.base is NULL: # <<<<<<<<<<<<<< - * return None - * else: - */ - __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0); - if (__pyx_t_1) { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1002 - * cdef inline object get_array_base(ndarray arr): - * if arr.base is NULL: - * return None # <<<<<<<<<<<<<< - * else: - * return arr.base - */ - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(Py_None); - __pyx_r = Py_None; - goto __pyx_L0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1001 - * - * cdef inline object get_array_base(ndarray arr): - * if arr.base is NULL: # <<<<<<<<<<<<<< - * return None - * else: - */ - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1004 - * return None - * else: - * return arr.base # <<<<<<<<<<<<<< - * - * - */ - /*else*/ { - __Pyx_XDECREF(__pyx_r); - __Pyx_INCREF(((PyObject *)__pyx_v_arr->base)); - __pyx_r = ((PyObject *)__pyx_v_arr->base); - goto __pyx_L0; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1000 - * arr.base = baseptr - * - * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< - * if arr.base is NULL: - * return None - */ - - /* function exit code */ - __pyx_L0:; - __Pyx_XGIVEREF(__pyx_r); - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1009 - * # Versions of the import_* functions which are more suitable for - * # Cython code. - * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< - * try: - * _import_array() - */ - -static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - __Pyx_RefNannySetupContext("import_array", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1010 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * _import_array() - * except Exception: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1011 - * cdef inline int import_array() except -1: - * try: - * _import_array() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") - */ - __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 1011, __pyx_L3_error) - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1010 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * _import_array() - * except Exception: - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1012 - * try: - * _import_array() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.multiarray failed to import") - * - */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 1012, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1013 - * _import_array() - * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_umath() except -1: - */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 1013, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(1, 1013, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1010 - * # Cython code. - * cdef inline int import_array() except -1: - * try: # <<<<<<<<<<<<<< - * _import_array() - * except Exception: - */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1009 - * # Versions of the import_* functions which are more suitable for - * # Cython code. - * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< - * try: - * _import_array() - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1015 - * raise ImportError("numpy.core.multiarray failed to import") - * - * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - -static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - __Pyx_RefNannySetupContext("import_umath", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1016 - * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1017 - * cdef inline int import_umath() except -1: - * try: - * _import_umath() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy.core.umath failed to import") - */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 1017, __pyx_L3_error) - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1016 - * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1018 - * try: - * _import_umath() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.umath failed to import") - * - */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 1018, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1019 - * _import_umath() - * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_ufunc() except -1: - */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 1019, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(1, 1019, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1016 - * - * cdef inline int import_umath() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1015 - * raise ImportError("numpy.core.multiarray failed to import") - * - * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -/* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1021 - * raise ImportError("numpy.core.umath failed to import") - * - * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - -static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { - int __pyx_r; - __Pyx_RefNannyDeclarations - PyObject *__pyx_t_1 = NULL; - PyObject *__pyx_t_2 = NULL; - PyObject *__pyx_t_3 = NULL; - int __pyx_t_4; - PyObject *__pyx_t_5 = NULL; - PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - PyObject *__pyx_t_8 = NULL; - __Pyx_RefNannySetupContext("import_ufunc", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1022 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - { - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); - __Pyx_XGOTREF(__pyx_t_1); - __Pyx_XGOTREF(__pyx_t_2); - __Pyx_XGOTREF(__pyx_t_3); - /*try:*/ { - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1023 - * cdef inline int import_ufunc() except -1: - * try: - * _import_umath() # <<<<<<<<<<<<<< - * except Exception: - * raise ImportError("numpy.core.umath failed to import") - */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 1023, __pyx_L3_error) - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1022 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - } - __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - goto __pyx_L8_try_end; - __pyx_L3_error:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1024 - * try: - * _import_umath() - * except Exception: # <<<<<<<<<<<<<< - * raise ImportError("numpy.core.umath failed to import") - */ - __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0]))); - if (__pyx_t_4) { - __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(1, 1024, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_5); - __Pyx_GOTREF(__pyx_t_6); - __Pyx_GOTREF(__pyx_t_7); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1025 - * _import_umath() - * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< - */ - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ImportError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 1025, __pyx_L5_except_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_Raise(__pyx_t_8, 0, 0, 0); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(1, 1025, __pyx_L5_except_error) - } - goto __pyx_L5_except_error; - __pyx_L5_except_error:; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1022 - * - * cdef inline int import_ufunc() except -1: - * try: # <<<<<<<<<<<<<< - * _import_umath() - * except Exception: - */ - __Pyx_XGIVEREF(__pyx_t_1); - __Pyx_XGIVEREF(__pyx_t_2); - __Pyx_XGIVEREF(__pyx_t_3); - __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); - goto __pyx_L1_error; - __pyx_L8_try_end:; - } - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1021 - * raise ImportError("numpy.core.umath failed to import") - * - * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - - /* function exit code */ - __pyx_r = 0; - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_5); - __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); - __Pyx_XDECREF(__pyx_t_8); - __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); - __pyx_r = -1; - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - return __pyx_r; -} - -static PyMethodDef __pyx_methods[] = { - {0, 0, 0, 0} -}; - -#if PY_MAJOR_VERSION >= 3 -#if CYTHON_PEP489_MULTI_PHASE_INIT -static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ -static int __pyx_pymod_exec_cython_function(PyObject* module); /*proto*/ -static PyModuleDef_Slot __pyx_moduledef_slots[] = { - {Py_mod_create, (void*)__pyx_pymod_create}, - {Py_mod_exec, (void*)__pyx_pymod_exec_cython_function}, - {0, NULL} -}; -#endif - -static struct PyModuleDef __pyx_moduledef = { - PyModuleDef_HEAD_INIT, - "cython_function", - 0, /* m_doc */ - #if CYTHON_PEP489_MULTI_PHASE_INIT - 0, /* m_size */ - #else - -1, /* m_size */ - #endif - __pyx_methods /* m_methods */, - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_moduledef_slots, /* m_slots */ - #else - NULL, /* m_reload */ - #endif - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; -#endif - -static __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0}, - {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0}, - {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, - {&__pyx_n_s_N, __pyx_k_N, sizeof(__pyx_k_N), 0, 0, 1, 1}, - {&__pyx_n_s_N_selected, __pyx_k_N_selected, sizeof(__pyx_k_N_selected), 0, 0, 1, 1}, - {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0}, - {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, - {&__pyx_n_s_S1_low, __pyx_k_S1_low, sizeof(__pyx_k_S1_low), 0, 0, 1, 1}, - {&__pyx_n_s_S2_low, __pyx_k_S2_low, sizeof(__pyx_k_S2_low), 0, 0, 1, 1}, - {&__pyx_n_s_S_low, __pyx_k_S_low, sizeof(__pyx_k_S_low), 0, 0, 1, 1}, - {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, - {&__pyx_n_s_bin_spacing, __pyx_k_bin_spacing, sizeof(__pyx_k_bin_spacing), 0, 0, 1, 1}, - {&__pyx_n_s_bin_spacing_1, __pyx_k_bin_spacing_1, sizeof(__pyx_k_bin_spacing_1), 0, 0, 1, 1}, - {&__pyx_n_s_bin_spacing_2, __pyx_k_bin_spacing_2, sizeof(__pyx_k_bin_spacing_2), 0, 0, 1, 1}, - {&__pyx_n_s_bins_end, __pyx_k_bins_end, sizeof(__pyx_k_bins_end), 0, 0, 1, 1}, - {&__pyx_n_s_bins_end_1, __pyx_k_bins_end_1, sizeof(__pyx_k_bins_end_1), 0, 0, 1, 1}, - {&__pyx_n_s_bins_end_2, __pyx_k_bins_end_2, sizeof(__pyx_k_bins_end_2), 0, 0, 1, 1}, - {&__pyx_n_s_bins_start, __pyx_k_bins_start, sizeof(__pyx_k_bins_start), 0, 0, 1, 1}, - {&__pyx_n_s_bins_start_1, __pyx_k_bins_start_1, sizeof(__pyx_k_bins_start_1), 0, 0, 1, 1}, - {&__pyx_n_s_bins_start_2, __pyx_k_bins_start_2, sizeof(__pyx_k_bins_start_2), 0, 0, 1, 1}, - {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, - {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1}, - {&__pyx_n_s_extract_indices_cython, __pyx_k_extract_indices_cython, sizeof(__pyx_k_extract_indices_cython), 0, 0, 1, 1}, - {&__pyx_n_s_float64, __pyx_k_float64, sizeof(__pyx_k_float64), 0, 0, 1, 1}, - {&__pyx_n_s_hist_data, __pyx_k_hist_data, sizeof(__pyx_k_hist_data), 0, 0, 1, 1}, - {&__pyx_n_s_histogram_cic_1d, __pyx_k_histogram_cic_1d, sizeof(__pyx_k_histogram_cic_1d), 0, 0, 1, 1}, - {&__pyx_n_s_histogram_cic_2d, __pyx_k_histogram_cic_2d, sizeof(__pyx_k_histogram_cic_2d), 0, 0, 1, 1}, - {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, - {&__pyx_n_s_i1_low_bin, __pyx_k_i1_low_bin, sizeof(__pyx_k_i1_low_bin), 0, 0, 1, 1}, - {&__pyx_n_s_i2_low_bin, __pyx_k_i2_low_bin, sizeof(__pyx_k_i2_low_bin), 0, 0, 1, 1}, - {&__pyx_n_s_i_fill, __pyx_k_i_fill, sizeof(__pyx_k_i_fill), 0, 0, 1, 1}, - {&__pyx_n_s_i_low_bin, __pyx_k_i_low_bin, sizeof(__pyx_k_i_low_bin), 0, 0, 1, 1}, - {&__pyx_n_s_i_select, __pyx_k_i_select, sizeof(__pyx_k_i_select), 0, 0, 1, 1}, - {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, - {&__pyx_n_s_inv_spacing, __pyx_k_inv_spacing, sizeof(__pyx_k_inv_spacing), 0, 0, 1, 1}, - {&__pyx_n_s_inv_spacing_1, __pyx_k_inv_spacing_1, sizeof(__pyx_k_inv_spacing_1), 0, 0, 1, 1}, - {&__pyx_n_s_inv_spacing_2, __pyx_k_inv_spacing_2, sizeof(__pyx_k_inv_spacing_2), 0, 0, 1, 1}, - {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_n_ptcl, __pyx_k_n_ptcl, sizeof(__pyx_k_n_ptcl), 0, 0, 1, 1}, - {&__pyx_n_s_nbins, __pyx_k_nbins, sizeof(__pyx_k_nbins), 0, 0, 1, 1}, - {&__pyx_n_s_nbins_1, __pyx_k_nbins_1, sizeof(__pyx_k_nbins_1), 0, 0, 1, 1}, - {&__pyx_n_s_nbins_2, __pyx_k_nbins_2, sizeof(__pyx_k_nbins_2), 0, 0, 1, 1}, - {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0}, - {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0}, - {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, - {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, - {&__pyx_kp_s_numpy_core_multiarray_failed_to, __pyx_k_numpy_core_multiarray_failed_to, sizeof(__pyx_k_numpy_core_multiarray_failed_to), 0, 0, 1, 0}, - {&__pyx_kp_s_numpy_core_umath_failed_to_impor, __pyx_k_numpy_core_umath_failed_to_impor, sizeof(__pyx_k_numpy_core_umath_failed_to_impor), 0, 0, 1, 0}, - {&__pyx_kp_s_opmd_viewer_openpmd_timeseries_c, __pyx_k_opmd_viewer_openpmd_timeseries_c, sizeof(__pyx_k_opmd_viewer_openpmd_timeseries_c), 0, 0, 1, 0}, - {&__pyx_n_s_opmd_viewer_openpmd_timeseries_c_2, __pyx_k_opmd_viewer_openpmd_timeseries_c_2, sizeof(__pyx_k_opmd_viewer_openpmd_timeseries_c_2), 0, 0, 1, 1}, - {&__pyx_n_s_original_indices, __pyx_k_original_indices, sizeof(__pyx_k_original_indices), 0, 0, 1, 1}, - {&__pyx_n_s_pid, __pyx_k_pid, sizeof(__pyx_k_pid), 0, 0, 1, 1}, - {&__pyx_n_s_preserve_particle_index, __pyx_k_preserve_particle_index, sizeof(__pyx_k_preserve_particle_index), 0, 0, 1, 1}, - {&__pyx_n_s_q1, __pyx_k_q1, sizeof(__pyx_k_q1), 0, 0, 1, 1}, - {&__pyx_n_s_q1_cell, __pyx_k_q1_cell, sizeof(__pyx_k_q1_cell), 0, 0, 1, 1}, - {&__pyx_n_s_q2, __pyx_k_q2, sizeof(__pyx_k_q2), 0, 0, 1, 1}, - {&__pyx_n_s_q2_cell, __pyx_k_q2_cell, sizeof(__pyx_k_q2_cell), 0, 0, 1, 1}, - {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, - {&__pyx_n_s_selected_indices, __pyx_k_selected_indices, sizeof(__pyx_k_selected_indices), 0, 0, 1, 1}, - {&__pyx_n_s_selected_pid, __pyx_k_selected_pid, sizeof(__pyx_k_selected_pid), 0, 0, 1, 1}, - {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, - {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0}, - {&__pyx_n_s_w, __pyx_k_w, sizeof(__pyx_k_w), 0, 0, 1, 1}, - {&__pyx_n_s_xrange, __pyx_k_xrange, sizeof(__pyx_k_xrange), 0, 0, 1, 1}, - {&__pyx_n_s_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 0, 0, 1, 1}, - {0, 0, 0, 0, 0, 0, 0} -}; -static int __Pyx_InitCachedBuiltins(void) { - #if PY_MAJOR_VERSION >= 3 - __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_xrange) __PYX_ERR(0, 73, __pyx_L1_error) - #else - __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_xrange); if (!__pyx_builtin_xrange) __PYX_ERR(0, 73, __pyx_L1_error) - #endif - __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) __PYX_ERR(1, 235, __pyx_L1_error) - __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(1, 248, __pyx_L1_error) - __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(1, 823, __pyx_L1_error) - __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) __PYX_ERR(1, 1013, __pyx_L1_error) - return 0; - __pyx_L1_error:; - return -1; -} - -static int __Pyx_InitCachedConstants(void) { - __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":235 - * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) - * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): - * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< - * - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) - */ - __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple_)) __PYX_ERR(1, 235, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple_); - __Pyx_GIVEREF(__pyx_tuple_); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":239 - * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) - * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): - * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< - * - * info.buf = PyArray_DATA(self) - */ - __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 239, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__2); - __Pyx_GIVEREF(__pyx_tuple__2); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":276 - * if ((descr.byteorder == c'>' and little_endian) or - * (descr.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< - * if t == NPY_BYTE: f = "b" - * elif t == NPY_UBYTE: f = "B" - */ - __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(1, 276, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__3); - __Pyx_GIVEREF(__pyx_tuple__3); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":823 - * - * if (end - f) - (new_offset - offset[0]) < 15: - * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< - * - * if ((child.byteorder == c'>' and little_endian) or - */ - __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(1, 823, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__4); - __Pyx_GIVEREF(__pyx_tuple__4); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":827 - * if ((child.byteorder == c'>' and little_endian) or - * (child.byteorder == c'<' and not little_endian)): - * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< - * # One could encode it in the format string and have Cython - * # complain instead, BUT: < and > in format strings also imply - */ - __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 827, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__5); - __Pyx_GIVEREF(__pyx_tuple__5); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":847 - * t = child.type_num - * if end - f < 5: - * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< - * - * # Until ticket #99 is fixed, use integers to avoid warnings - */ - __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 847, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__6); - __Pyx_GIVEREF(__pyx_tuple__6); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1013 - * _import_array() - * except Exception: - * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_umath() except -1: - */ - __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_multiarray_failed_to); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(1, 1013, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__7); - __Pyx_GIVEREF(__pyx_tuple__7); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1019 - * _import_umath() - * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< - * - * cdef inline int import_ufunc() except -1: - */ - __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_umath_failed_to_impor); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(1, 1019, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__8); - __Pyx_GIVEREF(__pyx_tuple__8); - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1025 - * _import_umath() - * except Exception: - * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< - */ - __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_numpy_core_umath_failed_to_impor); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(1, 1025, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__9); - __Pyx_GIVEREF(__pyx_tuple__9); - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":9 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * def extract_indices_cython( # <<<<<<<<<<<<<< - * np.ndarray[np.int64_t, ndim=1] original_indices, - * np.ndarray[np.int64_t, ndim=1] selected_indices, - */ - __pyx_tuple__10 = PyTuple_Pack(10, __pyx_n_s_original_indices, __pyx_n_s_selected_indices, __pyx_n_s_pid, __pyx_n_s_selected_pid, __pyx_n_s_preserve_particle_index, __pyx_n_s_i, __pyx_n_s_i_select, __pyx_n_s_i_fill, __pyx_n_s_N, __pyx_n_s_N_selected); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__10); - __Pyx_GIVEREF(__pyx_tuple__10); - __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(5, 0, 10, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_opmd_viewer_openpmd_timeseries_c, __pyx_n_s_extract_indices_cython, 9, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) __PYX_ERR(0, 9, __pyx_L1_error) - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":51 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * def histogram_cic_1d( # <<<<<<<<<<<<<< - * np.ndarray[np.float64_t, ndim=1] q1, - * np.ndarray[np.float64_t, ndim=1] w, - */ - __pyx_tuple__12 = PyTuple_Pack(13, __pyx_n_s_q1, __pyx_n_s_w, __pyx_n_s_nbins, __pyx_n_s_bins_start, __pyx_n_s_bins_end, __pyx_n_s_bin_spacing, __pyx_n_s_inv_spacing, __pyx_n_s_n_ptcl, __pyx_n_s_i_low_bin, __pyx_n_s_q1_cell, __pyx_n_s_S_low, __pyx_n_s_hist_data, __pyx_n_s_i); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(0, 51, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__12); - __Pyx_GIVEREF(__pyx_tuple__12); - __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(5, 0, 13, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__12, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_opmd_viewer_openpmd_timeseries_c, __pyx_n_s_histogram_cic_1d, 51, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) __PYX_ERR(0, 51, __pyx_L1_error) - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":89 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * def histogram_cic_2d( # <<<<<<<<<<<<<< - * np.ndarray[np.float64_t, ndim=1] q1, - * np.ndarray[np.float64_t, ndim=1] q2, - */ - __pyx_tuple__14 = PyTuple_Pack(22, __pyx_n_s_q1, __pyx_n_s_q2, __pyx_n_s_w, __pyx_n_s_nbins_1, __pyx_n_s_bins_start_1, __pyx_n_s_bins_end_1, __pyx_n_s_nbins_2, __pyx_n_s_bins_start_2, __pyx_n_s_bins_end_2, __pyx_n_s_bin_spacing_1, __pyx_n_s_inv_spacing_1, __pyx_n_s_bin_spacing_2, __pyx_n_s_inv_spacing_2, __pyx_n_s_n_ptcl, __pyx_n_s_i1_low_bin, __pyx_n_s_i2_low_bin, __pyx_n_s_q1_cell, __pyx_n_s_q2_cell, __pyx_n_s_S1_low, __pyx_n_s_S2_low, __pyx_n_s_hist_data, __pyx_n_s_i); if (unlikely(!__pyx_tuple__14)) __PYX_ERR(0, 89, __pyx_L1_error) - __Pyx_GOTREF(__pyx_tuple__14); - __Pyx_GIVEREF(__pyx_tuple__14); - __pyx_codeobj__15 = (PyObject*)__Pyx_PyCode_New(9, 0, 22, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__14, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_opmd_viewer_openpmd_timeseries_c, __pyx_n_s_histogram_cic_2d, 89, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__15)) __PYX_ERR(0, 89, __pyx_L1_error) - __Pyx_RefNannyFinishContext(); - return 0; - __pyx_L1_error:; - __Pyx_RefNannyFinishContext(); - return -1; -} - -static int __Pyx_InitGlobals(void) { - if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - return 0; - __pyx_L1_error:; - return -1; -} - -#if PY_MAJOR_VERSION < 3 -PyMODINIT_FUNC initcython_function(void); /*proto*/ -PyMODINIT_FUNC initcython_function(void) -#else -PyMODINIT_FUNC PyInit_cython_function(void); /*proto*/ -PyMODINIT_FUNC PyInit_cython_function(void) -#if CYTHON_PEP489_MULTI_PHASE_INIT -{ - return PyModuleDef_Init(&__pyx_moduledef); -} -static int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name) { - PyObject *value = PyObject_GetAttrString(spec, from_name); - int result = 0; - if (likely(value)) { - result = PyDict_SetItemString(moddict, to_name, value); - Py_DECREF(value); - } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - } else { - result = -1; - } - return result; -} -static PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { - PyObject *module = NULL, *moddict, *modname; - if (__pyx_m) - return __Pyx_NewRef(__pyx_m); - modname = PyObject_GetAttrString(spec, "name"); - if (unlikely(!modname)) goto bad; - module = PyModule_NewObject(modname); - Py_DECREF(modname); - if (unlikely(!module)) goto bad; - moddict = PyModule_GetDict(module); - if (unlikely(!moddict)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__") < 0)) goto bad; - if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__") < 0)) goto bad; - return module; -bad: - Py_XDECREF(module); - return NULL; -} - - -static int __pyx_pymod_exec_cython_function(PyObject *__pyx_pyinit_module) -#endif -#endif -{ - PyObject *__pyx_t_1 = NULL; - __Pyx_RefNannyDeclarations - #if CYTHON_PEP489_MULTI_PHASE_INIT - if (__pyx_m && __pyx_m == __pyx_pyinit_module) return 0; - #endif - #if CYTHON_REFNANNY - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); - if (!__Pyx_RefNanny) { - PyErr_Clear(); - __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); - if (!__Pyx_RefNanny) - Py_FatalError("failed to import 'refnanny' module"); - } - #endif - __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_cython_function(void)", 0); - if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) - #ifdef __Pyx_CyFunction_USED - if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_FusedFunction_USED - if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Coroutine_USED - if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_Generator_USED - if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_AsyncGen_USED - if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - #ifdef __Pyx_StopAsyncIteration_USED - if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - /*--- Library function declarations ---*/ - /*--- Threads initialization code ---*/ - #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS - #ifdef WITH_THREAD /* Python build with threading support? */ - PyEval_InitThreads(); - #endif - #endif - /*--- Module creation code ---*/ - #if CYTHON_PEP489_MULTI_PHASE_INIT - __pyx_m = __pyx_pyinit_module; - Py_INCREF(__pyx_m); - #else - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("cython_function", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); - #endif - if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) - Py_INCREF(__pyx_d); - __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) - __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) - #if CYTHON_COMPILING_IN_PYPY - Py_INCREF(__pyx_b); - #endif - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); - /*--- Initialize various global constants etc. ---*/ - if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) - if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - if (__pyx_module_is_main_opmd_viewer__openpmd_timeseries__cython_function) { - if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - } - #if PY_MAJOR_VERSION >= 3 - { - PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) - if (!PyDict_GetItemString(modules, "opmd_viewer.openpmd_timeseries.cython_function")) { - if (unlikely(PyDict_SetItemString(modules, "opmd_viewer.openpmd_timeseries.cython_function", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) - } - } - #endif - /*--- Builtin init code ---*/ - if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Constants init code ---*/ - if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - /*--- Global init code ---*/ - /*--- Variable export code ---*/ - /*--- Function export code ---*/ - /*--- Type init code ---*/ - /*--- Type import code ---*/ - __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", - #if CYTHON_COMPILING_IN_PYPY - sizeof(PyTypeObject), - #else - sizeof(PyHeapTypeObject), - #endif - 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) __PYX_ERR(2, 9, __pyx_L1_error) - __pyx_ptype_7cpython_4bool_bool = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "bool", sizeof(PyBoolObject), 0); if (unlikely(!__pyx_ptype_7cpython_4bool_bool)) __PYX_ERR(3, 8, __pyx_L1_error) - __pyx_ptype_7cpython_7complex_complex = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "complex", sizeof(PyComplexObject), 0); if (unlikely(!__pyx_ptype_7cpython_7complex_complex)) __PYX_ERR(4, 15, __pyx_L1_error) - __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) __PYX_ERR(1, 163, __pyx_L1_error) - __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) __PYX_ERR(1, 185, __pyx_L1_error) - __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) __PYX_ERR(1, 189, __pyx_L1_error) - __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) __PYX_ERR(1, 198, __pyx_L1_error) - __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) __PYX_ERR(1, 885, __pyx_L1_error) - /*--- Variable import code ---*/ - /*--- Function import code ---*/ - /*--- Execution code ---*/ - #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) - if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) - #endif - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":1 - * import numpy as np # <<<<<<<<<<<<<< - * cimport numpy as np - * from cpython cimport bool - */ - __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":9 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * def extract_indices_cython( # <<<<<<<<<<<<<< - * np.ndarray[np.int64_t, ndim=1] original_indices, - * np.ndarray[np.int64_t, ndim=1] selected_indices, - */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11opmd_viewer_18openpmd_timeseries_15cython_function_1extract_indices_cython, NULL, __pyx_n_s_opmd_viewer_openpmd_timeseries_c_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_extract_indices_cython, __pyx_t_1) < 0) __PYX_ERR(0, 9, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":51 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * def histogram_cic_1d( # <<<<<<<<<<<<<< - * np.ndarray[np.float64_t, ndim=1] q1, - * np.ndarray[np.float64_t, ndim=1] w, - */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11opmd_viewer_18openpmd_timeseries_15cython_function_3histogram_cic_1d, NULL, __pyx_n_s_opmd_viewer_openpmd_timeseries_c_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_histogram_cic_1d, __pyx_t_1) < 0) __PYX_ERR(0, 51, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":89 - * @cython.boundscheck(False) - * @cython.wraparound(False) - * def histogram_cic_2d( # <<<<<<<<<<<<<< - * np.ndarray[np.float64_t, ndim=1] q1, - * np.ndarray[np.float64_t, ndim=1] q2, - */ - __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_11opmd_viewer_18openpmd_timeseries_15cython_function_5histogram_cic_2d, NULL, __pyx_n_s_opmd_viewer_openpmd_timeseries_c_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_histogram_cic_2d, __pyx_t_1) < 0) __PYX_ERR(0, 89, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "opmd_viewer/openpmd_timeseries/cython_function.pyx":1 - * import numpy as np # <<<<<<<<<<<<<< - * cimport numpy as np - * from cpython cimport bool - */ - __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "../../../miniconda3/lib/python3.6/site-packages/Cython/Includes/numpy/__init__.pxd":1021 - * raise ImportError("numpy.core.umath failed to import") - * - * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< - * try: - * _import_umath() - */ - - /*--- Wrapped vars code ---*/ - - goto __pyx_L0; - __pyx_L1_error:; - __Pyx_XDECREF(__pyx_t_1); - if (__pyx_m) { - if (__pyx_d) { - __Pyx_AddTraceback("init opmd_viewer.openpmd_timeseries.cython_function", 0, __pyx_lineno, __pyx_filename); - } - Py_DECREF(__pyx_m); __pyx_m = 0; - } else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "init opmd_viewer.openpmd_timeseries.cython_function"); - } - __pyx_L0:; - __Pyx_RefNannyFinishContext(); - #if CYTHON_PEP489_MULTI_PHASE_INIT - return (__pyx_m != NULL) ? 0 : -1; - #elif PY_MAJOR_VERSION >= 3 - return __pyx_m; - #else - return; - #endif -} - -/* --- Runtime support code --- */ -/* Refnanny */ -#if CYTHON_REFNANNY -static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { - PyObject *m = NULL, *p = NULL; - void *r = NULL; - m = PyImport_ImportModule((char *)modname); - if (!m) goto end; - p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); - if (!p) goto end; - r = PyLong_AsVoidPtr(p); -end: - Py_XDECREF(p); - Py_XDECREF(m); - return (__Pyx_RefNannyAPIStruct *)r; -} -#endif - -/* GetBuiltinName */ -static PyObject *__Pyx_GetBuiltinName(PyObject *name) { - PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); - if (unlikely(!result)) { - PyErr_Format(PyExc_NameError, -#if PY_MAJOR_VERSION >= 3 - "name '%U' is not defined", name); -#else - "name '%.200s' is not defined", PyString_AS_STRING(name)); -#endif - } - return result; -} - -/* RaiseArgTupleInvalid */ -static void __Pyx_RaiseArgtupleInvalid( - const char* func_name, - int exact, - Py_ssize_t num_min, - Py_ssize_t num_max, - Py_ssize_t num_found) -{ - Py_ssize_t num_expected; - const char *more_or_less; - if (num_found < num_min) { - num_expected = num_min; - more_or_less = "at least"; - } else { - num_expected = num_max; - more_or_less = "at most"; - } - if (exact) { - more_or_less = "exactly"; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", - func_name, more_or_less, num_expected, - (num_expected == 1) ? "" : "s", num_found); -} - -/* RaiseDoubleKeywords */ -static void __Pyx_RaiseDoubleKeywordsError( - const char* func_name, - PyObject* kw_name) -{ - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION >= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AsString(kw_name)); - #endif -} - -/* ParseKeywords */ -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - while (PyDict_Next(kwds, &pos, &key, &value)) { - name = first_kw_arg; - while (*name && (**name != key)) name++; - if (*name) { - values[name-argnames] = value; - continue; - } - name = first_kw_arg; - #if PY_MAJOR_VERSION < 3 - if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) { - while (*name) { - if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) - && _PyString_Eq(**name, key)) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - if ((**argname == key) || ( - (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) - && _PyString_Eq(**argname, key))) { - goto arg_passed_twice; - } - argname++; - } - } - } else - #endif - if (likely(PyUnicode_Check(key))) { - while (*name) { - int cmp = (**name == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 : - #endif - PyUnicode_Compare(**name, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) { - values[name-argnames] = value; - break; - } - name++; - } - if (*name) continue; - else { - PyObject*** argname = argnames; - while (argname != first_kw_arg) { - int cmp = (**argname == key) ? 0 : - #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 - (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 : - #endif - PyUnicode_Compare(**argname, key); - if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; - if (cmp == 0) goto arg_passed_twice; - argname++; - } - } - } else - goto invalid_keyword_type; - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; - } else { - goto invalid_keyword; - } - } - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, key); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%.200s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION < 3 - "%.200s() got an unexpected keyword argument '%.200s'", - function_name, PyString_AsString(key)); - #else - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif -bad: - return -1; -} - -/* ArgTypeTest */ -static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) -{ - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - else if (exact) { - #if PY_MAJOR_VERSION == 2 - if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; - #endif - } - else { - if (likely(__Pyx_TypeCheck(obj, type))) return 1; - } - PyErr_Format(PyExc_TypeError, - "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", - name, type->tp_name, Py_TYPE(obj)->tp_name); - return 0; -} - -/* IsLittleEndian */ -static CYTHON_INLINE int __Pyx_Is_Little_Endian(void) -{ - union { - uint32_t u32; - uint8_t u8[4]; - } S; - S.u32 = 0x01020304; - return S.u8[0] == 4; -} - -/* BufferFormatCheck */ -static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, - __Pyx_BufFmt_StackElem* stack, - __Pyx_TypeInfo* type) { - stack[0].field = &ctx->root; - stack[0].parent_offset = 0; - ctx->root.type = type; - ctx->root.name = "buffer dtype"; - ctx->root.offset = 0; - ctx->head = stack; - ctx->head->field = &ctx->root; - ctx->fmt_offset = 0; - ctx->head->parent_offset = 0; - ctx->new_packmode = '@'; - ctx->enc_packmode = '@'; - ctx->new_count = 1; - ctx->enc_count = 0; - ctx->enc_type = 0; - ctx->is_complex = 0; - ctx->is_valid_array = 0; - ctx->struct_alignment = 0; - while (type->typegroup == 'S') { - ++ctx->head; - ctx->head->field = type->fields; - ctx->head->parent_offset = 0; - type = type->fields->type; - } -} -static int __Pyx_BufFmt_ParseNumber(const char** ts) { - int count; - const char* t = *ts; - if (*t < '0' || *t > '9') { - return -1; - } else { - count = *t++ - '0'; - while (*t >= '0' && *t < '9') { - count *= 10; - count += *t++ - '0'; - } - } - *ts = t; - return count; -} -static int __Pyx_BufFmt_ExpectNumber(const char **ts) { - int number = __Pyx_BufFmt_ParseNumber(ts); - if (number == -1) - PyErr_Format(PyExc_ValueError,\ - "Does not understand character buffer dtype format string ('%c')", **ts); - return number; -} -static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { - PyErr_Format(PyExc_ValueError, - "Unexpected format string character: '%c'", ch); -} -static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { - switch (ch) { - case 'c': return "'char'"; - case 'b': return "'signed char'"; - case 'B': return "'unsigned char'"; - case 'h': return "'short'"; - case 'H': return "'unsigned short'"; - case 'i': return "'int'"; - case 'I': return "'unsigned int'"; - case 'l': return "'long'"; - case 'L': return "'unsigned long'"; - case 'q': return "'long long'"; - case 'Q': return "'unsigned long long'"; - case 'f': return (is_complex ? "'complex float'" : "'float'"); - case 'd': return (is_complex ? "'complex double'" : "'double'"); - case 'g': return (is_complex ? "'complex long double'" : "'long double'"); - case 'T': return "a struct"; - case 'O': return "Python object"; - case 'P': return "a pointer"; - case 's': case 'p': return "a string"; - case 0: return "end"; - default: return "unparseable format string"; - } -} -static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return 2; - case 'i': case 'I': case 'l': case 'L': return 4; - case 'q': case 'Q': return 8; - case 'f': return (is_complex ? 8 : 4); - case 'd': return (is_complex ? 16 : 8); - case 'g': { - PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); - return 0; - } - case 'O': case 'P': return sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } -} -static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { - switch (ch) { - case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(short); - case 'i': case 'I': return sizeof(int); - case 'l': case 'L': return sizeof(long); - #ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(PY_LONG_LONG); - #endif - case 'f': return sizeof(float) * (is_complex ? 2 : 1); - case 'd': return sizeof(double) * (is_complex ? 2 : 1); - case 'g': return sizeof(long double) * (is_complex ? 2 : 1); - case 'O': case 'P': return sizeof(void*); - default: { - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } - } -} -typedef struct { char c; short x; } __Pyx_st_short; -typedef struct { char c; int x; } __Pyx_st_int; -typedef struct { char c; long x; } __Pyx_st_long; -typedef struct { char c; float x; } __Pyx_st_float; -typedef struct { char c; double x; } __Pyx_st_double; -typedef struct { char c; long double x; } __Pyx_st_longdouble; -typedef struct { char c; void *x; } __Pyx_st_void_p; -#ifdef HAVE_LONG_LONG -typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; -#endif -static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); - case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); - case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); -#ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); -#endif - case 'f': return sizeof(__Pyx_st_float) - sizeof(float); - case 'd': return sizeof(__Pyx_st_double) - sizeof(double); - case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); - case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } -} -/* These are for computing the padding at the end of the struct to align - on the first member of the struct. This will probably the same as above, - but we don't have any guarantees. - */ -typedef struct { short x; char c; } __Pyx_pad_short; -typedef struct { int x; char c; } __Pyx_pad_int; -typedef struct { long x; char c; } __Pyx_pad_long; -typedef struct { float x; char c; } __Pyx_pad_float; -typedef struct { double x; char c; } __Pyx_pad_double; -typedef struct { long double x; char c; } __Pyx_pad_longdouble; -typedef struct { void *x; char c; } __Pyx_pad_void_p; -#ifdef HAVE_LONG_LONG -typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; -#endif -static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) { - switch (ch) { - case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; - case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); - case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); - case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); -#ifdef HAVE_LONG_LONG - case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); -#endif - case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); - case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); - case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); - case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); - default: - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } -} -static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { - switch (ch) { - case 'c': - return 'H'; - case 'b': case 'h': case 'i': - case 'l': case 'q': case 's': case 'p': - return 'I'; - case 'B': case 'H': case 'I': case 'L': case 'Q': - return 'U'; - case 'f': case 'd': case 'g': - return (is_complex ? 'C' : 'R'); - case 'O': - return 'O'; - case 'P': - return 'P'; - default: { - __Pyx_BufFmt_RaiseUnexpectedChar(ch); - return 0; - } - } -} -static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { - if (ctx->head == NULL || ctx->head->field == &ctx->root) { - const char* expected; - const char* quote; - if (ctx->head == NULL) { - expected = "end"; - quote = ""; - } else { - expected = ctx->head->field->type->name; - quote = "'"; - } - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch, expected %s%s%s but got %s", - quote, expected, quote, - __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); - } else { - __Pyx_StructField* field = ctx->head->field; - __Pyx_StructField* parent = (ctx->head - 1)->field; - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", - field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), - parent->type->name, field->name); - } -} -static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { - char group; - size_t size, offset, arraysize = 1; - if (ctx->enc_type == 0) return 0; - if (ctx->head->field->type->arraysize[0]) { - int i, ndim = 0; - if (ctx->enc_type == 's' || ctx->enc_type == 'p') { - ctx->is_valid_array = ctx->head->field->type->ndim == 1; - ndim = 1; - if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { - PyErr_Format(PyExc_ValueError, - "Expected a dimension of size %zu, got %zu", - ctx->head->field->type->arraysize[0], ctx->enc_count); - return -1; - } - } - if (!ctx->is_valid_array) { - PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", - ctx->head->field->type->ndim, ndim); - return -1; - } - for (i = 0; i < ctx->head->field->type->ndim; i++) { - arraysize *= ctx->head->field->type->arraysize[i]; - } - ctx->is_valid_array = 0; - ctx->enc_count = 1; - } - group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); - do { - __Pyx_StructField* field = ctx->head->field; - __Pyx_TypeInfo* type = field->type; - if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { - size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); - } else { - size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); - } - if (ctx->enc_packmode == '@') { - size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); - size_t align_mod_offset; - if (align_at == 0) return -1; - align_mod_offset = ctx->fmt_offset % align_at; - if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; - if (ctx->struct_alignment == 0) - ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, - ctx->is_complex); - } - if (type->size != size || type->typegroup != group) { - if (type->typegroup == 'C' && type->fields != NULL) { - size_t parent_offset = ctx->head->parent_offset + field->offset; - ++ctx->head; - ctx->head->field = type->fields; - ctx->head->parent_offset = parent_offset; - continue; - } - if ((type->typegroup == 'H' || group == 'H') && type->size == size) { - } else { - __Pyx_BufFmt_RaiseExpected(ctx); - return -1; - } - } - offset = ctx->head->parent_offset + field->offset; - if (ctx->fmt_offset != offset) { - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", - (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); - return -1; - } - ctx->fmt_offset += size; - if (arraysize) - ctx->fmt_offset += (arraysize - 1) * size; - --ctx->enc_count; - while (1) { - if (field == &ctx->root) { - ctx->head = NULL; - if (ctx->enc_count != 0) { - __Pyx_BufFmt_RaiseExpected(ctx); - return -1; - } - break; - } - ctx->head->field = ++field; - if (field->type == NULL) { - --ctx->head; - field = ctx->head->field; - continue; - } else if (field->type->typegroup == 'S') { - size_t parent_offset = ctx->head->parent_offset + field->offset; - if (field->type->fields->type == NULL) continue; - field = field->type->fields; - ++ctx->head; - ctx->head->field = field; - ctx->head->parent_offset = parent_offset; - break; - } else { - break; - } - } - } while (ctx->enc_count); - ctx->enc_type = 0; - ctx->is_complex = 0; - return 0; -} -static PyObject * -__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) -{ - const char *ts = *tsp; - int i = 0, number; - int ndim = ctx->head->field->type->ndim; -; - ++ts; - if (ctx->new_count != 1) { - PyErr_SetString(PyExc_ValueError, - "Cannot handle repeated arrays in format string"); - return NULL; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - while (*ts && *ts != ')') { - switch (*ts) { - case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; - default: break; - } - number = __Pyx_BufFmt_ExpectNumber(&ts); - if (number == -1) return NULL; - if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) - return PyErr_Format(PyExc_ValueError, - "Expected a dimension of size %zu, got %d", - ctx->head->field->type->arraysize[i], number); - if (*ts != ',' && *ts != ')') - return PyErr_Format(PyExc_ValueError, - "Expected a comma in format string, got '%c'", *ts); - if (*ts == ',') ts++; - i++; - } - if (i != ndim) - return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", - ctx->head->field->type->ndim, i); - if (!*ts) { - PyErr_SetString(PyExc_ValueError, - "Unexpected end of format string, expected ')'"); - return NULL; - } - ctx->is_valid_array = 1; - ctx->new_count = 1; - *tsp = ++ts; - return Py_None; -} -static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { - int got_Z = 0; - while (1) { - switch(*ts) { - case 0: - if (ctx->enc_type != 0 && ctx->head == NULL) { - __Pyx_BufFmt_RaiseExpected(ctx); - return NULL; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - if (ctx->head != NULL) { - __Pyx_BufFmt_RaiseExpected(ctx); - return NULL; - } - return ts; - case ' ': - case '\r': - case '\n': - ++ts; - break; - case '<': - if (!__Pyx_Is_Little_Endian()) { - PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); - return NULL; - } - ctx->new_packmode = '='; - ++ts; - break; - case '>': - case '!': - if (__Pyx_Is_Little_Endian()) { - PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); - return NULL; - } - ctx->new_packmode = '='; - ++ts; - break; - case '=': - case '@': - case '^': - ctx->new_packmode = *ts++; - break; - case 'T': - { - const char* ts_after_sub; - size_t i, struct_count = ctx->new_count; - size_t struct_alignment = ctx->struct_alignment; - ctx->new_count = 1; - ++ts; - if (*ts != '{') { - PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); - return NULL; - } - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_type = 0; - ctx->enc_count = 0; - ctx->struct_alignment = 0; - ++ts; - ts_after_sub = ts; - for (i = 0; i != struct_count; ++i) { - ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); - if (!ts_after_sub) return NULL; - } - ts = ts_after_sub; - if (struct_alignment) ctx->struct_alignment = struct_alignment; - } - break; - case '}': - { - size_t alignment = ctx->struct_alignment; - ++ts; - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_type = 0; - if (alignment && ctx->fmt_offset % alignment) { - ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); - } - } - return ts; - case 'x': - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->fmt_offset += ctx->new_count; - ctx->new_count = 1; - ctx->enc_count = 0; - ctx->enc_type = 0; - ctx->enc_packmode = ctx->new_packmode; - ++ts; - break; - case 'Z': - got_Z = 1; - ++ts; - if (*ts != 'f' && *ts != 'd' && *ts != 'g') { - __Pyx_BufFmt_RaiseUnexpectedChar('Z'); - return NULL; - } - case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': - case 'l': case 'L': case 'q': case 'Q': - case 'f': case 'd': case 'g': - case 'O': case 'p': - if (ctx->enc_type == *ts && got_Z == ctx->is_complex && - ctx->enc_packmode == ctx->new_packmode) { - ctx->enc_count += ctx->new_count; - ctx->new_count = 1; - got_Z = 0; - ++ts; - break; - } - case 's': - if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; - ctx->enc_count = ctx->new_count; - ctx->enc_packmode = ctx->new_packmode; - ctx->enc_type = *ts; - ctx->is_complex = got_Z; - ++ts; - ctx->new_count = 1; - got_Z = 0; - break; - case ':': - ++ts; - while(*ts != ':') ++ts; - ++ts; - break; - case '(': - if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL; - break; - default: - { - int number = __Pyx_BufFmt_ExpectNumber(&ts); - if (number == -1) return NULL; - ctx->new_count = (size_t)number; - } - } - } -} - -/* BufferGetAndValidate */ - static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { - if (unlikely(info->buf == NULL)) return; - if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; - __Pyx_ReleaseBuffer(info); -} -static void __Pyx_ZeroBuffer(Py_buffer* buf) { - buf->buf = NULL; - buf->obj = NULL; - buf->strides = __Pyx_zeros; - buf->shape = __Pyx_zeros; - buf->suboffsets = __Pyx_minusones; -} -static int __Pyx__GetBufferAndValidate( - Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, - int nd, int cast, __Pyx_BufFmt_StackElem* stack) -{ - buf->buf = NULL; - if (unlikely(__Pyx_GetBuffer(obj, buf, flags) == -1)) { - __Pyx_ZeroBuffer(buf); - return -1; - } - if (unlikely(buf->ndim != nd)) { - PyErr_Format(PyExc_ValueError, - "Buffer has wrong number of dimensions (expected %d, got %d)", - nd, buf->ndim); - goto fail; - } - if (!cast) { - __Pyx_BufFmt_Context ctx; - __Pyx_BufFmt_Init(&ctx, stack, dtype); - if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; - } - if (unlikely((unsigned)buf->itemsize != dtype->size)) { - PyErr_Format(PyExc_ValueError, - "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", - buf->itemsize, (buf->itemsize > 1) ? "s" : "", - dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); - goto fail; - } - if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; - return 0; -fail:; - __Pyx_SafeReleaseBuffer(buf); - return -1; -} - -/* PyErrFetchRestore */ - #if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -} -#endif - -/* GetModuleGlobalName */ - static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) { - PyObject *result; -#if !CYTHON_AVOID_BORROWED_REFS - result = PyDict_GetItem(__pyx_d, name); - if (likely(result)) { - Py_INCREF(result); - } else { -#else - result = PyObject_GetItem(__pyx_d, name); - if (!result) { - PyErr_Clear(); -#endif - result = __Pyx_GetBuiltinName(name); - } - return result; -} - -/* PyObjectCall */ - #if CYTHON_COMPILING_IN_CPYTHON -static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { - PyObject *result; - ternaryfunc call = func->ob_type->tp_call; - if (unlikely(!call)) - return PyObject_Call(func, arg, kw); - if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) - return NULL; - result = (*call)(func, arg, kw); - Py_LeaveRecursiveCall(); - if (unlikely(!result) && unlikely(!PyErr_Occurred())) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); - } - return result; -} -#endif - -/* GetItemInt */ - static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { - PyObject *r; - if (!j) return NULL; - r = PyObject_GetItem(o, j); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyList_GET_SIZE(o); - } - if ((!boundscheck) || likely((0 <= wrapped_i) & (wrapped_i < PyList_GET_SIZE(o)))) { - PyObject *r = PyList_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS - Py_ssize_t wrapped_i = i; - if (wraparound & unlikely(i < 0)) { - wrapped_i += PyTuple_GET_SIZE(o); - } - if ((!boundscheck) || likely((0 <= wrapped_i) & (wrapped_i < PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); - Py_INCREF(r); - return r; - } - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -#else - return PySequence_GetItem(o, i); -#endif -} -static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, - CYTHON_NCP_UNUSED int wraparound, - CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); - if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) { - PyObject *r = PyList_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } - else if (PyTuple_CheckExact(o)) { - Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); - if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) { - PyObject *r = PyTuple_GET_ITEM(o, n); - Py_INCREF(r); - return r; - } - } else { - PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (likely(m && m->sq_item)) { - if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { - Py_ssize_t l = m->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; - PyErr_Clear(); - } - } - return m->sq_item(o, i); - } - } -#else - if (is_list || PySequence_Check(o)) { - return PySequence_GetItem(o, i); - } -#endif - return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); -} - -/* SetItemInt */ - static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) { - int r; - if (!j) return -1; - r = PyObject_SetItem(o, j, v); - Py_DECREF(j); - return r; -} -static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int is_list, - CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { -#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS - if (is_list || PyList_CheckExact(o)) { - Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o)); - if ((!boundscheck) || likely((n >= 0) & (n < PyList_GET_SIZE(o)))) { - PyObject* old = PyList_GET_ITEM(o, n); - Py_INCREF(v); - PyList_SET_ITEM(o, n, v); - Py_DECREF(old); - return 1; - } - } else { - PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; - if (likely(m && m->sq_ass_item)) { - if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { - Py_ssize_t l = m->sq_length(o); - if (likely(l >= 0)) { - i += l; - } else { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return -1; - PyErr_Clear(); - } - } - return m->sq_ass_item(o, i, v); - } - } -#else -#if CYTHON_COMPILING_IN_PYPY - if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) { -#else - if (is_list || PySequence_Check(o)) { -#endif - return PySequence_SetItem(o, i, v); - } -#endif - return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v); -} - -/* RaiseException */ - #if PY_MAJOR_VERSION < 3 -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, - CYTHON_UNUSED PyObject *cause) { - __Pyx_PyThreadState_declare - Py_XINCREF(type); - if (!value || value == Py_None) - value = NULL; - else - Py_INCREF(value); - if (!tb || tb == Py_None) - tb = NULL; - else { - Py_INCREF(tb); - if (!PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto raise_error; - } - } - if (PyType_Check(type)) { -#if CYTHON_COMPILING_IN_PYPY - if (!value) { - Py_INCREF(Py_None); - value = Py_None; - } -#endif - PyErr_NormalizeException(&type, &value, &tb); - } else { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto raise_error; - } - value = type; - type = (PyObject*) Py_TYPE(type); - Py_INCREF(type); - if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto raise_error; - } - } - __Pyx_PyThreadState_assign - __Pyx_ErrRestore(type, value, tb); - return; -raise_error: - Py_XDECREF(value); - Py_XDECREF(type); - Py_XDECREF(tb); - return; -} -#else -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { - PyObject* owned_instance = NULL; - if (tb == Py_None) { - tb = 0; - } else if (tb && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto bad; - } - if (value == Py_None) - value = 0; - if (PyExceptionInstance_Check(type)) { - if (value) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto bad; - } - value = type; - type = (PyObject*) Py_TYPE(value); - } else if (PyExceptionClass_Check(type)) { - PyObject *instance_class = NULL; - if (value && PyExceptionInstance_Check(value)) { - instance_class = (PyObject*) Py_TYPE(value); - if (instance_class != type) { - int is_subclass = PyObject_IsSubclass(instance_class, type); - if (!is_subclass) { - instance_class = NULL; - } else if (unlikely(is_subclass == -1)) { - goto bad; - } else { - type = instance_class; - } - } - } - if (!instance_class) { - PyObject *args; - if (!value) - args = PyTuple_New(0); - else if (PyTuple_Check(value)) { - Py_INCREF(value); - args = value; - } else - args = PyTuple_Pack(1, value); - if (!args) - goto bad; - owned_instance = PyObject_Call(type, args, NULL); - Py_DECREF(args); - if (!owned_instance) - goto bad; - value = owned_instance; - if (!PyExceptionInstance_Check(value)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %R", - type, Py_TYPE(value)); - goto bad; - } - } - } else { - PyErr_SetString(PyExc_TypeError, - "raise: exception class must be a subclass of BaseException"); - goto bad; - } - if (cause) { - PyObject *fixed_cause; - if (cause == Py_None) { - fixed_cause = NULL; - } else if (PyExceptionClass_Check(cause)) { - fixed_cause = PyObject_CallObject(cause, NULL); - if (fixed_cause == NULL) - goto bad; - } else if (PyExceptionInstance_Check(cause)) { - fixed_cause = cause; - Py_INCREF(fixed_cause); - } else { - PyErr_SetString(PyExc_TypeError, - "exception causes must derive from " - "BaseException"); - goto bad; - } - PyException_SetCause(value, fixed_cause); - } - PyErr_SetObject(type, value); - if (tb) { -#if CYTHON_COMPILING_IN_PYPY - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); - Py_INCREF(tb); - PyErr_Restore(tmp_type, tmp_value, tb); - Py_XDECREF(tmp_tb); -#else - PyThreadState *tstate = __Pyx_PyThreadState_Current; - PyObject* tmp_tb = tstate->curexc_traceback; - if (tb != tmp_tb) { - Py_INCREF(tb); - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_tb); - } -#endif - } -bad: - Py_XDECREF(owned_instance); - return; -} -#endif - -/* RaiseTooManyValuesToUnpack */ - static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { - PyErr_Format(PyExc_ValueError, - "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); -} - -/* RaiseNeedMoreValuesToUnpack */ - static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { - PyErr_Format(PyExc_ValueError, - "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", - index, (index == 1) ? "" : "s"); -} - -/* RaiseNoneIterError */ - static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { - PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); -} - -/* ExtTypeTest */ - static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { - if (unlikely(!type)) { - PyErr_SetString(PyExc_SystemError, "Missing type object"); - return 0; - } - if (likely(__Pyx_TypeCheck(obj, type))) - return 1; - PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", - Py_TYPE(obj)->tp_name, type->tp_name); - return 0; -} - -/* SaveResetException */ - #if CYTHON_FAST_THREAD_STATE -static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if PY_VERSION_HEX >= 0x030700A2 - *type = tstate->exc_state.exc_type; - *value = tstate->exc_state.exc_value; - *tb = tstate->exc_state.exc_traceback; - #else - *type = tstate->exc_type; - *value = tstate->exc_value; - *tb = tstate->exc_traceback; - #endif - Py_XINCREF(*type); - Py_XINCREF(*value); - Py_XINCREF(*tb); -} -static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - #if PY_VERSION_HEX >= 0x030700A2 - tmp_type = tstate->exc_state.exc_type; - tmp_value = tstate->exc_state.exc_value; - tmp_tb = tstate->exc_state.exc_traceback; - tstate->exc_state.exc_type = type; - tstate->exc_state.exc_value = value; - tstate->exc_state.exc_traceback = tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = type; - tstate->exc_value = value; - tstate->exc_traceback = tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} -#endif - -/* PyErrExceptionMatches */ - #if CYTHON_FAST_THREAD_STATE -static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(tuple); -#if PY_MAJOR_VERSION >= 3 - for (i=0; icurexc_type; - if (exc_type == err) return 1; - if (unlikely(!exc_type)) return 0; - if (unlikely(PyTuple_Check(err))) - return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); - return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); -} -#endif - -/* GetException */ - #if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { -#endif - PyObject *local_type, *local_value, *local_tb; -#if CYTHON_FAST_THREAD_STATE - PyObject *tmp_type, *tmp_value, *tmp_tb; - local_type = tstate->curexc_type; - local_value = tstate->curexc_value; - local_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -#else - PyErr_Fetch(&local_type, &local_value, &local_tb); -#endif - PyErr_NormalizeException(&local_type, &local_value, &local_tb); -#if CYTHON_FAST_THREAD_STATE - if (unlikely(tstate->curexc_type)) -#else - if (unlikely(PyErr_Occurred())) -#endif - goto bad; - #if PY_MAJOR_VERSION >= 3 - if (local_tb) { - if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) - goto bad; - } - #endif - Py_XINCREF(local_tb); - Py_XINCREF(local_type); - Py_XINCREF(local_value); - *type = local_type; - *value = local_value; - *tb = local_tb; -#if CYTHON_FAST_THREAD_STATE - #if PY_VERSION_HEX >= 0x030700A2 - tmp_type = tstate->exc_state.exc_type; - tmp_value = tstate->exc_state.exc_value; - tmp_tb = tstate->exc_state.exc_traceback; - tstate->exc_state.exc_type = local_type; - tstate->exc_state.exc_value = local_value; - tstate->exc_state.exc_traceback = local_tb; - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = local_type; - tstate->exc_value = local_value; - tstate->exc_traceback = local_tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -#else - PyErr_SetExcInfo(local_type, local_value, local_tb); -#endif - return 0; -bad: - *type = 0; - *value = 0; - *tb = 0; - Py_XDECREF(local_type); - Py_XDECREF(local_value); - Py_XDECREF(local_tb); - return -1; -} - -/* Import */ - static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { - PyObject *empty_list = 0; - PyObject *module = 0; - PyObject *global_dict = 0; - PyObject *empty_dict = 0; - PyObject *list; - #if PY_MAJOR_VERSION < 3 - PyObject *py_import; - py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); - if (!py_import) - goto bad; - #endif - if (from_list) - list = from_list; - else { - empty_list = PyList_New(0); - if (!empty_list) - goto bad; - list = empty_list; - } - global_dict = PyModule_GetDict(__pyx_m); - if (!global_dict) - goto bad; - empty_dict = PyDict_New(); - if (!empty_dict) - goto bad; - { - #if PY_MAJOR_VERSION >= 3 - if (level == -1) { - if (strchr(__Pyx_MODULE_NAME, '.')) { - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, 1); - if (!module) { - if (!PyErr_ExceptionMatches(PyExc_ImportError)) - goto bad; - PyErr_Clear(); - } - } - level = 0; - } - #endif - if (!module) { - #if PY_MAJOR_VERSION < 3 - PyObject *py_level = PyInt_FromLong(level); - if (!py_level) - goto bad; - module = PyObject_CallFunctionObjArgs(py_import, - name, global_dict, empty_dict, list, py_level, NULL); - Py_DECREF(py_level); - #else - module = PyImport_ImportModuleLevelObject( - name, global_dict, empty_dict, list, level); - #endif - } - } -bad: - #if PY_MAJOR_VERSION < 3 - Py_XDECREF(py_import); - #endif - Py_XDECREF(empty_list); - Py_XDECREF(empty_dict); - return module; -} - -/* CLineInTraceback */ - #ifndef CYTHON_CLINE_IN_TRACEBACK -static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_line) { - PyObject *use_cline; - PyObject *ptype, *pvalue, *ptraceback; -#if CYTHON_COMPILING_IN_CPYTHON - PyObject **cython_runtime_dict; -#endif - __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); -#if CYTHON_COMPILING_IN_CPYTHON - cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); - if (likely(cython_runtime_dict)) { - use_cline = PyDict_GetItem(*cython_runtime_dict, __pyx_n_s_cline_in_traceback); - } else -#endif - { - PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); - if (use_cline_obj) { - use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; - Py_DECREF(use_cline_obj); - } else { - PyErr_Clear(); - use_cline = NULL; - } - } - if (!use_cline) { - c_line = 0; - PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); - } - else if (PyObject_Not(use_cline) != 0) { - c_line = 0; - } - __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); - return c_line; -} -#endif - -/* CodeObjectCache */ - static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { - int start = 0, mid = 0, end = count - 1; - if (end >= 0 && code_line > entries[end].code_line) { - return count; - } - while (start < end) { - mid = start + (end - start) / 2; - if (code_line < entries[mid].code_line) { - end = mid; - } else if (code_line > entries[mid].code_line) { - start = mid + 1; - } else { - return mid; - } - } - if (code_line <= entries[mid].code_line) { - return mid; - } else { - return mid + 1; - } -} -static PyCodeObject *__pyx_find_code_object(int code_line) { - PyCodeObject* code_object; - int pos; - if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { - return NULL; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { - return NULL; - } - code_object = __pyx_code_cache.entries[pos].code_object; - Py_INCREF(code_object); - return code_object; -} -static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { - int pos, i; - __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; - if (unlikely(!code_line)) { - return; - } - if (unlikely(!entries)) { - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); - if (likely(entries)) { - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = 64; - __pyx_code_cache.count = 1; - entries[0].code_line = code_line; - entries[0].code_object = code_object; - Py_INCREF(code_object); - } - return; - } - pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); - if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { - PyCodeObject* tmp = entries[pos].code_object; - entries[pos].code_object = code_object; - Py_DECREF(tmp); - return; - } - if (__pyx_code_cache.count == __pyx_code_cache.max_count) { - int new_max = __pyx_code_cache.max_count + 64; - entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( - __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry)); - if (unlikely(!entries)) { - return; - } - __pyx_code_cache.entries = entries; - __pyx_code_cache.max_count = new_max; - } - for (i=__pyx_code_cache.count; i>pos; i--) { - entries[i] = entries[i-1]; - } - entries[pos].code_line = code_line; - entries[pos].code_object = code_object; - __pyx_code_cache.count++; - Py_INCREF(code_object); -} - -/* AddTraceback */ - #include "compile.h" -#include "frameobject.h" -#include "traceback.h" -static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( - const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyObject *py_srcfile = 0; - PyObject *py_funcname = 0; - #if PY_MAJOR_VERSION < 3 - py_srcfile = PyString_FromString(filename); - #else - py_srcfile = PyUnicode_FromString(filename); - #endif - if (!py_srcfile) goto bad; - if (c_line) { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #else - py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); - #endif - } - else { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - #else - py_funcname = PyUnicode_FromString(funcname); - #endif - } - if (!py_funcname) goto bad; - py_code = __Pyx_PyCode_New( - 0, - 0, - 0, - 0, - 0, - __pyx_empty_bytes, /*PyObject *code,*/ - __pyx_empty_tuple, /*PyObject *consts,*/ - __pyx_empty_tuple, /*PyObject *names,*/ - __pyx_empty_tuple, /*PyObject *varnames,*/ - __pyx_empty_tuple, /*PyObject *freevars,*/ - __pyx_empty_tuple, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - py_line, - __pyx_empty_bytes /*PyObject *lnotab*/ - ); - Py_DECREF(py_srcfile); - Py_DECREF(py_funcname); - return py_code; -bad: - Py_XDECREF(py_srcfile); - Py_XDECREF(py_funcname); - return NULL; -} -static void __Pyx_AddTraceback(const char *funcname, int c_line, - int py_line, const char *filename) { - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyThreadState *tstate = __Pyx_PyThreadState_Current; - if (c_line) { - c_line = __Pyx_CLineForTraceback(tstate, c_line); - } - py_code = __pyx_find_code_object(c_line ? -c_line : py_line); - if (!py_code) { - py_code = __Pyx_CreateCodeObjectForTraceback( - funcname, c_line, py_line, filename); - if (!py_code) goto bad; - __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); - } - py_frame = PyFrame_New( - tstate, /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - __pyx_d, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) goto bad; - __Pyx_PyFrame_SetLineNumber(py_frame, py_line); - PyTraceBack_Here(py_frame); -bad: - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} - -#if PY_MAJOR_VERSION < 3 -static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { - if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); - if (__Pyx_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags); - PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name); - return -1; -} -static void __Pyx_ReleaseBuffer(Py_buffer *view) { - PyObject *obj = view->obj; - if (!obj) return; - if (PyObject_CheckBuffer(obj)) { - PyBuffer_Release(view); - return; - } - if ((0)) {} - else if (__Pyx_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); - view->obj = NULL; - Py_DECREF(obj); -} -#endif - - - /* CIntFromPyVerify */ - #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) -#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ - __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) -#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ - {\ - func_type value = func_value;\ - if (sizeof(target_type) < sizeof(func_type)) {\ - if (unlikely(value != (func_type) (target_type) value)) {\ - func_type zero = 0;\ - if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ - return (target_type) -1;\ - if (is_unsigned && unlikely(value < zero))\ - goto raise_neg_overflow;\ - else\ - goto raise_overflow;\ - }\ - }\ - return (target_type) value;\ - } - -/* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value) { - const unsigned int neg_one = (unsigned int) -1, const_zero = (unsigned int) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(unsigned int) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(unsigned int) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(unsigned int) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(unsigned int) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(unsigned int) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(unsigned int), - little, !is_unsigned); - } -} - -/* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { - const int neg_one = (int) -1, const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(int) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(int) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(int) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(int), - little, !is_unsigned); - } -} - -/* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { - const long neg_one = (long) -1, const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(long) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(long) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(long) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(long), - little, !is_unsigned); - } -} - -/* Declarations */ - #if CYTHON_CCOMPLEX - #ifdef __cplusplus - static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { - return ::std::complex< float >(x, y); - } - #else - static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { - return x + y*(__pyx_t_float_complex)_Complex_I; - } - #endif -#else - static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) { - __pyx_t_float_complex z; - z.real = x; - z.imag = y; - return z; - } -#endif - -/* Arithmetic */ - #if CYTHON_CCOMPLEX -#else - static CYTHON_INLINE int __Pyx_c_eq_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - return (a.real == b.real) && (a.imag == b.imag); - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sum_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - z.real = a.real + b.real; - z.imag = a.imag + b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_diff_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - z.real = a.real - b.real; - z.imag = a.imag - b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prod_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - z.real = a.real * b.real - a.imag * b.imag; - z.imag = a.real * b.imag + a.imag * b.real; - return z; - } - #if 1 - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - if (b.imag == 0) { - return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); - } else if (fabsf(b.real) >= fabsf(b.imag)) { - if (b.real == 0 && b.imag == 0) { - return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.imag); - } else { - float r = b.imag / b.real; - float s = 1.0 / (b.real + b.imag * r); - return __pyx_t_float_complex_from_parts( - (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); - } - } else { - float r = b.real / b.imag; - float s = 1.0 / (b.imag + b.real * r); - return __pyx_t_float_complex_from_parts( - (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); - } - } - #else - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quot_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - if (b.imag == 0) { - return __pyx_t_float_complex_from_parts(a.real / b.real, a.imag / b.real); - } else { - float denom = b.real * b.real + b.imag * b.imag; - return __pyx_t_float_complex_from_parts( - (a.real * b.real + a.imag * b.imag) / denom, - (a.imag * b.real - a.real * b.imag) / denom); - } - } - #endif - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_neg_float(__pyx_t_float_complex a) { - __pyx_t_float_complex z; - z.real = -a.real; - z.imag = -a.imag; - return z; - } - static CYTHON_INLINE int __Pyx_c_is_zero_float(__pyx_t_float_complex a) { - return (a.real == 0) && (a.imag == 0); - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conj_float(__pyx_t_float_complex a) { - __pyx_t_float_complex z; - z.real = a.real; - z.imag = -a.imag; - return z; - } - #if 1 - static CYTHON_INLINE float __Pyx_c_abs_float(__pyx_t_float_complex z) { - #if !defined(HAVE_HYPOT) || defined(_MSC_VER) - return sqrtf(z.real*z.real + z.imag*z.imag); - #else - return hypotf(z.real, z.imag); - #endif - } - static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_pow_float(__pyx_t_float_complex a, __pyx_t_float_complex b) { - __pyx_t_float_complex z; - float r, lnr, theta, z_r, z_theta; - if (b.imag == 0 && b.real == (int)b.real) { - if (b.real < 0) { - float denom = a.real * a.real + a.imag * a.imag; - a.real = a.real / denom; - a.imag = -a.imag / denom; - b.real = -b.real; - } - switch ((int)b.real) { - case 0: - z.real = 1; - z.imag = 0; - return z; - case 1: - return a; - case 2: - z = __Pyx_c_prod_float(a, a); - return __Pyx_c_prod_float(a, a); - case 3: - z = __Pyx_c_prod_float(a, a); - return __Pyx_c_prod_float(z, a); - case 4: - z = __Pyx_c_prod_float(a, a); - return __Pyx_c_prod_float(z, z); - } - } - if (a.imag == 0) { - if (a.real == 0) { - return a; - } else if (b.imag == 0) { - z.real = powf(a.real, b.real); - z.imag = 0; - return z; - } else if (a.real > 0) { - r = a.real; - theta = 0; - } else { - r = -a.real; - theta = atan2f(0, -1); - } - } else { - r = __Pyx_c_abs_float(a); - theta = atan2f(a.imag, a.real); - } - lnr = logf(r); - z_r = expf(lnr * b.real - theta * b.imag); - z_theta = theta * b.real + lnr * b.imag; - z.real = z_r * cosf(z_theta); - z.imag = z_r * sinf(z_theta); - return z; - } - #endif -#endif - -/* Declarations */ - #if CYTHON_CCOMPLEX - #ifdef __cplusplus - static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { - return ::std::complex< double >(x, y); - } - #else - static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { - return x + y*(__pyx_t_double_complex)_Complex_I; - } - #endif -#else - static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) { - __pyx_t_double_complex z; - z.real = x; - z.imag = y; - return z; - } -#endif - -/* Arithmetic */ - #if CYTHON_CCOMPLEX -#else - static CYTHON_INLINE int __Pyx_c_eq_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - return (a.real == b.real) && (a.imag == b.imag); - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - z.real = a.real + b.real; - z.imag = a.imag + b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - z.real = a.real - b.real; - z.imag = a.imag - b.imag; - return z; - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - z.real = a.real * b.real - a.imag * b.imag; - z.imag = a.real * b.imag + a.imag * b.real; - return z; - } - #if 1 - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - if (b.imag == 0) { - return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); - } else if (fabs(b.real) >= fabs(b.imag)) { - if (b.real == 0 && b.imag == 0) { - return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.imag); - } else { - double r = b.imag / b.real; - double s = 1.0 / (b.real + b.imag * r); - return __pyx_t_double_complex_from_parts( - (a.real + a.imag * r) * s, (a.imag - a.real * r) * s); - } - } else { - double r = b.real / b.imag; - double s = 1.0 / (b.imag + b.real * r); - return __pyx_t_double_complex_from_parts( - (a.real * r + a.imag) * s, (a.imag * r - a.real) * s); - } - } - #else - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - if (b.imag == 0) { - return __pyx_t_double_complex_from_parts(a.real / b.real, a.imag / b.real); - } else { - double denom = b.real * b.real + b.imag * b.imag; - return __pyx_t_double_complex_from_parts( - (a.real * b.real + a.imag * b.imag) / denom, - (a.imag * b.real - a.real * b.imag) / denom); - } - } - #endif - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg_double(__pyx_t_double_complex a) { - __pyx_t_double_complex z; - z.real = -a.real; - z.imag = -a.imag; - return z; - } - static CYTHON_INLINE int __Pyx_c_is_zero_double(__pyx_t_double_complex a) { - return (a.real == 0) && (a.imag == 0); - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj_double(__pyx_t_double_complex a) { - __pyx_t_double_complex z; - z.real = a.real; - z.imag = -a.imag; - return z; - } - #if 1 - static CYTHON_INLINE double __Pyx_c_abs_double(__pyx_t_double_complex z) { - #if !defined(HAVE_HYPOT) || defined(_MSC_VER) - return sqrt(z.real*z.real + z.imag*z.imag); - #else - return hypot(z.real, z.imag); - #endif - } - static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow_double(__pyx_t_double_complex a, __pyx_t_double_complex b) { - __pyx_t_double_complex z; - double r, lnr, theta, z_r, z_theta; - if (b.imag == 0 && b.real == (int)b.real) { - if (b.real < 0) { - double denom = a.real * a.real + a.imag * a.imag; - a.real = a.real / denom; - a.imag = -a.imag / denom; - b.real = -b.real; - } - switch ((int)b.real) { - case 0: - z.real = 1; - z.imag = 0; - return z; - case 1: - return a; - case 2: - z = __Pyx_c_prod_double(a, a); - return __Pyx_c_prod_double(a, a); - case 3: - z = __Pyx_c_prod_double(a, a); - return __Pyx_c_prod_double(z, a); - case 4: - z = __Pyx_c_prod_double(a, a); - return __Pyx_c_prod_double(z, z); - } - } - if (a.imag == 0) { - if (a.real == 0) { - return a; - } else if (b.imag == 0) { - z.real = pow(a.real, b.real); - z.imag = 0; - return z; - } else if (a.real > 0) { - r = a.real; - theta = 0; - } else { - r = -a.real; - theta = atan2(0, -1); - } - } else { - r = __Pyx_c_abs_double(a); - theta = atan2(a.imag, a.real); - } - lnr = log(r); - z_r = exp(lnr * b.real - theta * b.imag); - z_theta = theta * b.real + lnr * b.imag; - z.real = z_r * cos(z_theta); - z.imag = z_r * sin(z_theta); - return z; - } - #endif -#endif - -/* CIntToPy */ - static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value) { - const enum NPY_TYPES neg_one = (enum NPY_TYPES) -1, const_zero = (enum NPY_TYPES) 0; - const int is_unsigned = neg_one > const_zero; - if (is_unsigned) { - if (sizeof(enum NPY_TYPES) < sizeof(long)) { - return PyInt_FromLong((long) value); - } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned long)) { - return PyLong_FromUnsignedLong((unsigned long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned PY_LONG_LONG)) { - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); -#endif - } - } else { - if (sizeof(enum NPY_TYPES) <= sizeof(long)) { - return PyInt_FromLong((long) value); -#ifdef HAVE_LONG_LONG - } else if (sizeof(enum NPY_TYPES) <= sizeof(PY_LONG_LONG)) { - return PyLong_FromLongLong((PY_LONG_LONG) value); -#endif - } - } - { - int one = 1; int little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&value; - return _PyLong_FromByteArray(bytes, sizeof(enum NPY_TYPES), - little, !is_unsigned); - } -} - -/* CIntFromPy */ - static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { - const int neg_one = (int) -1, const_zero = (int) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(int) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (int) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { - return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { - return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { - return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (int) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(int) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (int) 0; - case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) - case -2: - if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(int) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(int) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(int) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { - return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); - } - } - break; - } -#endif - if (sizeof(int) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - int val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (int) -1; - } - } else { - int val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (int) -1; - val = __Pyx_PyInt_As_int(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to int"); - return (int) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to int"); - return (int) -1; -} - -/* CIntFromPy */ - static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { - const long neg_one = (long) -1, const_zero = (long) 0; - const int is_unsigned = neg_one > const_zero; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x))) { - if (sizeof(long) < sizeof(long)) { - __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) - } else { - long val = PyInt_AS_LONG(x); - if (is_unsigned && unlikely(val < 0)) { - goto raise_neg_overflow; - } - return (long) val; - } - } else -#endif - if (likely(PyLong_Check(x))) { - if (is_unsigned) { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { - return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { - return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { - return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); - } - } - break; - } -#endif -#if CYTHON_COMPILING_IN_CPYTHON - if (unlikely(Py_SIZE(x) < 0)) { - goto raise_neg_overflow; - } -#else - { - int result = PyObject_RichCompareBool(x, Py_False, Py_LT); - if (unlikely(result < 0)) - return (long) -1; - if (unlikely(result == 1)) - goto raise_neg_overflow; - } -#endif - if (sizeof(long) <= sizeof(unsigned long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) -#endif - } - } else { -#if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)x)->ob_digit; - switch (Py_SIZE(x)) { - case 0: return (long) 0; - case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) - case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) - case -2: - if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 2: - if (8 * sizeof(long) > 1 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -3: - if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 3: - if (8 * sizeof(long) > 2 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case -4: - if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - case 4: - if (8 * sizeof(long) > 3 * PyLong_SHIFT) { - if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { - __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) - } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { - return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); - } - } - break; - } -#endif - if (sizeof(long) <= sizeof(long)) { - __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) -#ifdef HAVE_LONG_LONG - } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { - __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) -#endif - } - } - { -#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) - PyErr_SetString(PyExc_RuntimeError, - "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); -#else - long val; - PyObject *v = __Pyx_PyNumber_IntOrLong(x); - #if PY_MAJOR_VERSION < 3 - if (likely(v) && !PyLong_Check(v)) { - PyObject *tmp = v; - v = PyNumber_Long(tmp); - Py_DECREF(tmp); - } - #endif - if (likely(v)) { - int one = 1; int is_little = (int)*(unsigned char *)&one; - unsigned char *bytes = (unsigned char *)&val; - int ret = _PyLong_AsByteArray((PyLongObject *)v, - bytes, sizeof(val), - is_little, !is_unsigned); - Py_DECREF(v); - if (likely(!ret)) - return val; - } -#endif - return (long) -1; - } - } else { - long val; - PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); - if (!tmp) return (long) -1; - val = __Pyx_PyInt_As_long(tmp); - Py_DECREF(tmp); - return val; - } -raise_overflow: - PyErr_SetString(PyExc_OverflowError, - "value too large to convert to long"); - return (long) -1; -raise_neg_overflow: - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to long"); - return (long) -1; -} - -/* FastTypeChecks */ - #if CYTHON_COMPILING_IN_CPYTHON -static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { - while (a) { - a = a->tp_base; - if (a == b) - return 1; - } - return b == &PyBaseObject_Type; -} -static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { - PyObject *mro; - if (a == b) return 1; - mro = a->tp_mro; - if (likely(mro)) { - Py_ssize_t i, n; - n = PyTuple_GET_SIZE(mro); - for (i = 0; i < n; i++) { - if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) - return 1; - } - return 0; - } - return __Pyx_InBases(a, b); -} -#if PY_MAJOR_VERSION == 2 -static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { - PyObject *exception, *value, *tb; - int res; - __Pyx_PyThreadState_declare - __Pyx_PyThreadState_assign - __Pyx_ErrFetch(&exception, &value, &tb); - res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - if (!res) { - res = PyObject_IsSubclass(err, exc_type2); - if (unlikely(res == -1)) { - PyErr_WriteUnraisable(err); - res = 0; - } - } - __Pyx_ErrRestore(exception, value, tb); - return res; -} -#else -static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { - int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; - if (!res) { - res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); - } - return res; -} -#endif -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject* exc_type) { - if (likely(err == exc_type)) return 1; - if (likely(PyExceptionClass_Check(err))) { - return __Pyx_inner_PyErr_GivenExceptionMatches2(err, NULL, exc_type); - } - return PyErr_GivenExceptionMatches(err, exc_type); -} -static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *exc_type1, PyObject *exc_type2) { - if (likely(err == exc_type1 || err == exc_type2)) return 1; - if (likely(PyExceptionClass_Check(err))) { - return __Pyx_inner_PyErr_GivenExceptionMatches2(err, exc_type1, exc_type2); - } - return (PyErr_GivenExceptionMatches(err, exc_type1) || PyErr_GivenExceptionMatches(err, exc_type2)); -} -#endif - -/* CheckBinaryVersion */ - static int __Pyx_check_binary_version(void) { - char ctversion[4], rtversion[4]; - PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); - PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); - if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { - char message[200]; - PyOS_snprintf(message, sizeof(message), - "compiletime version %s of module '%.100s' " - "does not match runtime version %s", - ctversion, __Pyx_MODULE_NAME, rtversion); - return PyErr_WarnEx(NULL, message, 1); - } - return 0; -} - -/* ModuleImport */ - #ifndef __PYX_HAVE_RT_ImportModule -#define __PYX_HAVE_RT_ImportModule -static PyObject *__Pyx_ImportModule(const char *name) { - PyObject *py_name = 0; - PyObject *py_module = 0; - py_name = __Pyx_PyIdentifier_FromString(name); - if (!py_name) - goto bad; - py_module = PyImport_Import(py_name); - Py_DECREF(py_name); - return py_module; -bad: - Py_XDECREF(py_name); - return 0; -} -#endif - -/* TypeImport */ - #ifndef __PYX_HAVE_RT_ImportType -#define __PYX_HAVE_RT_ImportType -static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, - size_t size, int strict) -{ - PyObject *py_module = 0; - PyObject *result = 0; - PyObject *py_name = 0; - char warning[200]; - Py_ssize_t basicsize; -#ifdef Py_LIMITED_API - PyObject *py_basicsize; -#endif - py_module = __Pyx_ImportModule(module_name); - if (!py_module) - goto bad; - py_name = __Pyx_PyIdentifier_FromString(class_name); - if (!py_name) - goto bad; - result = PyObject_GetAttr(py_module, py_name); - Py_DECREF(py_name); - py_name = 0; - Py_DECREF(py_module); - py_module = 0; - if (!result) - goto bad; - if (!PyType_Check(result)) { - PyErr_Format(PyExc_TypeError, - "%.200s.%.200s is not a type object", - module_name, class_name); - goto bad; - } -#ifndef Py_LIMITED_API - basicsize = ((PyTypeObject *)result)->tp_basicsize; -#else - py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); - if (!py_basicsize) - goto bad; - basicsize = PyLong_AsSsize_t(py_basicsize); - Py_DECREF(py_basicsize); - py_basicsize = 0; - if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) - goto bad; -#endif - if (!strict && (size_t)basicsize > size) { - PyOS_snprintf(warning, sizeof(warning), - "%s.%s size changed, may indicate binary incompatibility. Expected %zd, got %zd", - module_name, class_name, basicsize, size); - if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; - } - else if ((size_t)basicsize != size) { - PyErr_Format(PyExc_ValueError, - "%.200s.%.200s has the wrong size, try recompiling. Expected %zd, got %zd", - module_name, class_name, basicsize, size); - goto bad; - } - return (PyTypeObject *)result; -bad: - Py_XDECREF(py_module); - Py_XDECREF(result); - return NULL; -} -#endif - -/* InitStrings */ - static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { - while (t->p) { - #if PY_MAJOR_VERSION < 3 - if (t->is_unicode) { - *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); - } else if (t->intern) { - *t->p = PyString_InternFromString(t->s); - } else { - *t->p = PyString_FromStringAndSize(t->s, t->n - 1); - } - #else - if (t->is_unicode | t->is_str) { - if (t->intern) { - *t->p = PyUnicode_InternFromString(t->s); - } else if (t->encoding) { - *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); - } else { - *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); - } - } else { - *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); - } - #endif - if (!*t->p) - return -1; - if (PyObject_Hash(*t->p) == -1) - PyErr_Clear(); - ++t; - } - return 0; -} - -static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { - return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); -} -static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { - Py_ssize_t ignore; - return __Pyx_PyObject_AsStringAndSize(o, &ignore); -} -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT -#if !CYTHON_PEP393_ENABLED -static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - char* defenc_c; - PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); - if (!defenc) return NULL; - defenc_c = PyBytes_AS_STRING(defenc); -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - { - char* end = defenc_c + PyBytes_GET_SIZE(defenc); - char* c; - for (c = defenc_c; c < end; c++) { - if ((unsigned char) (*c) >= 128) { - PyUnicode_AsASCIIString(o); - return NULL; - } - } - } -#endif - *length = PyBytes_GET_SIZE(defenc); - return defenc_c; -} -#else -static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { - if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - if (likely(PyUnicode_IS_ASCII(o))) { - *length = PyUnicode_GET_LENGTH(o); - return PyUnicode_AsUTF8(o); - } else { - PyUnicode_AsASCIIString(o); - return NULL; - } -#else - return PyUnicode_AsUTF8AndSize(o, length); -#endif -} -#endif -#endif -static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { -#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT - if ( -#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII - __Pyx_sys_getdefaultencoding_not_ascii && -#endif - PyUnicode_Check(o)) { - return __Pyx_PyUnicode_AsStringAndSize(o, length); - } else -#endif -#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) - if (PyByteArray_Check(o)) { - *length = PyByteArray_GET_SIZE(o); - return PyByteArray_AS_STRING(o); - } else -#endif - { - char* result; - int r = PyBytes_AsStringAndSize(o, &result, length); - if (unlikely(r < 0)) { - return NULL; - } else { - return result; - } - } -} -static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - int is_true = x == Py_True; - if (is_true | (x == Py_False) | (x == Py_None)) return is_true; - else return PyObject_IsTrue(x); -} -static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { -#if PY_MAJOR_VERSION >= 3 - if (PyLong_Check(result)) { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "__int__ returned non-int (type %.200s). " - "The ability to return an instance of a strict subclass of int " - "is deprecated, and may be removed in a future version of Python.", - Py_TYPE(result)->tp_name)) { - Py_DECREF(result); - return NULL; - } - return result; - } -#endif - PyErr_Format(PyExc_TypeError, - "__%.4s__ returned non-%.4s (type %.200s)", - type_name, type_name, Py_TYPE(result)->tp_name); - Py_DECREF(result); - return NULL; -} -static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { -#if CYTHON_USE_TYPE_SLOTS - PyNumberMethods *m; -#endif - const char *name = NULL; - PyObject *res = NULL; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_Check(x) || PyLong_Check(x))) -#else - if (likely(PyLong_Check(x))) -#endif - return __Pyx_NewRef(x); -#if CYTHON_USE_TYPE_SLOTS - m = Py_TYPE(x)->tp_as_number; - #if PY_MAJOR_VERSION < 3 - if (m && m->nb_int) { - name = "int"; - res = m->nb_int(x); - } - else if (m && m->nb_long) { - name = "long"; - res = m->nb_long(x); - } - #else - if (likely(m && m->nb_int)) { - name = "int"; - res = m->nb_int(x); - } - #endif -#else - if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { - res = PyNumber_Int(x); - } -#endif - if (likely(res)) { -#if PY_MAJOR_VERSION < 3 - if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { -#else - if (unlikely(!PyLong_CheckExact(res))) { -#endif - return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); - } - } - else if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - } - return res; -} -static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { - Py_ssize_t ival; - PyObject *x; -#if PY_MAJOR_VERSION < 3 - if (likely(PyInt_CheckExact(b))) { - if (sizeof(Py_ssize_t) >= sizeof(long)) - return PyInt_AS_LONG(b); - else - return PyInt_AsSsize_t(x); - } -#endif - if (likely(PyLong_CheckExact(b))) { - #if CYTHON_USE_PYLONG_INTERNALS - const digit* digits = ((PyLongObject*)b)->ob_digit; - const Py_ssize_t size = Py_SIZE(b); - if (likely(__Pyx_sst_abs(size) <= 1)) { - ival = likely(size) ? digits[0] : 0; - if (size == -1) ival = -ival; - return ival; - } else { - switch (size) { - case 2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -2: - if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -3: - if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case 4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - case -4: - if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { - return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); - } - break; - } - } - #endif - return PyLong_AsSsize_t(b); - } - x = PyNumber_Index(b); - if (!x) return -1; - ival = PyInt_AsSsize_t(x); - Py_DECREF(x); - return ival; -} -static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { - return PyInt_FromSize_t(ival); -} - - -#endif /* Py_PYTHON_H */ diff --git a/opmd_viewer/openpmd_timeseries/cython_function.cpython-36m-x86_64-linux-gnu.so b/opmd_viewer/openpmd_timeseries/cython_function.cpython-36m-x86_64-linux-gnu.so deleted file mode 100755 index b46737a9a7f763c6c64476ffe2b80145e13101d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 301032 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 ByNc@TIva;JXSk;4PU9@Jk8R1)Te)BnRL_ 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ລ@hQ4TsimeUO=ry*5tTA#&r>Yu2g-;OwT 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 _x%{&hf&rsX0*J2l;X zd9=5ikpWToexfICMk!eizcwh3K(iZUG2HwWz>_W@>lW-VZD!e9YE}ZdJdm!L%gR|e zGoW@bq+0O2hGK8VtUNUoO9hK59?2q6(6BDs-LSSh-IY8?R!qaQlxa>4$=4i4jb0V2-Q$Bjj6%>0YpT(aFlKcWOXK-LQ+X_ z!ZT}X|Mp=mczkt2WRgrglTJuLxsq`&j9DaUkjCxFUokQn`OAuM!P;(Fg9`6+gtw<@ zSy$(AeC^sou%2gTQJlw8Iy{sWEFQvBmA_^kIAy+n&iOzuOIFCy+Pu37?^Y?$q()2&u8IhzWg@6Y0vK$ z5^v`}?uBaW1BW5B$nQ5J@n4U>j}reDV#d#Oh?mLrHzM}@z9O*^_BwvhUQ!OsHTvWC z8j0Hx57XEA&%%Bo9P;~*#J%$U2=g)a@~7`{<<}#eDOVN~zb8r5-_SF$Mn6S4iQ4n~ zl*BM|5d;2Bn0URmHw{WYjX>%wTaKUSH^@OWeSSZa__fVcTGak-R`&cJCz1dEM=v`6 zpMyQ?Z|wV?Ke85${D)6Chye+A$bpHU_Wb`g;-@GC>h!;^?D_ps;^VAX*t7l6?RVs0 zs{F8h@q4CiFIa`v^PKntk;%V&j@k43sB0!@{}Zt_`Dgn4-fDXddoc+=Bl6p1k@l$< zVj-V`{ity+AC?>AW;^(VT#Kg9@4>db7@B$8EsXu9J@F}JKlXjueb%Io6$=lvBR;F_ z`MuiM%hsR;{U7FDj0eEIg2or~--rL>NlmsHkMRQZF(APdlTkL30MdT0;;mO}V=lca zKjfm)FCu;IS8ERwLUYE?Pho%G^HHzkwdQ-K)$BLDVA(fW@o=NHr#S34zHF5nPI>F} z&xXCu=kKT4ia+|o>h_Fdo+JGuS6KVTzoXLnsXX(%1rGc3kG2`#x3qftWQ{-7M8ivs zS6KUge6{*CVa>ldv)yw3HRGddVxj%^lC}RCg&{k>u1xc;W`Enw)_#S`usZer7ZLu_ AB>(^b diff --git a/setup.py b/setup.py index 89b80401..decff674 100644 --- a/setup.py +++ b/setup.py @@ -9,9 +9,9 @@ with open('./requirements.txt') as f: install_requires = [line.strip('\n') for line in f.readlines()] -# Read the version number, by executing the file opmd_viewer/__version__.py +# Read the version number, by executing the file openpmd_viewer/__version__.py # This defines the variable __version__ -with open('./opmd_viewer/__version__.py') as f: +with open('./openpmd_viewer/__version__.py') as f: exec( f.read() ) # Define a custom class to run the py.test with `python setup.py test` @@ -28,7 +28,7 @@ def run_tests(self): include_dirs = [numpy.get_include()] from Cython.Build import cythonize ext_modules = cythonize( - "opmd_viewer/openpmd_timeseries/cython_function.pyx") + "openpmd_viewer/openpmd_timeseries/cython_function.pyx") except ImportError: # If the compilation fails, still install the package in a robust way include_dirs = [] @@ -45,8 +45,8 @@ def run_tests(self): maintainer_email='remi.lehe@lbl.gov', license='BSD-3-Clause-LBNL', packages=find_packages('.'), - package_data={'opmd_viewer': ['notebook_starter/*.ipynb']}, - scripts=['opmd_viewer/notebook_starter/openPMD_notebook'], + package_data={'openpmd_viewer': ['notebook_starter/*.ipynb']}, + scripts=['openpmd_viewer/notebook_starter/openPMD_notebook'], tests_require=['pytest', 'jupyter'], ext_modules=ext_modules, include_dirs=include_dirs, diff --git a/tutorials/1_Introduction-to-the-API.ipynb b/tutorials/1_Introduction-to-the-API.ipynb index 2f109317..8f5c58b8 100644 --- a/tutorials/1_Introduction-to-the-API.ipynb +++ b/tutorials/1_Introduction-to-the-API.ipynb @@ -62,7 +62,7 @@ "\n", "In order to start using the API:\n", "\n", - "- Load the class `OpenPMDTimeSeries` from the module `opmd_viewer`" + "- Load the class `OpenPMDTimeSeries` from the module `openpmd_viewer`" ] }, { @@ -71,7 +71,7 @@ "metadata": {}, "outputs": [], "source": [ - "from opmd_viewer import OpenPMDTimeSeries" + "from openpmd_viewer import OpenPMDTimeSeries" ] }, { diff --git a/tutorials/2_Specific-field-geometries.ipynb b/tutorials/2_Specific-field-geometries.ipynb index d10bfa5b..3a99a308 100644 --- a/tutorials/2_Specific-field-geometries.ipynb +++ b/tutorials/2_Specific-field-geometries.ipynb @@ -72,7 +72,7 @@ "metadata": {}, "outputs": [], "source": [ - "from opmd_viewer import OpenPMDTimeSeries" + "from openpmd_viewer import OpenPMDTimeSeries" ] }, { diff --git a/tutorials/3_Introduction-to-the-GUI.ipynb b/tutorials/3_Introduction-to-the-GUI.ipynb index d3a4768f..43afe4c5 100644 --- a/tutorials/3_Introduction-to-the-GUI.ipynb +++ b/tutorials/3_Introduction-to-the-GUI.ipynb @@ -65,7 +65,7 @@ "## Prepare and use the GUI \n", "\n", "In order to start using the GUI:\n", - "- Load the class `OpenPMDTimeSeries` from the module `opmd_viewer`" + "- Load the class `OpenPMDTimeSeries` from the module `openpmd_viewer`" ] }, { @@ -74,7 +74,7 @@ "metadata": {}, "outputs": [], "source": [ - "from opmd_viewer import OpenPMDTimeSeries" + "from openpmd_viewer import OpenPMDTimeSeries" ] }, { diff --git a/tutorials/4_Particle_selection.ipynb b/tutorials/4_Particle_selection.ipynb index c8b81e7b..5e1b38e1 100644 --- a/tutorials/4_Particle_selection.ipynb +++ b/tutorials/4_Particle_selection.ipynb @@ -68,7 +68,7 @@ "metadata": {}, "source": [ "As usual, in order to use openPMD-viewer, we:\n", - "- load the class `OpenPMDTimeSeries` from the module `opmd_viewer`\n", + "- load the class `OpenPMDTimeSeries` from the module `openpmd_viewer`\n", "- create a time series object by pointing to the folder which contains the corresponding openPMD data" ] }, @@ -78,7 +78,7 @@ "metadata": {}, "outputs": [], "source": [ - "from opmd_viewer import OpenPMDTimeSeries\n", + "from openpmd_viewer import OpenPMDTimeSeries\n", "ts = OpenPMDTimeSeries('./example-2d/hdf5/')" ] }, @@ -195,7 +195,7 @@ "metadata": {}, "outputs": [], "source": [ - "from opmd_viewer import ParticleTracker\n", + "from openpmd_viewer import ParticleTracker\n", "# Select particles to be tracked, at iteration 300\n", "pt = ParticleTracker( ts, iteration=300, select={'uz':[0.05,0.2], 'z':[22e-6,26e-6]}, species='electrons' )" ] diff --git a/tutorials/5_Laser-plasma_tools.ipynb b/tutorials/5_Laser-plasma_tools.ipynb index 90f4d7b1..d7395e6d 100644 --- a/tutorials/5_Laser-plasma_tools.ipynb +++ b/tutorials/5_Laser-plasma_tools.ipynb @@ -62,7 +62,7 @@ "## The LpaDiagnostics class\n", "\n", "To use the laser-plasma acceleration (LPA) tools:\n", - "- Load the class `LpaDiagnostics` from the module `opmd_viewer.addons`" + "- Load the class `LpaDiagnostics` from the module `openpmd_viewer.addons`" ] }, { @@ -71,7 +71,7 @@ "metadata": {}, "outputs": [], "source": [ - "from opmd_viewer.addons import LpaDiagnostics" + "from openpmd_viewer.addons import LpaDiagnostics" ] }, { From 19aaebe762a1c00d1f728d3bf7872cf1664bbc64 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sun, 28 Jul 2019 15:03:51 -0700 Subject: [PATCH 56/90] Update CHANGELOG.md Co-Authored-By: Axel Huebl --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 890e86f4..874edfb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -115,7 +115,7 @@ This new version includes: - an additional option `use_field_mesh` when plotting the particle. When set to `True`, this option uses information from the field mesh to choose the parameters of the particle histograms (esp. the bins). This is useful in order to avoid plotting/binning artifacts (aliasing) when the particles are evenly spaced. -In addition, the package `openpmd_viewer` now has an attribute `__version__`. +In addition, the module `openpmd_viewer` now has an attribute `__version__`. ## 0.3.3 From a1080b61c97f032c2c9b11d5cbec72fed9b2c4bb Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Wed, 31 Jul 2019 10:51:37 -0700 Subject: [PATCH 57/90] Make imshow_extent an array --- openpmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py b/openpmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py index e33075a0..80b5c84a 100644 --- a/openpmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py +++ b/openpmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py @@ -129,6 +129,7 @@ def _generate_imshow_extent(self): coord_step = getattr( self, 'd'+label ) self.imshow_extent += [ coord_min - 0.5*coord_step, coord_max + 0.5*coord_step ] + self.imshow_extent = np.array(self.imshow_extent) else: if hasattr(self, 'imshow_extent'): delattr(self, 'imshow_extent') From c962b4ff2784f256c466b4cbf7d83700bb97ac87 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Wed, 31 Jul 2019 11:14:00 -0700 Subject: [PATCH 58/90] Drop python 3.4 support in CI --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9c86d343..d54b3e69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,8 +8,6 @@ matrix: include: - os: linux python: "2.7" - - os: linux - python: "3.4" - os: linux python: "3.5" - os: linux From 52eb28f66f13d5cb7e4f9fec2d06d2d3e1c91f67 Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Wed, 31 Jul 2019 20:50:51 -0500 Subject: [PATCH 59/90] Travis CI: Add Python 3.7 --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index d54b3e69..d2d740be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,8 @@ matrix: python: "3.5" - os: linux python: "3.6" + - os: linux + python: "3.7" before_install: # Setup anaconda From 7fff0ffde5ac8bdf647ac58197a79babf6de827a Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 22 Aug 2019 08:29:08 -0700 Subject: [PATCH 60/90] Fix matplotlib custom ticker for matplotlib >= 3.1 --- openpmd_viewer/openpmd_timeseries/plotter.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/openpmd_viewer/openpmd_timeseries/plotter.py b/openpmd_viewer/openpmd_timeseries/plotter.py index ec93a9d5..50b07512 100644 --- a/openpmd_viewer/openpmd_timeseries/plotter.py +++ b/openpmd_viewer/openpmd_timeseries/plotter.py @@ -46,10 +46,17 @@ def __init__( self, *args, **kwargs ): # Reduce the threshold for printing an offset on side of the axis self._offset_threshold = 2 - def pprint_val( self, x, pos=None ): + def __call__(self, x, pos=None): """ - Function that is called for each tick of an axis. - Returns the string that + Function called for each tick of an axis (for matplotlib>=3.1) + Returns the string that appears in the plot. + """ + return self.pprint_val( x, pos ) + + def pprint_val( self, x, pos=None): + """ + Function called for each tick of an axis (for matplotlib<3.1) + Returns the string that appears in the plot. """ # Calculate the exponent (power of 3) xp = (x - self.offset) From 21ebeff43a1fc7cdf383f7ed024036ad505720c9 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Fri, 23 Aug 2019 09:14:37 -0700 Subject: [PATCH 61/90] Add deprecation warning when using `opmd_viewer` --- opmd_viewer/__init__.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 opmd_viewer/__init__.py diff --git a/opmd_viewer/__init__.py b/opmd_viewer/__init__.py new file mode 100644 index 00000000..ab10b7c8 --- /dev/null +++ b/opmd_viewer/__init__.py @@ -0,0 +1,29 @@ +""" +This is a stub that detects whether the user is attempting to use the +old import statement from openPMD-viewer 0.X (`import opmd_viewer`). + +In that case, an exception is raise, that prompts the user to use the new API. +""" +# Define the version number +from openpmd_viewer import __version__ +__all__ = ['__version__'] + +raise DeprecationWarning(""" +It looks like you are trying to use the API from openPMD-viewer version 0.X +but the installed version on your system is openPMD-viewer version 1.X. + +* If you wish to use the new openPMD-viewer version 1.X, the import statement +should use `openpmd_viewer` instead of `opmd_viewer`, e.g.: +``` +from openpmd_viewer import OpenPMDTimeSeries +``` +Please have a look at the list of the changes introduced in version 1.X here: +https://github.com/openPMD/openPMD-viewer/blob/upcoming-1.0/CHANGELOG.md#10 +In particular, note that `get_particle` now returns particle positions in +meters (not in microns anymore). + +* If you wish to go back to the old openPMD-viewer version 0.X, use: +``` +pip install openPMD-viewer==0.9 +``` +""") From cf06f90ab435e9915ae98b401ada50ec3796423c Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Fri, 23 Aug 2019 11:31:43 -0700 Subject: [PATCH 62/90] Update opmd_viewer/__init__.py Co-Authored-By: Axel Huebl --- opmd_viewer/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opmd_viewer/__init__.py b/opmd_viewer/__init__.py index ab10b7c8..5c45d149 100644 --- a/opmd_viewer/__init__.py +++ b/opmd_viewer/__init__.py @@ -2,7 +2,7 @@ This is a stub that detects whether the user is attempting to use the old import statement from openPMD-viewer 0.X (`import opmd_viewer`). -In that case, an exception is raise, that prompts the user to use the new API. +In that case, an exception is raised that prompts the user to use the new API. """ # Define the version number from openpmd_viewer import __version__ From e9852a0ea8a59605f9d3253ff690295cd3eb8cad Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Wed, 28 Aug 2019 06:43:15 -0700 Subject: [PATCH 63/90] Update CHANGELOG --- CHANGELOG.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 874edfb4..870d4fc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,28 @@ ## 1.0 -This version introduces a capability to do slicing along several directions, -and for 1d, 2d, 3d and circ geometries. -It breaks backward compatibility: for a 3d field, +This version introduces major changes and breaks backward compatibility. + +Here is a list of the changes: +- The import statement now uses `openpmd_viewer` instead of `opmd_viewer`, e.g. +``` +from openpmd_viewer import OpenPMDTimeSeries +``` +- For consistency, `ts.get_particle` now return particle positions in meters, +instead of microns. For instance, in the code below, `x`, `y`, `z` will be in +meters +``` +x, y, z = ts.get_particle(['x', 'y', 'z'], iteration=1000) +``` +- In `ts.get_field`, slicing can now be done in several directions +(by passing a list as the argument `slicing_dir`), and for +1d, 2d, 3d, and circ geometries. As a consequence, this breaks backward +compatibility for 3d field: ```get_field(field=field, coord=coord, iteration=iteration)``` -used to return the central slice along `y` while it returns the full 3d field -now. +used to return the central slice along `y` while it now returns the full 3d field. +- A new function (`ts.iterate`) was introduced in order to quickly apply a +given function to all iterations of a time series. See the docstring of +`ts.iterate` for more information. ## 0.9.0 From f16335811f5719474a40e7e832c2bce878c58412 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Wed, 28 Aug 2019 11:45:25 -0700 Subject: [PATCH 64/90] Fix slicing for circ --- .../openpmd_timeseries/data_reader/field_reader.py | 2 +- openpmd_viewer/openpmd_timeseries/utilities.py | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 4afb7f0f..39699f70 100644 --- a/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -227,7 +227,7 @@ def read_field_circ( filename, field_path, slicing, slicing_dir, m=0, # Slice field and clear metadata inverted_axes_dict = {info.axes[key]: key for key in info.axes.keys()} for count, slicing_dir_item in enumerate(slicing_dir): - slicing_index = inverted_axes_dict(slicing_dir_item) + slicing_index = inverted_axes_dict[slicing_dir_item] coord_array = getattr( info, slicing_dir_item ) # Number of cells along the slicing direction n_cells = len(coord_array) diff --git a/openpmd_viewer/openpmd_timeseries/utilities.py b/openpmd_viewer/openpmd_timeseries/utilities.py index c865a5f5..7217dccd 100644 --- a/openpmd_viewer/openpmd_timeseries/utilities.py +++ b/openpmd_viewer/openpmd_timeseries/utilities.py @@ -193,16 +193,15 @@ def combine_cylindrical_components( Fr, Ft, theta, coord, info ): Contains info on the coordinate system """ if theta is not None: - # Fr and Fr are 2Darrays - assert (Fr.ndim == 2) and (Ft.ndim == 2) - if coord == 'x': F = np.cos(theta) * Fr - np.sin(theta) * Ft elif coord == 'y': F = np.sin(theta) * Fr + np.cos(theta) * Ft # Revert the sign below the axis - F[: int(F.shape[0] / 2)] *= -1 - + if info.axes[0] == 'r': + F[ : int(F.shape[0]/2) ] *= -1 + elif (F.ndim == 2) and (info.axes[1] == 'r'): + F[ : , : int(F.shape[1]/2) ] *= -1 else: # Fr, Ft are 3Darrays, info corresponds to Cartesian data assert (Fr.ndim == 3) and (Ft.ndim == 3) From 2c5a75d826f280b6f0fd01f982166a1508e607a7 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Wed, 28 Aug 2019 22:42:51 -0700 Subject: [PATCH 65/90] Correct slicing in cylindrical geometry --- .../data_reader/field_metainfo.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/openpmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py b/openpmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py index 80b5c84a..e6b75e5c 100644 --- a/openpmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py +++ b/openpmd_viewer/openpmd_timeseries/data_reader/field_metainfo.py @@ -75,16 +75,12 @@ def __init__(self, axes, shape, grid_spacing, step = grid_spacing[axis] * grid_unitSI n_points = shape[axis] start = global_offset[axis] * grid_unitSI + position[axis] * step + end = start + (n_points - 1) * step + axis_points = np.linspace(start, end, n_points, endpoint=True) # Create the points below the axis if thetaMode is true if axes[axis] == 'r' and thetaMode: - end = start + (n_points / 2 - 1) * step - axis_points = np.linspace(start, end, n_points / 2, - endpoint=True) axis_points = np.concatenate((-axis_points[::-1], axis_points)) start = -end - else: - end = start + (n_points - 1) * step - axis_points = np.linspace(start, end, n_points, endpoint=True) # Register the results in the object axis_name = axes[axis] setattr(self, axis_name, axis_points) @@ -142,10 +138,12 @@ def _remove_axis(self, obsolete_axis): delattr(self, obsolete_axis) delattr(self, obsolete_axis + 'min') delattr(self, obsolete_axis + 'max') - # Remove from dictionary - for key in list(self.axes.keys()): - if self.axes[key] == obsolete_axis: - del self.axes[key] + # Rebuild the dictionary `axes`, by including the axis + # label in the same order, but omitting obsolete_axis + ndim = len(self.axes) + self.axes = dict( enumerate([ + self.axes[i] for i in range(ndim) \ + if self.axes[i] != obsolete_axis ])) self._generate_imshow_extent() From d6a84bf1e09765e71fb3a6ba2bb7ffba0e66602a Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 29 Aug 2019 06:45:47 -0700 Subject: [PATCH 66/90] Correct default slicing --- openpmd_viewer/openpmd_timeseries/main.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openpmd_viewer/openpmd_timeseries/main.py b/openpmd_viewer/openpmd_timeseries/main.py index 81e4a410..ee1fccf2 100644 --- a/openpmd_viewer/openpmd_timeseries/main.py +++ b/openpmd_viewer/openpmd_timeseries/main.py @@ -344,7 +344,7 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, return(data_list) def get_field(self, field=None, coord=None, t=None, iteration=None, - m='all', theta=0., slicing=0., slicing_dir=None, + m='all', theta=0., slicing=None, slicing_dir=None, plot=False, plot_range=[[None, None], [None, None]], **kw): """ @@ -388,6 +388,8 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box + Default: None, which results in slicing at 0 in all direction + of `slicing_dir`. slicing_dir : str or list of str, optional Direction(s) along which to slice the data @@ -433,6 +435,8 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, # Convert to lists if not isinstance(slicing_dir, list): slicing_dir = [slicing_dir] + if slicing is None: + slicing = [0]*len(slicing_dir) if not isinstance(slicing, list): slicing = [slicing] # Check that the elements are valid From 76717df57bc70f6fc0aa9efdfeb78d5abf74288e Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 29 Aug 2019 06:45:58 -0700 Subject: [PATCH 67/90] Update notebook with respect to slicing --- tutorials/2_Specific-field-geometries.ipynb | 44 +++++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/tutorials/2_Specific-field-geometries.ipynb b/tutorials/2_Specific-field-geometries.ipynb index 3a99a308..a16ab2bd 100644 --- a/tutorials/2_Specific-field-geometries.ipynb +++ b/tutorials/2_Specific-field-geometries.ipynb @@ -129,11 +129,22 @@ " slicing_dir='z', plot=True )" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Slice across x and y (i.e. along a line parallel to the z axis)\n", + "Ez2, info_Ez2 = ts_3d.get_field( field='E', coord='z', iteration=500,\n", + " slicing_dir=['x','y'], plot=True )" + ] + }, { "cell_type": "markdown", "metadata": {}, "source": [ - "- For one given slicing direction, `slicing` allows to select which slice to take: `slicing` is a number between -1 and 1, where -1 indicates to take the slice at the lower bound of the slicing range (e.g. $z_min$ if `slicing_dir` is `z`) and 1 indicates to take the slice at the upper bound of the slicing range (e.g. $z_max$ if `slicing_dir` is `z`). For example:" + "- For one given slicing direction, `slicing` allows to select which slice to take: `slicing` is a number between -1 and 1, where -1 indicates to take the slice at the lower bound of the slicing range (e.g. $z_min$ if `slicing_dir` is `z`) and 1 indicates to take the slice at the upper bound of the slicing range (e.g. $z_{max}$ if `slicing_dir` is `z`). For example:" ] }, { @@ -209,7 +220,7 @@ "source": [ "The argument `theta` (in radians) selects the plane of observation: this plane contains the $z$ axis and has an angle `theta` with respect to the $x$ axis.\n", "\n", - "When passing `slicing=None`, `get_field` returns a full 3D Cartesian array. This can be useful for further analysis by hand, with `numpy` (e.g. calculating the total energy in the field), or for comparison with Cartesian simulations." + "When passing `theta=None`, `get_field` returns a full 3D Cartesian array. This can be useful for further analysis by hand, with `numpy` (e.g. calculating the total energy in the field), or for comparison with Cartesian simulations." ] }, { @@ -227,7 +238,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "- Finally, in cylindrical geometry, the users can also choose the coordinates `r` and `t` for the radial and azimuthal components of the fields. For instance:" + "- In cylindrical geometry, the users can also choose the coordinates `r` and `t` for the radial and azimuthal components of the fields. For instance:" ] }, { @@ -239,6 +250,31 @@ "Er, info_Er = ts_circ.get_field( field='E', coord='r', iteration=500, m=0, \n", " plot=True, theta=0.5)" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Finally, in cylindrical geometry, fields can also be sliced, by using the `r` and `z` direction. (Keep in mind that `slicing_dir` is the direction **orthogonal** to the slice.)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Er_slice, info = ts_circ.get_field( field='E', coord='r', iteration=500, plot=True, slicing_dir='r' )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Er_slice, info = ts_circ.get_field( field='E', coord='r', iteration=500, plot=True, slicing_dir='z' )" + ] } ], "metadata": { @@ -257,7 +293,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.8" + "version": "3.7.3" } }, "nbformat": 4, From 292eaf1598317b930694012075960d87f214e984 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sun, 8 Sep 2019 07:08:17 -0700 Subject: [PATCH 68/90] Use numba instead of cython --- MANIFEST.in | 1 - conda_recipe/meta.yaml | 4 +- .../openpmd_timeseries/cython_function.pyx | 138 ------------------ .../openpmd_timeseries/numba_wrapper.py | 30 ++++ .../openpmd_timeseries/particle_tracker.py | 29 +--- openpmd_viewer/openpmd_timeseries/plotter.py | 19 +-- .../openpmd_timeseries/utilities.py | 83 ++++++++++- setup.py | 20 +-- 8 files changed, 127 insertions(+), 197 deletions(-) delete mode 100644 openpmd_viewer/openpmd_timeseries/cython_function.pyx create mode 100644 openpmd_viewer/openpmd_timeseries/numba_wrapper.py diff --git a/MANIFEST.in b/MANIFEST.in index 561db4e6..7e937e5c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,4 @@ include README.md include requirements.txt -include openpmd_viewer/openpmd_timeseries/cython_function.pyx include openpmd_viewer/notebook_starter/openPMD_notebook include openpmd_viewer/notebook_starter/Template_notebook.ipynb diff --git a/conda_recipe/meta.yaml b/conda_recipe/meta.yaml index baf41eb9..fe9e8de1 100644 --- a/conda_recipe/meta.yaml +++ b/conda_recipe/meta.yaml @@ -16,18 +16,18 @@ requirements: build: - python - setuptools - - cython - numpy - scipy - matplotlib + - numba - h5py - tqdm run: - python - - cython - numpy - scipy - matplotlib + - numba - h5py - jupyter - tqdm diff --git a/openpmd_viewer/openpmd_timeseries/cython_function.pyx b/openpmd_viewer/openpmd_timeseries/cython_function.pyx deleted file mode 100644 index b76440a3..00000000 --- a/openpmd_viewer/openpmd_timeseries/cython_function.pyx +++ /dev/null @@ -1,138 +0,0 @@ -import numpy as np -cimport numpy as np -from cpython cimport bool -cimport cython -from libc.math cimport floor - -@cython.boundscheck(False) -@cython.wraparound(False) -def extract_indices_cython( - np.ndarray[np.int64_t, ndim=1] original_indices, - np.ndarray[np.int64_t, ndim=1] selected_indices, - np.ndarray[np.uint64_t, ndim=1] pid, - np.ndarray[np.uint64_t, ndim=1] selected_pid, - bool preserve_particle_index ): - """ - Go through the sorted arrays `pid` and `selected_pid`, and record - the indices (of the array `pid`) where they match, by storing them - in the array `selected_indices` (this array is thus modified in-place) - - Return the number of elements that were filled in `selected_indices` - """ - cdef unsigned int i = 0 - cdef unsigned int i_select = 0 - cdef unsigned int i_fill = 0 - cdef unsigned int N = pid.shape[0] - cdef unsigned int N_selected = selected_pid.shape[0] - - # Go through both sorted arrays (pid and selected_pid) and match them. - # i.e. whenever the same number appears in both arrays, - # record the corresponding original index in selected_indices - while i < N and i_select < N_selected: - - if pid[i] < selected_pid[i_select]: - i += 1 - elif pid[i] == selected_pid[i_select]: - selected_indices[i_fill] = original_indices[i] - i_fill += 1 - i_select += 1 - elif pid[i] > selected_pid[i_select]: - i_select += 1 - if preserve_particle_index: - # Fill the index, to indicate that the particle is absent - selected_indices[i_fill] = -1 - i_fill += 1 - - return( i_fill ) - - -@cython.boundscheck(False) -@cython.wraparound(False) -def histogram_cic_1d( - np.ndarray[np.float64_t, ndim=1] q1, - np.ndarray[np.float64_t, ndim=1] w, - int nbins, double bins_start, double bins_end ): - """ - Return an 1D histogram of the values in `q1` weighted by `w`, - consisting of `nbins` evenly-spaced bins between `bins_start` - and `bins_end`. Contribution to each bins is determined by the - CIC weighting scheme (i.e. linear weights). - """ - # Define various scalars - cdef double bin_spacing = (bins_end-bins_start)/nbins - cdef double inv_spacing = 1./bin_spacing - cdef int n_ptcl = len(w) - cdef int i_low_bin - cdef double q1_cell - cdef double S_low - - # Allocate array for histogrammed data - hist_data = np.zeros( nbins, dtype=np.float64 ) - - # Go through particle array and bin the data - for i in xrange(n_ptcl): - # Calculate the index of lower bin to which this particle contributes - q1_cell = (q1[i] - bins_start) * inv_spacing - i_low_bin = floor( q1_cell ) - # Calculate corresponding CIC shape and deposit the weight - S_low = 1. - (q1_cell - i_low_bin) - if (i_low_bin >= 0) and (i_low_bin < nbins): - hist_data[ i_low_bin ] += w[i] * S_low - if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): - hist_data[ i_low_bin + 1 ] += w[i] * (1. - S_low) - - return( hist_data ) - - -@cython.boundscheck(False) -@cython.wraparound(False) -def histogram_cic_2d( - np.ndarray[np.float64_t, ndim=1] q1, - np.ndarray[np.float64_t, ndim=1] q2, - np.ndarray[np.float64_t, ndim=1] w, - int nbins_1, double bins_start_1, double bins_end_1, - int nbins_2, double bins_start_2, double bins_end_2 ): - """ - Return an 2D histogram of the values in `q1` and `q2` weighted by `w`, - consisting of `nbins_1` bins in the first dimension and `nbins_2` bins - in the second dimension. - Contribution to each bins is determined by the - CIC weighting scheme (i.e. linear weights). - """ - # Define various scalars - cdef double bin_spacing_1 = (bins_end_1-bins_start_1)/nbins_1 - cdef double inv_spacing_1 = 1./bin_spacing_1 - cdef double bin_spacing_2 = (bins_end_2-bins_start_2)/nbins_2 - cdef double inv_spacing_2 = 1./bin_spacing_2 - cdef int n_ptcl = len(w) - cdef int i1_low_bin, i2_low_bin - cdef double q1_cell, q2_cell - cdef double S1_low, S2_low - - # Allocate array for histogrammed data - hist_data = np.zeros( (nbins_1, nbins_2), dtype=np.float64 ) - - # Go through particle array and bin the data - for i in xrange(n_ptcl): - - # Calculate the index of lower bin to which this particle contributes - q1_cell = (q1[i] - bins_start_1) * inv_spacing_1 - q2_cell = (q2[i] - bins_start_2) * inv_spacing_2 - i1_low_bin = floor( q1_cell ) - i2_low_bin = floor( q2_cell ) - - # Calculate corresponding CIC shape and deposit the weight - S1_low = 1. - (q1_cell - i1_low_bin) - S2_low = 1. - (q2_cell - i2_low_bin) - if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): - if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low - if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): - hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) - if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): - if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): - hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low - if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): - hist_data[ i1_low_bin+1, i2_low_bin+1 ] += w[i]*(1.-S1_low)*(1.-S2_low) - - return( hist_data ) diff --git a/openpmd_viewer/openpmd_timeseries/numba_wrapper.py b/openpmd_viewer/openpmd_timeseries/numba_wrapper.py new file mode 100644 index 00000000..f03ebc54 --- /dev/null +++ b/openpmd_viewer/openpmd_timeseries/numba_wrapper.py @@ -0,0 +1,30 @@ +""" +This file is part of the openPMD-viewer. + +It defines a wrapper around numba. + +Copyright 2019, openPMD-viewer contributors +Author: Remi Lehe +License: 3-Clause-BSD-LBNL +""" +import warnings + +try: + # Import jit decorator from numba + import numba + numba_installed = True + jit = numba.njit(cache=True) + +except ImportError: + numba_installed = False + # Create dummy decorator: warns about installing numba when calling + # the decorated function. + def jit(f): + def decorated_f(*args, **kwargs): + warnings.warn( + '\nOne of the functions called by openPMD-viewer ' +\ + '(%s)\n' %f.__name__ +\ + 'could have been faster if `numba` had been installed.\n' +\ + 'Please consider installing `numba` (e.g. `pip install numba`)') + return f(*args, **kwargs) + return decorated_f diff --git a/openpmd_viewer/openpmd_timeseries/particle_tracker.py b/openpmd_viewer/openpmd_timeseries/particle_tracker.py index 7aa5dfd7..40150f3f 100644 --- a/openpmd_viewer/openpmd_timeseries/particle_tracker.py +++ b/openpmd_viewer/openpmd_timeseries/particle_tracker.py @@ -7,15 +7,9 @@ Authors: Remi Lehe License: 3-Clause-BSD-LBNL """ -import warnings import numpy as np from .data_reader.particle_reader import read_species_data -try: - from .cython_function import extract_indices_cython - cython_function_available = True -except ImportError: - cython_function_available = False - +from .numba_wrapper import jit class ParticleTracker( object ): """ @@ -104,14 +98,6 @@ def __init__(self, ts, species=None, t=None, self.species = species self.preserve_particle_index = preserve_particle_index - # Print a warning if the Cython function is unavailable - if not cython_function_available: - warnings.warn( - "\nUnable to compile particle tracking with Cython. \n" - "The ParticleTracker will still work, but will be slow. \n" - "For faster particle tracking: \n" - " - make sure that Cython is installed \n" - " - then reinstall openPMD-viewer") def extract_tracked_particles( self, file_handle, data_list, species, extensions ): @@ -245,8 +231,8 @@ def get_extraction_indices( self, pid ): return( selected_indices ) - -def extract_indices_python( original_indices, selected_indices, +@jit +def extract_indices( original_indices, selected_indices, pid, selected_pid, preserve_particle_index ): """ Go through the sorted arrays `pid` and `selected_pid`, and record @@ -280,12 +266,3 @@ def extract_indices_python( original_indices, selected_indices, i_fill += 1 return( i_fill ) - - -# The functions `extract_indices_python` and `extract_indices_cython` -# perform the same operations, but the cython version is much faster -# since it is compiled -if cython_function_available: - extract_indices = extract_indices_cython -else: - extract_indices = extract_indices_python diff --git a/openpmd_viewer/openpmd_timeseries/plotter.py b/openpmd_viewer/openpmd_timeseries/plotter.py index ec93a9d5..5f051de3 100644 --- a/openpmd_viewer/openpmd_timeseries/plotter.py +++ b/openpmd_viewer/openpmd_timeseries/plotter.py @@ -17,11 +17,10 @@ matplotlib_installed = True except ImportError: matplotlib_installed = False -try: - from .cython_function import histogram_cic_1d, histogram_cic_2d - cython_function_available = True -except ImportError: - cython_function_available = False + +from .numba_wrapper import numba_installed +if numba_installed: + from .utilities import histogram_cic_1d, histogram_cic_2d # Redefine the default matplotlib formatter for ticks if matplotlib_installed: @@ -150,7 +149,7 @@ def hist1d(self, q1, w, quantity1, species, current_i, nbins, hist_range, time = self.t[current_i] # Check deposition method - if deposition == 'cic' and not cython_function_available: + if deposition == 'cic' and not numba_installed: print_cic_unavailable() deposition = 'ngp' @@ -227,7 +226,7 @@ def hist2d(self, q1, q2, w, quantity1, quantity2, species, current_i, time = self.t[current_i] # Check deposition method - if deposition == 'cic' and not cython_function_available: + if deposition == 'cic' and not numba_installed: print_cic_unavailable() deposition = 'ngp' @@ -388,10 +387,8 @@ def show_field_2d(self, F, info, slicing_dir, m, field_label, geometry, def print_cic_unavailable(): warnings.warn( "\nCIC particle histogramming is unavailable because \n" - "Cython is not installed. NGP histogramming is used instead.\n" - "For CIC histogramming: \n" - " - make sure that Cython is installed \n" - " - then reinstall openPMD-viewer") + "Numba is not installed. NGP histogramming is used instead.\n" + "Please considering installing numba (e.g. `pip install numba`)") def check_matplotlib(): diff --git a/openpmd_viewer/openpmd_timeseries/utilities.py b/openpmd_viewer/openpmd_timeseries/utilities.py index c865a5f5..2b575aba 100644 --- a/openpmd_viewer/openpmd_timeseries/utilities.py +++ b/openpmd_viewer/openpmd_timeseries/utilities.py @@ -9,10 +9,11 @@ """ import os +import math import numpy as np import h5py from .data_reader.particle_reader import read_species_data - +from .numba_wrapper import jit def list_h5_files(path_to_dir): """ @@ -222,7 +223,85 @@ def combine_cylindrical_components( Fr, Ft, theta, coord, info ): return F - +@jit +def histogram_cic_1d( q1, w, nbins, bins_start, bins_end ): + """ + Return an 1D histogram of the values in `q1` weighted by `w`, + consisting of `nbins` evenly-spaced bins between `bins_start` + and `bins_end`. Contribution to each bins is determined by the + CIC weighting scheme (i.e. linear weights). + """ + # Define various scalars + bin_spacing = (bins_end-bins_start)/nbins + inv_spacing = 1./bin_spacing + n_ptcl = len(w) + + # Allocate array for histogrammed data + hist_data = np.zeros( nbins, dtype=np.float64 ) + + # Go through particle array and bin the data + for i in range(n_ptcl): + # Calculate the index of lower bin to which this particle contributes + q1_cell = (q1[i] - bins_start) * inv_spacing + i_low_bin = int( math.floor( q1_cell ) ) + # Calculate corresponding CIC shape and deposit the weight + S_low = 1. - (q1_cell - i_low_bin) + if (i_low_bin >= 0) and (i_low_bin < nbins): + hist_data[ i_low_bin ] += w[i] * S_low + if (i_low_bin + 1 >= 0) and (i_low_bin + 1 < nbins): + hist_data[ i_low_bin + 1 ] += w[i] * (1. - S_low) + + return( hist_data ) + + +@jit +def histogram_cic_2d( q1, q2, w, + nbins_1, bins_start_1, bins_end_1, + nbins_2, bins_start_2, bins_end_2 ): + """ + Return an 2D histogram of the values in `q1` and `q2` weighted by `w`, + consisting of `nbins_1` bins in the first dimension and `nbins_2` bins + in the second dimension. + Contribution to each bins is determined by the + CIC weighting scheme (i.e. linear weights). + """ + # Define various scalars + bin_spacing_1 = (bins_end_1-bins_start_1)/nbins_1 + inv_spacing_1 = 1./bin_spacing_1 + bin_spacing_2 = (bins_end_2-bins_start_2)/nbins_2 + inv_spacing_2 = 1./bin_spacing_2 + n_ptcl = len(w) + + # Allocate array for histogrammed data + hist_data = np.zeros( (nbins_1, nbins_2), dtype=np.float64 ) + + # Go through particle array and bin the data + for i in range(n_ptcl): + + # Calculate the index of lower bin to which this particle contributes + q1_cell = (q1[i] - bins_start_1) * inv_spacing_1 + q2_cell = (q2[i] - bins_start_2) * inv_spacing_2 + i1_low_bin = int( math.floor( q1_cell ) ) + i2_low_bin = int( math.floor( q2_cell ) ) + + # Calculate corresponding CIC shape and deposit the weight + S1_low = 1. - (q1_cell - i1_low_bin) + S2_low = 1. - (q2_cell - i2_low_bin) + if (i1_low_bin >= 0) and (i1_low_bin < nbins_1): + if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + hist_data[ i1_low_bin, i2_low_bin ] += w[i]*S1_low*S2_low + if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): + hist_data[ i1_low_bin, i2_low_bin+1 ] += w[i]*S1_low*(1.-S2_low) + if (i1_low_bin+1 >= 0) and (i1_low_bin+1 < nbins_1): + if (i2_low_bin >= 0) and (i2_low_bin < nbins_2): + hist_data[ i1_low_bin+1, i2_low_bin ] += w[i]*(1.-S1_low)*S2_low + if (i2_low_bin+1 >= 0) and (i2_low_bin+1 < nbins_2): + hist_data[ i1_low_bin+1, i2_low_bin+1 ] += w[i]*(1.-S1_low)*(1.-S2_low) + + return( hist_data ) + + +@jit def construct_3d_from_circ( F3d, Fcirc, x_array, y_array, modes, nx, ny, nz, nr, nmodes, inv_dr, rmax ): """ diff --git a/setup.py b/setup.py index decff674..d4f95fc2 100644 --- a/setup.py +++ b/setup.py @@ -22,18 +22,6 @@ def run_tests(self): errcode = pytest.main([]) sys.exit(errcode) -# Try to compile the Cython function -try: - import numpy - include_dirs = [numpy.get_include()] - from Cython.Build import cythonize - ext_modules = cythonize( - "openpmd_viewer/openpmd_timeseries/cython_function.pyx") -except ImportError: - # If the compilation fails, still install the package in a robust way - include_dirs = [] - ext_modules = [] - # Main setup command setup(name='openPMD-viewer', version=__version__, @@ -48,13 +36,11 @@ def run_tests(self): package_data={'openpmd_viewer': ['notebook_starter/*.ipynb']}, scripts=['openpmd_viewer/notebook_starter/openPMD_notebook'], tests_require=['pytest', 'jupyter'], - ext_modules=ext_modules, - include_dirs=include_dirs, install_requires=install_requires, extras_require = { - 'GUI': ["ipywidgets", "matplotlib", "cython"], - 'plot': ["matplotlib", "cython"], - 'tutorials': ["ipywidgets", "matplotlib", "wget", "cython"] + 'GUI': ["ipywidgets", "matplotlib"], + 'plot': ["matplotlib"], + 'tutorials': ["ipywidgets", "matplotlib", "wget"] }, cmdclass={'test': PyTest}, platforms='any', From e60f5185a2313955a48364f7cc141b1f4d59655a Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sat, 12 Oct 2019 20:38:07 -0700 Subject: [PATCH 69/90] Update slicing and plotter in get_laser_envelope --- openpmd_viewer/addons/pic/lpa_diagnostics.py | 91 ++++++++++--------- openpmd_viewer/openpmd_timeseries/main.py | 16 +--- .../openpmd_timeseries/utilities.py | 23 +++++ 3 files changed, 75 insertions(+), 55 deletions(-) diff --git a/openpmd_viewer/addons/pic/lpa_diagnostics.py b/openpmd_viewer/addons/pic/lpa_diagnostics.py index c837cc4e..596e9a05 100644 --- a/openpmd_viewer/addons/pic/lpa_diagnostics.py +++ b/openpmd_viewer/addons/pic/lpa_diagnostics.py @@ -14,7 +14,7 @@ import numpy as np import scipy.constants as const from scipy.optimize import curve_fit -from openpmd_viewer.openpmd_timeseries.plotter import check_matplotlib +from openpmd_viewer.openpmd_timeseries.utilities import sanitize_slicing from scipy.signal import hilbert try: import matplotlib.pyplot as plt @@ -438,8 +438,9 @@ def get_current( self, t=None, iteration=None, species=None, select=None, return(current, info) def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', - index='center', theta=0, slicing=0, - slicing_dir=None, plot=False, **kw ): + theta=0, slicing=0, slicing_dir=None, + plot=False, + plot_range=[[None, None], [None, None]], **kw ): """ Calculate a laser field by filtering out high frequencies. Can either return the envelope slice-wise or a full 2D envelope. @@ -463,11 +464,6 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', Either 'all' (for the sum of all the modes) or an integer (for the selection of a particular mode) - index : int or str, optional - Transversal index of the slice from which to calculate the envelope - Default is 'center', using the center slice. - Use 'all' to calculate a full 2D envelope - theta : float, optional Only used for thetaMode geometry The angle of the plane of observation, with respect to the x axis @@ -494,6 +490,12 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', plot : bool, optional Whether to plot the requested quantity + plot_range : list of lists + A list containing 2 lists of 2 elements each + Indicates the values between which to clip the plot, + along the 1st axis (first list) and 2nd axis (second list) + Default: plots the full extent of the simulation box + **kw : dict, otional Additional options to be passed to matplotlib's `plot`(1D) or `imshow` (2D) method @@ -507,45 +509,48 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', # Check if polarization has been entered if pol is None: raise ValueError('The `pol` argument is missing or erroneous.') - # Get field data - field = self.get_field( t=t, iteration=iteration, field='E', - coord=pol, theta=theta, m=m, - slicing=slicing, slicing_dir=slicing_dir ) - info = field[1] - if index == 'all': - # Filter the full 2D array - e_complx = hilbert(field[0], axis=1) - elif index == 'center': - # Filter the central slice (1D array) - field_slice = field[0][int( field[0].shape[0] / 2), :] - e_complx = hilbert(field_slice) - else: - # Filter the requested slice (2D array) - field_slice = field[0][index, :] - e_complx = hilbert(field_slice) + # Prevent slicing across z at this point + # (z axis is needed for calculation of envelope) + slicing_coord_z = None + if slicing_dir is not None: + slicing_dir, slicing = sanitize_slicing(slicing_dir, slicing) + if 'z' in slicing_dir: + index_slicing_z = slicing_dir.index('z') + slicing_dir.pop(index_slicing_z) + slicing_coord_z = slicing.pop(index_slicing_z) + # Get field data, and perform Hilbert transform + field, info = self.get_field( t=t, iteration=iteration, field='E', + coord=pol, theta=theta, m=m, + slicing=slicing, slicing_dir=slicing_dir ) + e_complx = hilbert(field, axis=-1) envelope = np.abs(e_complx) - # Restrict the metainformation to 1d if needed - if index != 'all': - info.restrict_to_1Daxis( info.axes[1] ) + # If the user asked for slicing along z, add it at this point + if slicing_coord_z is not None: + inverted_axes_dict = {info.axes[key]: key for key in info.axes.keys()} + slicing_index = inverted_axes_dict['z'] + coord_array = getattr( info, 'z' ) + # Number of cells along the slicing direction + n_cells = len(coord_array) + # Index of the slice (prevent stepping out of the array) + i_cell = int( 0.5 * (slicing_coord_z + 1.) * n_cells ) + i_cell = max( i_cell, 0 ) + i_cell = min( i_cell, n_cells - 1) + envelope = np.take( envelope, [i_cell], axis=slicing_index ) + envelope = np.squeeze(envelope) + # Remove the sliced labels from the FieldMetaInformation + info._remove_axis('z') # Plot the result if needed if plot: - check_matplotlib() - iteration = self.iterations[ self._current_i ] - time_s = self.t[ self._current_i ] - if index != 'all': - plt.plot( info.z, envelope, **kw) - plt.ylabel('$E_%s \;(V/m)$' % pol, - fontsize=self.plotter.fontsize) - else: - plt.imshow( envelope, extent=info.imshow_extent, - aspect='auto', **kw) - plt.colorbar() - plt.ylabel('$%s \;(m)$' % pol, - fontsize=self.plotter.fontsize) - plt.title("Laser envelope at %.2e s (iteration %d)" - % (time_s, iteration ), fontsize=self.plotter.fontsize) - plt.xlabel('$z \;(m)$', fontsize=self.plotter.fontsize) + geometry = self.fields_metadata['E']['geometry'] + field_label = 'E%s (envelope)' %pol + if envelope.ndim == 1: + self.plotter.show_field_1d(envelope, info, field_label, + self._current_i, plot_range=plot_range, **kw) + elif envelope.ndim == 2: + self.plotter.show_field_2d(envelope, info, slicing_dir, m, + field_label, geometry, self._current_i, + plot_range=plot_range, **kw) # Return the result return( envelope, info ) diff --git a/openpmd_viewer/openpmd_timeseries/main.py b/openpmd_viewer/openpmd_timeseries/main.py index ee1fccf2..d73f3d35 100644 --- a/openpmd_viewer/openpmd_timeseries/main.py +++ b/openpmd_viewer/openpmd_timeseries/main.py @@ -12,7 +12,8 @@ import h5py as h5 from tqdm import tqdm from .utilities import list_h5_files, apply_selection, fit_bins_to_grid, \ - combine_cylindrical_components, try_array + combine_cylindrical_components, try_array, \ + sanitize_slicing from .plotter import Plotter from .particle_tracker import ParticleTracker from .data_reader.params_reader import read_openPMD_params @@ -431,14 +432,8 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, "The available fields are: \n - %s\nPlease set the `field` " "argument accordingly." % field_list) # Check slicing + slicing_dir, slicing = sanitize_slicing(slicing_dir, slicing) if slicing_dir is not None: - # Convert to lists - if not isinstance(slicing_dir, list): - slicing_dir = [slicing_dir] - if slicing is None: - slicing = [0]*len(slicing_dir) - if not isinstance(slicing, list): - slicing = [slicing] # Check that the elements are valid axis_labels = self.fields_metadata[field]['axis_labels'] for axis in slicing_dir: @@ -447,10 +442,7 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, raise OpenPMDException( 'The `slicing_dir` argument is erroneous: contains %s\n' 'The available axes are: \n - %s' % (axis, axes_list) ) - if len(slicing_dir) != len(slicing): - raise OpenPMDException( - 'The `slicing_dir` argument is erroneous: \nIt should have' - 'the same number of elements as `slicing_dir`.') + # Check the coordinate (for vector fields) if self.fields_metadata[field]['type'] == 'vector': available_coord = ['x', 'y', 'z'] diff --git a/openpmd_viewer/openpmd_timeseries/utilities.py b/openpmd_viewer/openpmd_timeseries/utilities.py index 25638b1f..beaa0d69 100644 --- a/openpmd_viewer/openpmd_timeseries/utilities.py +++ b/openpmd_viewer/openpmd_timeseries/utilities.py @@ -15,6 +15,29 @@ from .data_reader.particle_reader import read_species_data from .numba_wrapper import jit +def sanitize_slicing(slicing_dir, slicing): + """ + TODO + """ + # Skip None and empty lists + if slicing_dir is None or slicing_dir == []: + return None, None + + # Convert to lists + if not isinstance(slicing_dir, list): + slicing_dir = [slicing_dir] + if slicing is None: + slicing = [0]*len(slicing_dir) + if not isinstance(slicing, list): + slicing = [slicing] + # Check that the length are matching + if len(slicing_dir) != len(slicing): + raise OpenPMDException( + 'The `slicing_dir` argument is erroneous: \nIt should have' + 'the same number of elements as `slicing_dir`.') + return slicing_dir, slicing + + def list_h5_files(path_to_dir): """ Return a list of the hdf5 files in this directory, From 2afa4f3eef4934fc11bf1b60377138c2eccc5066 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sat, 12 Oct 2019 21:15:39 -0700 Subject: [PATCH 70/90] Fix import errors --- openpmd_viewer/addons/pic/lpa_diagnostics.py | 1 + openpmd_viewer/openpmd_timeseries/utilities.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/openpmd_viewer/addons/pic/lpa_diagnostics.py b/openpmd_viewer/addons/pic/lpa_diagnostics.py index 596e9a05..353cb98e 100644 --- a/openpmd_viewer/addons/pic/lpa_diagnostics.py +++ b/openpmd_viewer/addons/pic/lpa_diagnostics.py @@ -15,6 +15,7 @@ import scipy.constants as const from scipy.optimize import curve_fit from openpmd_viewer.openpmd_timeseries.utilities import sanitize_slicing +from openpmd_viewer.openpmd_timeseries.plotter import check_matplotlib from scipy.signal import hilbert try: import matplotlib.pyplot as plt diff --git a/openpmd_viewer/openpmd_timeseries/utilities.py b/openpmd_viewer/openpmd_timeseries/utilities.py index beaa0d69..ab8daa1e 100644 --- a/openpmd_viewer/openpmd_timeseries/utilities.py +++ b/openpmd_viewer/openpmd_timeseries/utilities.py @@ -32,7 +32,7 @@ def sanitize_slicing(slicing_dir, slicing): slicing = [slicing] # Check that the length are matching if len(slicing_dir) != len(slicing): - raise OpenPMDException( + raise ValueError( 'The `slicing_dir` argument is erroneous: \nIt should have' 'the same number of elements as `slicing_dir`.') return slicing_dir, slicing From e6dd997c8b6c7b72b04f4b143af1437c6692d2fd Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sat, 12 Oct 2019 21:47:16 -0700 Subject: [PATCH 71/90] Fix get_spectrogram --- openpmd_viewer/addons/pic/lpa_diagnostics.py | 26 ++++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/openpmd_viewer/addons/pic/lpa_diagnostics.py b/openpmd_viewer/addons/pic/lpa_diagnostics.py index 353cb98e..a9289b8a 100644 --- a/openpmd_viewer/addons/pic/lpa_diagnostics.py +++ b/openpmd_viewer/addons/pic/lpa_diagnostics.py @@ -893,8 +893,8 @@ def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, else: raise ValueError('Unknown method: {:s}'.format(method)) - def get_spectrogram( self, t=None, iteration=None, pol=None, theta=0, - slicing_dir=None, slicing=0., plot=False, **kw ): + def get_spectrogram( self, t=None, iteration=None, pol=None, + plot=False, **kw ): """ Calculates the spectrogram of a laserpulse, by the FROG method. @@ -932,15 +932,25 @@ def get_spectrogram( self, t=None, iteration=None, pol=None, theta=0, - info : a FieldMetaInformation object (see the corresponding docstring) """ + # Get a lineout along the 'z' axis, + # i.e. slice across all transverse directions + geometry = self.fields_metadata['E']['geometry'] + if geometry == "2dcartesian": + slicing_dir = 'x' + elif geometry == "3dcartesian": + slicing_dir = ['x', 'y'] + elif geometry == "thetaMode": + slicing_dir = 'r' + else: + raise OpenPMDException('Unknown geometry: %s' %geometry) + # Get the field envelope - env, _ = self.get_laser_envelope(t=t, iteration=iteration, pol=pol) + env, _ = self.get_laser_envelope(t=t, iteration=iteration, + pol=pol, slicing_dir=slicing_dir) + print(env.shape) # Get the field E, info = self.get_field( t=t, iteration=iteration, field='E', - coord=pol, theta=theta, - slicing_dir=slicing_dir, - slicing=slicing) - # Get central slice - E = E[ int(E.shape[0] / 2), :] + coord=pol, slicing_dir=slicing_dir) Nz = len(E) # Get time domain of the data tmin = info.zmin / const.c From 5250378544af6d5234e93c2c205f5e18d016ac5c Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sun, 13 Oct 2019 07:20:53 -0700 Subject: [PATCH 72/90] Fix import error --- openpmd_viewer/addons/pic/lpa_diagnostics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpmd_viewer/addons/pic/lpa_diagnostics.py b/openpmd_viewer/addons/pic/lpa_diagnostics.py index a9289b8a..9be78ed1 100644 --- a/openpmd_viewer/addons/pic/lpa_diagnostics.py +++ b/openpmd_viewer/addons/pic/lpa_diagnostics.py @@ -942,7 +942,7 @@ def get_spectrogram( self, t=None, iteration=None, pol=None, elif geometry == "thetaMode": slicing_dir = 'r' else: - raise OpenPMDException('Unknown geometry: %s' %geometry) + raise ValueError('Unknown geometry: %s' %geometry) # Get the field envelope env, _ = self.get_laser_envelope(t=t, iteration=iteration, From 9710e1a3610e1e748774776cc0277c2b2b51e6ab Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sun, 13 Oct 2019 07:39:19 -0700 Subject: [PATCH 73/90] Correct laser functions --- openpmd_viewer/addons/pic/lpa_diagnostics.py | 81 ++++++++------------ 1 file changed, 32 insertions(+), 49 deletions(-) diff --git a/openpmd_viewer/addons/pic/lpa_diagnostics.py b/openpmd_viewer/addons/pic/lpa_diagnostics.py index 9be78ed1..da7ab95d 100644 --- a/openpmd_viewer/addons/pic/lpa_diagnostics.py +++ b/openpmd_viewer/addons/pic/lpa_diagnostics.py @@ -649,19 +649,9 @@ def get_spectrum( self, t=None, iteration=None, pol=None, # Check if polarization has been entered if pol not in ['x', 'y']: raise ValueError('The `pol` argument is missing or erroneous.') - if pol == 'x': - theta = 0 - else: - theta = np.pi / 2. - if "3dcartesian" in self.avail_geom: - slicing = 0. - if pol == 'x': - slicing_dir = 'y' - else: - slicing_dir = 'x' - else: - slicing_dir = None - slicing = None + # Get a lineout along the 'z' axis, + geometry = self.fields_metadata['E']['geometry'] + slicing_dir = get_slicing_for_longitudinal_lineout(geometry) # Get field data field, info = self.get_field( t=t, iteration=iteration, field='E', @@ -715,20 +705,12 @@ def get_a0( self, t=None, iteration=None, pol=None ): ------- Float with normalized vector potential a0 """ + # Check that the polarization has been properly entered if pol not in ['x', 'y']: raise ValueError('The `pol` argument is missing or erroneous.') - if pol == 'x': - theta = 0 - else: - theta = np.pi / 2. - slicing = 0. - if "3dcartesian" in self.avail_geom: - if pol == 'x': - slicing_dir = 'y' - else: - slicing_dir = 'x' - else: - slicing_dir = None + # Get a lineout along the 'z' axis, + geometry = self.fields_metadata['E']['geometry'] + slicing_dir = get_slicing_for_longitudinal_lineout(geometry) # Get the peak field from field envelope Emax = np.amax(self.get_laser_envelope(t=t, iteration=iteration, @@ -770,25 +752,16 @@ def get_ctau( self, t=None, iteration=None, pol=None, method='fit' ): ------- Float with ctau in meters """ + # Check that the polarization has been properly entered if pol not in ['x', 'y']: raise ValueError('The `pol` argument is missing or erroneous.') - if pol == 'x': - theta = 0 - else: - theta = np.pi / 2. - slicing = 0. - if "3dcartesian" in self.avail_geom: - if pol == 'x': - slicing_dir = 'y' - else: - slicing_dir = 'x' - else: - slicing_dir = None + # Get a lineout along the 'z' axis, + geometry = self.fields_metadata['E']['geometry'] + slicing_dir = get_slicing_for_longitudinal_lineout(geometry) + # Get the field envelope E, info = self.get_laser_envelope(t=t, iteration=iteration, - pol=pol, theta=theta, - slicing=slicing, - slicing_dir=slicing_dir) + pol=pol, slicing_dir=slicing_dir) # Calculate ctau with RMS value ctau = np.sqrt(2) * w_std(info.z, E) if method == 'rms': @@ -859,6 +832,11 @@ def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, ------- Float with laser waist in meters """ + # In 3D slice across 'y' by default + if slicing_dir is None: + slicing_dir = 'y' + slicing = 0 + # Get the field envelope field, info = self.get_laser_envelope(t=t, iteration=iteration, pol=pol, index='all', @@ -933,16 +911,8 @@ def get_spectrogram( self, t=None, iteration=None, pol=None, (see the corresponding docstring) """ # Get a lineout along the 'z' axis, - # i.e. slice across all transverse directions geometry = self.fields_metadata['E']['geometry'] - if geometry == "2dcartesian": - slicing_dir = 'x' - elif geometry == "3dcartesian": - slicing_dir = ['x', 'y'] - elif geometry == "thetaMode": - slicing_dir = 'r' - else: - raise ValueError('Unknown geometry: %s' %geometry) + slicing_dir = get_slicing_for_longitudinal_lineout(geometry) # Get the field envelope env, _ = self.get_laser_envelope(t=t, iteration=iteration, @@ -1117,3 +1087,16 @@ def emittance_from_coord(x, y, ux, uy, w): emit_x = ( abs(xsq * uxsq - xux ** 2) )**.5 emit_y = ( abs(ysq * uysq - yuy ** 2) )**.5 return emit_x, emit_y + +def get_slicing_for_longitudinal_lineout(geometry): + """ + TODO + """ + if geometry == "2dcartesian": + return 'x' + elif geometry == "3dcartesian": + return ['x', 'y'] + elif geometry == "thetaMode": + return 'r' + else: + raise ValueError('Unknown geometry: %s' %geometry) From 40a60b58bb76ee3a384e1a7f53284ba31360c93f Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Sun, 13 Oct 2019 11:07:13 -0700 Subject: [PATCH 74/90] Fix various issues --- openpmd_viewer/addons/pic/lpa_diagnostics.py | 92 +++++++------------- 1 file changed, 31 insertions(+), 61 deletions(-) diff --git a/openpmd_viewer/addons/pic/lpa_diagnostics.py b/openpmd_viewer/addons/pic/lpa_diagnostics.py index da7ab95d..af5b9212 100644 --- a/openpmd_viewer/addons/pic/lpa_diagnostics.py +++ b/openpmd_viewer/addons/pic/lpa_diagnostics.py @@ -508,7 +508,7 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', - A FieldMetaInformation object """ # Check if polarization has been entered - if pol is None: + if pol not in ['x', 'y']: raise ValueError('The `pol` argument is missing or erroneous.') # Prevent slicing across z at this point # (z axis is needed for calculation of envelope) @@ -650,15 +650,11 @@ def get_spectrum( self, t=None, iteration=None, pol=None, if pol not in ['x', 'y']: raise ValueError('The `pol` argument is missing or erroneous.') # Get a lineout along the 'z' axis, - geometry = self.fields_metadata['E']['geometry'] - slicing_dir = get_slicing_for_longitudinal_lineout(geometry) + slicing_dir = self._get_slicing_for_longitudinal_lineout() # Get field data - field, info = self.get_field( t=t, iteration=iteration, field='E', - coord=pol, theta=theta, m=m, - slicing=slicing, slicing_dir=slicing_dir ) - # Get central field lineout - field1d = field[ int( field.shape[0] / 2 ), :] + field1d, info = self.get_field( t=t, iteration=iteration, field='E', + coord=pol, m=m, slicing_dir=slicing_dir ) # FFT of 1d data dt = (info.z[1] - info.z[0]) / const.c # Integration step for the FFT fft_field = np.fft.fft(field1d) * dt @@ -705,18 +701,12 @@ def get_a0( self, t=None, iteration=None, pol=None ): ------- Float with normalized vector potential a0 """ - # Check that the polarization has been properly entered - if pol not in ['x', 'y']: - raise ValueError('The `pol` argument is missing or erroneous.') # Get a lineout along the 'z' axis, - geometry = self.fields_metadata['E']['geometry'] - slicing_dir = get_slicing_for_longitudinal_lineout(geometry) + slicing_dir = self._get_slicing_for_longitudinal_lineout() # Get the peak field from field envelope Emax = np.amax(self.get_laser_envelope(t=t, iteration=iteration, - pol=pol, theta=theta, - slicing=slicing, - slicing_dir=slicing_dir)[0]) + pol=pol, slicing_dir=slicing_dir)[0]) # Get mean frequency omega = self.get_main_frequency(t=t, iteration=iteration, pol=pol) # Calculate a0 @@ -752,12 +742,8 @@ def get_ctau( self, t=None, iteration=None, pol=None, method='fit' ): ------- Float with ctau in meters """ - # Check that the polarization has been properly entered - if pol not in ['x', 'y']: - raise ValueError('The `pol` argument is missing or erroneous.') # Get a lineout along the 'z' axis, - geometry = self.fields_metadata['E']['geometry'] - slicing_dir = get_slicing_for_longitudinal_lineout(geometry) + slicing_dir = self._get_slicing_for_longitudinal_lineout() # Get the field envelope E, info = self.get_laser_envelope(t=t, iteration=iteration, @@ -803,25 +789,6 @@ def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, Only used for thetaMode geometry The angle of the plane of observation, with respect to the x axis - slicing : float or list of float, optional - Number(s) between -1 and 1 that indicate where to slice the data, - along the directions in `slicing_dir` - -1 : lower edge of the simulation box - 0 : middle of the simulation box - 1 : upper edge of the simulation box - If slicing is None, the full grid is returned. - Default is None - - slicing_dir : str or list of str, optional - Direction(s) along which to slice the data - + In cartesian geometry, elements can be: - - 1d: 'z' - - 2d: 'x' and/or 'z' - - 3d: 'x' and/or 'y' and/or 'z' - + In cylindrical geometry, elements can be 'r' and/or 'z' - Returned array is reduced by 1 dimension per slicing. - Default is None. - method : str, optional The method which is used to compute the waist 'fit': Gaussian fit of the transverse profile @@ -832,17 +799,19 @@ def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, ------- Float with laser waist in meters """ - # In 3D slice across 'y' by default - if slicing_dir is None: + # In 3D, slice across 'y' by default + geometry = self.fields_metadata['E']['geometry'] + if geometry == '3dcartesian': slicing_dir = 'y' - slicing = 0 + else: + slicing_dir = None - # Get the field envelope + # Get the field envelope (as 2D array) field, info = self.get_laser_envelope(t=t, iteration=iteration, pol=pol, index='all', - slicing=slicing, slicing_dir=slicing_dir, theta=theta) + assert field.ndim == 2 # Find the indices of the maximum field, and # pick the corresponding transverse slice itrans_max, iz_max = np.unravel_index( @@ -910,9 +879,8 @@ def get_spectrogram( self, t=None, iteration=None, pol=None, - info : a FieldMetaInformation object (see the corresponding docstring) """ - # Get a lineout along the 'z' axis, - geometry = self.fields_metadata['E']['geometry'] - slicing_dir = get_slicing_for_longitudinal_lineout(geometry) + # Get a lineout along the 'z' axis + slicing_dir = self._get_slicing_for_longitudinal_lineout() # Get the field envelope env, _ = self.get_laser_envelope(t=t, iteration=iteration, @@ -969,6 +937,21 @@ def get_spectrogram( self, t=None, iteration=None, pol=None, return( spectrogram, info ) + def _get_slicing_for_longitudinal_lineout(self): + """ + TODO + """ + geometry = self.fields_metadata['E']['geometry'] + if geometry == "2dcartesian": + return 'x' + elif geometry == "3dcartesian": + return ['x', 'y'] + elif geometry == "thetaMode": + return 'r' + else: + raise ValueError('Unknown geometry: %s' %geometry) + + def w_ave( a, weights ): """ Calculate the weighted average of array `a` @@ -1087,16 +1070,3 @@ def emittance_from_coord(x, y, ux, uy, w): emit_x = ( abs(xsq * uxsq - xux ** 2) )**.5 emit_y = ( abs(ysq * uysq - yuy ** 2) )**.5 return emit_x, emit_y - -def get_slicing_for_longitudinal_lineout(geometry): - """ - TODO - """ - if geometry == "2dcartesian": - return 'x' - elif geometry == "3dcartesian": - return ['x', 'y'] - elif geometry == "thetaMode": - return 'r' - else: - raise ValueError('Unknown geometry: %s' %geometry) From dc546e20903e9431efa4540d5417daf278c79176 Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Wed, 27 Nov 2019 09:28:44 -0800 Subject: [PATCH 75/90] Upcoming 1.0: Py 3.8 in CI Add Python 3.8 support for CI in upcoming-1.0 branch. --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index d2d740be..4f82ca0b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,8 @@ matrix: python: "3.6" - os: linux python: "3.7" + - os: linux + python: "3.8" before_install: # Setup anaconda From 88beb2b6707731810f2c70a2fde7b6ecd277b13a Mon Sep 17 00:00:00 2001 From: Soeren Jalas Date: Wed, 27 Nov 2019 15:19:10 +0100 Subject: [PATCH 76/90] Make get_current more robust for empty particle selections --- openpmd_viewer/addons/pic/lpa_diagnostics.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/openpmd_viewer/addons/pic/lpa_diagnostics.py b/openpmd_viewer/addons/pic/lpa_diagnostics.py index c837cc4e..601f600d 100644 --- a/openpmd_viewer/addons/pic/lpa_diagnostics.py +++ b/openpmd_viewer/addons/pic/lpa_diagnostics.py @@ -411,15 +411,20 @@ def get_current( self, t=None, iteration=None, species=None, select=None, var_list=['z', 'uz', 'uy', 'ux', 'w', 'charge'], t=t, iteration=iteration, species=species, select=select ) - # Calculate Lorentz factor for all particles - gamma = np.sqrt(1 + ux ** 2 + uy ** 2 + uz ** 2) - # Calculate particle velocities - vz = uz / gamma * const.c # Length to be seperated in bins len_z = np.max(z) - np.min(z) - vzq_sum, _ = np.histogram(z, bins=bins, weights=(vz * w * q)) - # Calculete the current in each bin - current = np.abs(vzq_sum * bins / (len_z * 1.e-6)) + if w.size > 0: + # Calculate Lorentz factor for all particles + gamma = np.sqrt(1 + ux ** 2 + uy ** 2 + uz ** 2) + # Calculate particle velocities + vz = uz / gamma * const.c + # Length to be seperated in bins + len_z = np.max(z) - np.min(z) + vzq_sum, _ = np.histogram(z, bins=bins, weights=(vz * w * q)) + # Calculate the current in each bin + current = np.abs(vzq_sum * bins / (len_z * 1.e-6)) + else: + current = np.zeros(bins) # Info object with central position of the bins info = FieldMetaInformation( {0: 'z'}, current.shape, grid_spacing=(len_z / bins, ), grid_unitSI=1, From 86aaaead5372dbf193cd7d92c122b8985be9cc53 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 16 Jan 2020 08:37:35 -0800 Subject: [PATCH 77/90] Sanitize tutorial notebook --- tutorials/5_Laser-plasma_tools.ipynb | 325 ++++----------------------- 1 file changed, 45 insertions(+), 280 deletions(-) diff --git a/tutorials/5_Laser-plasma_tools.ipynb b/tutorials/5_Laser-plasma_tools.ipynb index d7395e6d..c4821194 100644 --- a/tutorials/5_Laser-plasma_tools.ipynb +++ b/tutorials/5_Laser-plasma_tools.ipynb @@ -19,7 +19,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -48,7 +48,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -67,7 +67,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -83,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -99,70 +99,11 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "scrolled": false }, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "67d5ce646c1d4876bef42beb79f8bff7", - "version_major": 2, - "version_minor": 0 - }, - "text/html": [ - "

Failed to display Jupyter Widget of type HBox.

\n", - "

\n", - " If you're reading this message in the Jupyter Notebook or JupyterLab Notebook, it may mean\n", - " that the widgets JavaScript is still loading. If this message persists, it\n", - " likely means that the widgets JavaScript library is either not installed or\n", - " not enabled. See the Jupyter\n", - " Widgets Documentation for setup instructions.\n", - "

\n", - "

\n", - " If you're reading this message in another frontend (for example, a static\n", - " rendering on GitHub or NBViewer),\n", - " it may mean that your frontend doesn't currently support widgets.\n", - "

\n" - ], - "text/plain": [ - "HBox(children=(Button(description='-', layout=Layout(width='40px'), style=ButtonStyle()), Button(description='+', layout=Layout(width='40px'), style=ButtonStyle()), IntSlider(value=255, description='iteration', layout=Layout(width='500px'), max=407, min=255, step=7)))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "af69b5e03b634f54af65e3e2b67b6f86", - "version_major": 2, - "version_minor": 0 - }, - "text/html": [ - "

Failed to display Jupyter Widget of type HBox.

\n", - "

\n", - " If you're reading this message in the Jupyter Notebook or JupyterLab Notebook, it may mean\n", - " that the widgets JavaScript is still loading. If this message persists, it\n", - " likely means that the widgets JavaScript library is either not installed or\n", - " not enabled. See the Jupyter\n", - " Widgets Documentation for setup instructions.\n", - "

\n", - "

\n", - " If you're reading this message in another frontend (for example, a static\n", - " rendering on GitHub or NBViewer),\n", - " it may mean that your frontend doesn't currently support widgets.\n", - "

\n" - ], - "text/plain": [ - "HBox(children=(VBox(children=(Accordion(children=(VBox(children=(ToggleButtons(description='Field:', options=('E', 'rho'), style=ToggleButtonsStyle(button_width='initial'), value='E'), ToggleButtons(description='Coord:', options=('x', 'y', 'z'), style=ToggleButtonsStyle(button_width='initial'), value='x'), ToggleButtons(description='Slice normal:', options=('None', 'x', 'z'), style=ToggleButtonsStyle(button_width='initial'), value='None'), HBox(children=(HTML(value='Slicing:', layout=Layout(width='50px')), FloatSlider(value=0.0, layout=Layout(width='180px'), max=1.0, min=-1.0)))), layout=Layout(width='330px')), VBox(children=(HBox(children=(HTML(value='Figure:', layout=Layout(width='50px')), IntText(value=0, layout=Layout(width='50px')))), VBox(children=(HBox(children=(HTML(value='Colorbar:'), Select(index=164, layout=Layout(width='200px'), options=('Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Vega10', 'Vega10_r', 'Vega20', 'Vega20_r', 'Vega20b', 'Vega20b_r', 'Vega20c', 'Vega20c_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'seismic', 'seismic_r', 'spectral', 'spectral_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'viridis', 'viridis_r', 'winter', 'winter_r'), value='viridis'))), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-5.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=5.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='x 10^', layout=Layout(width='45px')), FloatText(value=9.0, layout=Layout(width='45px'))))))), layout=Layout(width='310px')), VBox(children=(HTML(value='Vertical axis:'), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-10.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=10.0, layout=Layout(width='60px'))))), layout=Layout(width='310px')))), VBox(children=(HTML(value='Horizontal axis:'), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-10.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=10.0, layout=Layout(width='60px'))))), layout=Layout(width='310px'))))), layout=Layout(width='330px'))), _titles={'0': 'Field type', '1': 'Plotting options'}), HBox(children=(ToggleButton(value=True, description='Always refresh'), Button(description='Refresh now!', style=ButtonStyle())))), layout=Layout(width='370px')), VBox(children=(Accordion(children=(VBox(children=(Dropdown(layout=Layout(width='250px'), options=('Hydrogen1+', 'electrons'), value='Hydrogen1+'), ToggleButtons(options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w'), style=ToggleButtonsStyle(button_width='initial'), value='x'), ToggleButtons(index=7, options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w', 'None'), style=ToggleButtonsStyle(button_width='initial'), value='None')), layout=Layout(width='310px')), VBox(children=(HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), Dropdown(description='Select ', options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w'), value='x'))), HBox(children=(HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-0.1, layout=Layout(width='90px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=0.1, layout=Layout(width='90px')))))), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), Dropdown(description='Select ', options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w'), value='x'))), HBox(children=(HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-0.1, layout=Layout(width='90px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=0.1, layout=Layout(width='90px')))))), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), Dropdown(description='Select ', options=('x', 'y', 'z', 'ux', 'uy', 'uz', 'w'), value='x'))), HBox(children=(HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-0.1, layout=Layout(width='90px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=0.1, layout=Layout(width='90px'))))))), layout=Layout(width='310px')), VBox(children=(HBox(children=(HBox(children=(HTML(value='Figure:', layout=Layout(width='50px')), IntText(value=1, layout=Layout(width='50px')))), HBox(children=(HTML(value='Bins:', layout=Layout(width='50px')), IntText(value=100, layout=Layout(width='60px')))))), VBox(children=(HBox(children=(HTML(value='Colorbar:'), Select(index=2, layout=Layout(width='200px'), options=('Accent', 'Accent_r', 'Blues', 'Blues_r', 'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r', 'CMRmap', 'CMRmap_r', 'Dark2', 'Dark2_r', 'GnBu', 'GnBu_r', 'Greens', 'Greens_r', 'Greys', 'Greys_r', 'OrRd', 'OrRd_r', 'Oranges', 'Oranges_r', 'PRGn', 'PRGn_r', 'Paired', 'Paired_r', 'Pastel1', 'Pastel1_r', 'Pastel2', 'Pastel2_r', 'PiYG', 'PiYG_r', 'PuBu', 'PuBuGn', 'PuBuGn_r', 'PuBu_r', 'PuOr', 'PuOr_r', 'PuRd', 'PuRd_r', 'Purples', 'Purples_r', 'RdBu', 'RdBu_r', 'RdGy', 'RdGy_r', 'RdPu', 'RdPu_r', 'RdYlBu', 'RdYlBu_r', 'RdYlGn', 'RdYlGn_r', 'Reds', 'Reds_r', 'Set1', 'Set1_r', 'Set2', 'Set2_r', 'Set3', 'Set3_r', 'Spectral', 'Spectral_r', 'Vega10', 'Vega10_r', 'Vega20', 'Vega20_r', 'Vega20b', 'Vega20b_r', 'Vega20c', 'Vega20c_r', 'Wistia', 'Wistia_r', 'YlGn', 'YlGnBu', 'YlGnBu_r', 'YlGn_r', 'YlOrBr', 'YlOrBr_r', 'YlOrRd', 'YlOrRd_r', 'afmhot', 'afmhot_r', 'autumn', 'autumn_r', 'binary', 'binary_r', 'bone', 'bone_r', 'brg', 'brg_r', 'bwr', 'bwr_r', 'cool', 'cool_r', 'coolwarm', 'coolwarm_r', 'copper', 'copper_r', 'cubehelix', 'cubehelix_r', 'flag', 'flag_r', 'gist_earth', 'gist_earth_r', 'gist_gray', 'gist_gray_r', 'gist_heat', 'gist_heat_r', 'gist_ncar', 'gist_ncar_r', 'gist_rainbow', 'gist_rainbow_r', 'gist_stern', 'gist_stern_r', 'gist_yarg', 'gist_yarg_r', 'gnuplot', 'gnuplot2', 'gnuplot2_r', 'gnuplot_r', 'gray', 'gray_r', 'hot', 'hot_r', 'hsv', 'hsv_r', 'inferno', 'inferno_r', 'jet', 'jet_r', 'magma', 'magma_r', 'nipy_spectral', 'nipy_spectral_r', 'ocean', 'ocean_r', 'pink', 'pink_r', 'plasma', 'plasma_r', 'prism', 'prism_r', 'rainbow', 'rainbow_r', 'seismic', 'seismic_r', 'spectral', 'spectral_r', 'spring', 'spring_r', 'summer', 'summer_r', 'tab10', 'tab10_r', 'tab20', 'tab20_r', 'tab20b', 'tab20b_r', 'tab20c', 'tab20c_r', 'terrain', 'terrain_r', 'viridis', 'viridis_r', 'winter', 'winter_r'), value='Blues'))), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-5.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=5.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='x 10^', layout=Layout(width='45px')), FloatText(value=9.0, layout=Layout(width='45px'))))))), layout=Layout(width='310px')), VBox(children=(HTML(value='Vertical axis:'), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-10.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=10.0, layout=Layout(width='60px'))))), layout=Layout(width='310px')))), VBox(children=(HTML(value='Horizontal axis:'), HBox(children=(Checkbox(value=False, indent=False, layout=Layout(width='20px')), HBox(children=(HTML(value='from', layout=Layout(width='30px')), FloatText(value=-10.0, layout=Layout(width='60px')))), HBox(children=(HTML(value='to', layout=Layout(width='20px')), FloatText(value=10.0, layout=Layout(width='60px'))))), layout=Layout(width='310px')))), ToggleButton(value=True, description=' Use field mesh')), layout=Layout(width='310px'))), _titles={'0': 'Particle quantities', '1': 'Particle selection', '2': 'Plotting options'}), HBox(children=(ToggleButton(value=True, description='Always refresh'), Button(description='Refresh now!', style=ButtonStyle())))), layout=Layout(width='370px'))))" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "ts_2d.slider()" ] @@ -203,7 +144,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -220,20 +161,9 @@ }, { "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "-0.0023057475697829941" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "ts_2d.get_charge(iteration=300, species='electrons')" ] @@ -247,56 +177,9 @@ }, { "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 29/29 [00:00<00:00, 360.08it/s]\n" - ] - }, - { - "data": { - "text/plain": [ - "[-0.0021049319607583184,\n", - " -0.0021403572862428925,\n", - " -0.0021556829061753998,\n", - " -0.0021817763542571313,\n", - " -0.0022063677618091746,\n", - " -0.0022291579223580171,\n", - " -0.0022504196064638497,\n", - " -0.0022704808597783558,\n", - " -0.0022887024138521007,\n", - " -0.0023057475697829941,\n", - " -0.0023212906851842003,\n", - " -0.002334958052371933,\n", - " -0.002347099346381503,\n", - " -0.0023565213462161264,\n", - " -0.0023659842015531576,\n", - " -0.0023739450163605012,\n", - " -0.0023792321990250011,\n", - " -0.0023844893408789076,\n", - " -0.002388244442203126,\n", - " -0.0023904975029976575,\n", - " -0.0023907678702930011,\n", - " -0.0023667352218180011,\n", - " -0.0023366944112242511,\n", - " -0.0023066536006305012,\n", - " -0.002277093443006251,\n", - " -0.0022470526324125011,\n", - " -0.0022170118218187511,\n", - " -0.0021869710112250012,\n", - " -0.0021569302006312508,\n", - " -0.0021268893900375013]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "ts_2d.iterate( ts_2d.get_charge, species='electrons' )" ] @@ -311,20 +194,9 @@ }, { "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(1.0665548693800455, 0.10151101005407513)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "ts_2d.get_mean_gamma(iteration=300, species='electrons', select={'uz' : [0.05, None]})" ] @@ -339,20 +211,9 @@ }, { "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(1.3080546184771431, 1.5751303670998404)" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "ts_2d.get_divergence(iteration=300, species='electrons')" ] @@ -368,20 +229,9 @@ }, { "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(1.1078612528297555e-07, 1.6064831448020442e-09)" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "ts_2d.get_emittance(iteration=300, species='electrons')" ] @@ -396,20 +246,9 @@ }, { "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "ts_2d.get_current(iteration=300, species='electrons', plot=True);" ] @@ -433,7 +272,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -450,20 +289,9 @@ }, { "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "ts_2d.get_spectrum(iteration=300, pol='y', plot=True);" ] @@ -485,20 +313,9 @@ }, { "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "ts_2d.get_spectrogram(iteration=300, pol='y', plot=True, cmap='YlGnBu_r');" ] @@ -513,20 +330,9 @@ }, { "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2354564459136067.0" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "ts_2d.get_main_frequency(iteration=300, pol='y')" ] @@ -541,20 +347,9 @@ }, { "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1.0542688340645183" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "ts_2d.get_a0(iteration=300, pol='y')" ] @@ -570,28 +365,9 @@ }, { "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/rlehe/miniconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py:785: OptimizeWarning: Covariance of the parameters could not be estimated\n", - " category=OptimizeWarning)\n" - ] - }, - { - "data": { - "text/plain": [ - "4.1474107457732672e-06" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "ts_2d.get_laser_waist(iteration=300, pol='y')" ] @@ -606,20 +382,9 @@ }, { "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2.9493466667473121e-06" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "ts_2d.get_ctau(iteration=300, pol='y')" ] @@ -642,7 +407,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.3" + "version": "3.7.4" }, "widgets": { "state": { From 5778170e84d550823973c354dfc5a0b6f20ab553 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 16 Jan 2020 08:39:39 -0800 Subject: [PATCH 78/90] Check that there is at least one species --- .../openpmd_timeseries/data_reader/params_reader.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpmd_viewer/openpmd_timeseries/data_reader/params_reader.py b/openpmd_viewer/openpmd_timeseries/data_reader/params_reader.py index 3f94f884..18f34a09 100644 --- a/openpmd_viewer/openpmd_timeseries/data_reader/params_reader.py +++ b/openpmd_viewer/openpmd_timeseries/data_reader/params_reader.py @@ -123,7 +123,9 @@ def read_openPMD_params(filename, extract_parameters=True): if ('particlesPath' in f.attrs): # Check for openPMD 1.1 files particle_path = f.attrs['particlesPath'].decode().strip('/') if particle_path in bpath.keys(): # Check for openPMD 1.0 files - particles_available = True + # Check that there is at least one species + if len(bpath[particle_path].keys()) > 0: + particles_available = True if particles_available: # Particles are present ; extract the species params['avail_species'] = [] From ebc8c896d2d5e354ad6635a43ad4c58fb390ef67 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 16 Jan 2020 08:40:40 -0800 Subject: [PATCH 79/90] File close() call missing --- openpmd_viewer/openpmd_timeseries/data_reader/params_reader.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpmd_viewer/openpmd_timeseries/data_reader/params_reader.py b/openpmd_viewer/openpmd_timeseries/data_reader/params_reader.py index 18f34a09..e982fccb 100644 --- a/openpmd_viewer/openpmd_timeseries/data_reader/params_reader.py +++ b/openpmd_viewer/openpmd_timeseries/data_reader/params_reader.py @@ -45,8 +45,9 @@ def read_openPMD_params(filename, extract_parameters=True): bpath = f[get_bpath(f)] t = bpath.attrs["time"] * bpath.attrs["timeUnitSI"] - # If the user did not request more parameters, exit now. + # If the user did not request more parameters, close file and exit if not extract_parameters: + f.close() return(t, None) # Otherwise, extract the rest of the parameters From 08050af511c53b5e8f8ac672efc86f869abe5594 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 16 Jan 2020 08:42:25 -0800 Subject: [PATCH 80/90] Prevent error in histogram of particle array containing single value --- openpmd_viewer/openpmd_timeseries/main.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/openpmd_viewer/openpmd_timeseries/main.py b/openpmd_viewer/openpmd_timeseries/main.py index ee1fccf2..c81b651b 100644 --- a/openpmd_viewer/openpmd_timeseries/main.py +++ b/openpmd_viewer/openpmd_timeseries/main.py @@ -295,6 +295,7 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, hist_range = [[None, None], [None, None]] for i_data in range(len(data_list)): data = data_list[i_data] + # Check if the user specified a value if (plot_range[i_data][0] is not None) and \ (plot_range[i_data][1] is not None): @@ -304,6 +305,15 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, hist_range[i_data] = [ data.min(), data.max() ] else: hist_range[i_data] = [ -1., 1. ] + + # Avoid error when the min and max are equal + if hist_range[i_data][0] == hist_range[i_data][1]: + if hist_range[i_data][0] == 0: + hist_range[i_data] = [ -1., 1. ] + else: + hist_range[i_data][0] *= 0.99 + hist_range[i_data][1] *= 1.01 + hist_bins = [ nbins for i_data in range(len(data_list)) ] # - Then, if required by the user, modify this values by # fitting them to the spatial grid From 0ba404789aa474e19726c8db2324b7b89bffbc39 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Wed, 29 Jan 2020 20:43:25 -0800 Subject: [PATCH 81/90] Correct a few bugs --- openpmd_viewer/addons/pic/lpa_diagnostics.py | 3 ++- openpmd_viewer/openpmd_timeseries/utilities.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/openpmd_viewer/addons/pic/lpa_diagnostics.py b/openpmd_viewer/addons/pic/lpa_diagnostics.py index af5b9212..852dd8ee 100644 --- a/openpmd_viewer/addons/pic/lpa_diagnostics.py +++ b/openpmd_viewer/addons/pic/lpa_diagnostics.py @@ -439,7 +439,7 @@ def get_current( self, t=None, iteration=None, species=None, select=None, return(current, info) def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', - theta=0, slicing=0, slicing_dir=None, + theta=0, slicing=None, slicing_dir=None, plot=False, plot_range=[[None, None], [None, None]], **kw ): """ @@ -510,6 +510,7 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', # Check if polarization has been entered if pol not in ['x', 'y']: raise ValueError('The `pol` argument is missing or erroneous.') + # Prevent slicing across z at this point # (z axis is needed for calculation of envelope) slicing_coord_z = None diff --git a/openpmd_viewer/openpmd_timeseries/utilities.py b/openpmd_viewer/openpmd_timeseries/utilities.py index ab8daa1e..17186cba 100644 --- a/openpmd_viewer/openpmd_timeseries/utilities.py +++ b/openpmd_viewer/openpmd_timeseries/utilities.py @@ -33,9 +33,9 @@ def sanitize_slicing(slicing_dir, slicing): # Check that the length are matching if len(slicing_dir) != len(slicing): raise ValueError( - 'The `slicing_dir` argument is erroneous: \nIt should have' + 'The `slicing` argument is erroneous: \nIt should have' 'the same number of elements as `slicing_dir`.') - return slicing_dir, slicing + return slicing_dir.copy(), slicing.copy() def list_h5_files(path_to_dir): From 51de1048e989e3281b7277616a4098cd6e541888 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 30 Jan 2020 09:02:57 -0800 Subject: [PATCH 82/90] Update CHANGELOG --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 870d4fc2..6ca932b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log / Release Log for openPMD-viewer -## 1.0 +## 1.0.0 This version introduces major changes and breaks backward compatibility. @@ -24,6 +24,10 @@ used to return the central slice along `y` while it now returns the full 3d fiel - A new function (`ts.iterate`) was introduced in order to quickly apply a given function to all iterations of a time series. See the docstring of `ts.iterate` for more information. +- The function `get_laser_envelope` does not support the argument `index` anymore +(which was effectively used in order to perform slicing). Instead, users should use +the argument `slicing_dir`. In addition, `get_laser_envelope` now supports the +argument `plot_range`. ## 0.9.0 From 62a9d5ae8b3549783987a11bdd0c8c3fbe15b6d1 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 30 Jan 2020 09:23:53 -0800 Subject: [PATCH 83/90] Update documentation. --- CHANGELOG.md | 3 +++ openpmd_viewer/addons/pic/lpa_diagnostics.py | 20 +++++++++++-------- .../openpmd_timeseries/utilities.py | 18 ++++++++++++++++- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ca932b3..fa450d64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ x, y, z = ts.get_particle(['x', 'y', 'z'], iteration=1000) compatibility for 3d field: ```get_field(field=field, coord=coord, iteration=iteration)``` used to return the central slice along `y` while it now returns the full 3d field. +- `openPMD-viewer` does not rely on Cython anymore. Instead, it uses `numba` +for functions that perform a substantial amount of computation. - A new function (`ts.iterate`) was introduced in order to quickly apply a given function to all iterations of a time series. See the docstring of `ts.iterate` for more information. @@ -28,6 +30,7 @@ given function to all iterations of a time series. See the docstring of (which was effectively used in order to perform slicing). Instead, users should use the argument `slicing_dir`. In addition, `get_laser_envelope` now supports the argument `plot_range`. +- The function `get_laser_waist` does not support the agument `slicing_dir` anymore. ## 0.9.0 diff --git a/openpmd_viewer/addons/pic/lpa_diagnostics.py b/openpmd_viewer/addons/pic/lpa_diagnostics.py index 5d998aee..25c1ec72 100644 --- a/openpmd_viewer/addons/pic/lpa_diagnostics.py +++ b/openpmd_viewer/addons/pic/lpa_diagnostics.py @@ -516,8 +516,11 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', if pol not in ['x', 'y']: raise ValueError('The `pol` argument is missing or erroneous.') - # Prevent slicing across z at this point + # Prevent slicing across z, when extracting the raw electric field # (z axis is needed for calculation of envelope) + # but record whether the user asked for slicing across z, + # and whether a corresponding `slicing` coordinate along z was given, + # so as to perform this slicing later in this function. slicing_coord_z = None if slicing_dir is not None: slicing_dir, slicing = sanitize_slicing(slicing_dir, slicing) @@ -531,7 +534,7 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', slicing=slicing, slicing_dir=slicing_dir ) e_complx = hilbert(field, axis=-1) envelope = np.abs(e_complx) - # If the user asked for slicing along z, add it at this point + # If the user asked for slicing along z, do it now if slicing_coord_z is not None: inverted_axes_dict = {info.axes[key]: key for key in info.axes.keys()} slicing_index = inverted_axes_dict['z'] @@ -773,10 +776,13 @@ def get_ctau( self, t=None, iteration=None, pol=None, method='fit' ): raise ValueError('Unknown method: {:s}'.format(method)) def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, - slicing=None, slicing_dir=None, method='fit' ): + method='fit' ): """ Calculate the waist of a (gaussian) laser pulse. ( sqrt(2) * sigma_r) + In 3D, this function takes a slice across `y`, and thus computes the + waist in the `x-z` plane. + Parameters ---------- t : float (in seconds), optional @@ -814,9 +820,7 @@ def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, # Get the field envelope (as 2D array) field, info = self.get_laser_envelope(t=t, iteration=iteration, - pol=pol, index='all', - slicing_dir=slicing_dir, - theta=theta) + pol=pol, slicing_dir=slicing_dir, theta=theta) assert field.ndim == 2 # Find the indices of the maximum field, and # pick the corresponding transverse slice @@ -891,7 +895,6 @@ def get_spectrogram( self, t=None, iteration=None, pol=None, # Get the field envelope env, _ = self.get_laser_envelope(t=t, iteration=iteration, pol=pol, slicing_dir=slicing_dir) - print(env.shape) # Get the field E, info = self.get_field( t=t, iteration=iteration, field='E', coord=pol, slicing_dir=slicing_dir) @@ -945,7 +948,8 @@ def get_spectrogram( self, t=None, iteration=None, pol=None, def _get_slicing_for_longitudinal_lineout(self): """ - TODO + Return the `slicing_dir` argument which results in a 1D slice + along `z`, for the current geometry. """ geometry = self.fields_metadata['E']['geometry'] if geometry == "2dcartesian": diff --git a/openpmd_viewer/openpmd_timeseries/utilities.py b/openpmd_viewer/openpmd_timeseries/utilities.py index 17186cba..3180a9e4 100644 --- a/openpmd_viewer/openpmd_timeseries/utilities.py +++ b/openpmd_viewer/openpmd_timeseries/utilities.py @@ -17,7 +17,17 @@ def sanitize_slicing(slicing_dir, slicing): """ - TODO + Return standardized format for `slicing_dir` and `slicing`: + - either `slicing_dir` and `slicing` are both `None` (no slicing) + - or `slicing_dir` and `slicing` are both lists, + with the same number of elements + + Parameters + ---------- + slicing : float, or list of float, or None + + slicing_dir : str, or list of str, or None + Direction(s) along which to slice the data """ # Skip None and empty lists if slicing_dir is None or slicing_dir == []: @@ -35,6 +45,12 @@ def sanitize_slicing(slicing_dir, slicing): raise ValueError( 'The `slicing` argument is erroneous: \nIt should have' 'the same number of elements as `slicing_dir`.') + + # Return a copy. This is because the rest of the `openPMD-viewer` code + # sometimes modifies the objects returned by `sanitize_slicing`. + # Using a copy avoids directly modifying objects that the user may pass + # to this function (and live outside of openPMD-viewer, e.g. directly in + # a user's notebook) return slicing_dir.copy(), slicing.copy() From f4c96f7ceacc34c73c369ed14f6b6466d92b537c Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 30 Jan 2020 09:48:09 -0800 Subject: [PATCH 84/90] Fix Python 2 bug --- openpmd_viewer/openpmd_timeseries/utilities.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpmd_viewer/openpmd_timeseries/utilities.py b/openpmd_viewer/openpmd_timeseries/utilities.py index 3180a9e4..f98bea2d 100644 --- a/openpmd_viewer/openpmd_timeseries/utilities.py +++ b/openpmd_viewer/openpmd_timeseries/utilities.py @@ -9,6 +9,7 @@ """ import os +import copy import math import numpy as np import h5py @@ -51,7 +52,7 @@ def sanitize_slicing(slicing_dir, slicing): # Using a copy avoids directly modifying objects that the user may pass # to this function (and live outside of openPMD-viewer, e.g. directly in # a user's notebook) - return slicing_dir.copy(), slicing.copy() + return copy.copy(slicing_dir), copy.copy(slicing) def list_h5_files(path_to_dir): From 561bed349f5a5f73d662edaf16b0f2db93bf3b81 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 30 Jan 2020 20:48:35 -0800 Subject: [PATCH 85/90] Replace slicing_dir by slice_across --- openpmd_viewer/addons/pic/lpa_diagnostics.py | 48 +++++++++---------- .../data_reader/field_reader.py | 30 ++++++------ .../openpmd_timeseries/interactive.py | 26 +++++----- openpmd_viewer/openpmd_timeseries/main.py | 26 +++++----- openpmd_viewer/openpmd_timeseries/plotter.py | 6 +-- .../openpmd_timeseries/utilities.py | 24 +++++----- tutorials/2_Specific-field-geometries.ipynb | 18 +++---- 7 files changed, 89 insertions(+), 89 deletions(-) diff --git a/openpmd_viewer/addons/pic/lpa_diagnostics.py b/openpmd_viewer/addons/pic/lpa_diagnostics.py index 25c1ec72..5604a6fb 100644 --- a/openpmd_viewer/addons/pic/lpa_diagnostics.py +++ b/openpmd_viewer/addons/pic/lpa_diagnostics.py @@ -444,7 +444,7 @@ def get_current( self, t=None, iteration=None, species=None, select=None, return(current, info) def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', - theta=0, slicing=None, slicing_dir=None, + theta=0, slicing=None, slice_across=None, plot=False, plot_range=[[None, None], [None, None]], **kw ): """ @@ -476,13 +476,13 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', slicing : float or list of float, optional Number(s) between -1 and 1 that indicate where to slice the data, - along the directions in `slicing_dir` + along the directions in `slice_across` -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box Default is 0. - slicing_dir : str or list of str, optional + slice_across : str or list of str, optional Direction(s) along which to slice the data + In cartesian geometry, elements can be: - 1d: 'z' @@ -490,7 +490,7 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', - 3d: 'x' and/or 'y' and/or 'z' + In cylindrical geometry, elements can be 'r' and/or 'z' Returned array is reduced by 1 dimension per slicing. - If slicing_dir is None, the full grid is returned. + If slice_across is None, the full grid is returned. Default is None. plot : bool, optional @@ -522,16 +522,16 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', # and whether a corresponding `slicing` coordinate along z was given, # so as to perform this slicing later in this function. slicing_coord_z = None - if slicing_dir is not None: - slicing_dir, slicing = sanitize_slicing(slicing_dir, slicing) - if 'z' in slicing_dir: - index_slicing_z = slicing_dir.index('z') - slicing_dir.pop(index_slicing_z) + if slice_across is not None: + slice_across, slicing = sanitize_slicing(slice_across, slicing) + if 'z' in slice_across: + index_slicing_z = slice_across.index('z') + slice_across.pop(index_slicing_z) slicing_coord_z = slicing.pop(index_slicing_z) # Get field data, and perform Hilbert transform field, info = self.get_field( t=t, iteration=iteration, field='E', coord=pol, theta=theta, m=m, - slicing=slicing, slicing_dir=slicing_dir ) + slicing=slicing, slice_across=slice_across ) e_complx = hilbert(field, axis=-1) envelope = np.abs(e_complx) # If the user asked for slicing along z, do it now @@ -558,7 +558,7 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', self.plotter.show_field_1d(envelope, info, field_label, self._current_i, plot_range=plot_range, **kw) elif envelope.ndim == 2: - self.plotter.show_field_2d(envelope, info, slicing_dir, m, + self.plotter.show_field_2d(envelope, info, slice_across, m, field_label, geometry, self._current_i, plot_range=plot_range, **kw) # Return the result @@ -659,11 +659,11 @@ def get_spectrum( self, t=None, iteration=None, pol=None, if pol not in ['x', 'y']: raise ValueError('The `pol` argument is missing or erroneous.') # Get a lineout along the 'z' axis, - slicing_dir = self._get_slicing_for_longitudinal_lineout() + slice_across = self._get_slicing_for_longitudinal_lineout() # Get field data field1d, info = self.get_field( t=t, iteration=iteration, field='E', - coord=pol, m=m, slicing_dir=slicing_dir ) + coord=pol, m=m, slice_across=slice_across ) # FFT of 1d data dt = (info.z[1] - info.z[0]) / const.c # Integration step for the FFT fft_field = np.fft.fft(field1d) * dt @@ -711,11 +711,11 @@ def get_a0( self, t=None, iteration=None, pol=None ): Float with normalized vector potential a0 """ # Get a lineout along the 'z' axis, - slicing_dir = self._get_slicing_for_longitudinal_lineout() + slice_across = self._get_slicing_for_longitudinal_lineout() # Get the peak field from field envelope Emax = np.amax(self.get_laser_envelope(t=t, iteration=iteration, - pol=pol, slicing_dir=slicing_dir)[0]) + pol=pol, slice_across=slice_across)[0]) # Get mean frequency omega = self.get_main_frequency(t=t, iteration=iteration, pol=pol) # Calculate a0 @@ -752,11 +752,11 @@ def get_ctau( self, t=None, iteration=None, pol=None, method='fit' ): Float with ctau in meters """ # Get a lineout along the 'z' axis, - slicing_dir = self._get_slicing_for_longitudinal_lineout() + slice_across = self._get_slicing_for_longitudinal_lineout() # Get the field envelope E, info = self.get_laser_envelope(t=t, iteration=iteration, - pol=pol, slicing_dir=slicing_dir) + pol=pol, slice_across=slice_across) # Calculate ctau with RMS value ctau = np.sqrt(2) * w_std(info.z, E) if method == 'rms': @@ -814,13 +814,13 @@ def get_laser_waist( self, t=None, iteration=None, pol=None, theta=0, # In 3D, slice across 'y' by default geometry = self.fields_metadata['E']['geometry'] if geometry == '3dcartesian': - slicing_dir = 'y' + slice_across = 'y' else: - slicing_dir = None + slice_across = None # Get the field envelope (as 2D array) field, info = self.get_laser_envelope(t=t, iteration=iteration, - pol=pol, slicing_dir=slicing_dir, theta=theta) + pol=pol, slice_across=slice_across, theta=theta) assert field.ndim == 2 # Find the indices of the maximum field, and # pick the corresponding transverse slice @@ -890,14 +890,14 @@ def get_spectrogram( self, t=None, iteration=None, pol=None, (see the corresponding docstring) """ # Get a lineout along the 'z' axis - slicing_dir = self._get_slicing_for_longitudinal_lineout() + slice_across = self._get_slicing_for_longitudinal_lineout() # Get the field envelope env, _ = self.get_laser_envelope(t=t, iteration=iteration, - pol=pol, slicing_dir=slicing_dir) + pol=pol, slice_across=slice_across) # Get the field E, info = self.get_field( t=t, iteration=iteration, field='E', - coord=pol, slicing_dir=slicing_dir) + coord=pol, slice_across=slice_across) Nz = len(E) # Get time domain of the data tmin = info.zmin / const.c @@ -948,7 +948,7 @@ def get_spectrogram( self, t=None, iteration=None, pol=None, def _get_slicing_for_longitudinal_lineout(self): """ - Return the `slicing_dir` argument which results in a 1D slice + Return the `slice_across` argument which results in a 1D slice along `z`, for the current geometry. """ geometry = self.fields_metadata['E']['geometry'] diff --git a/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 39699f70..e56a08be 100644 --- a/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -15,7 +15,7 @@ from ..utilities import construct_3d_from_circ def read_field_cartesian( filename, field_path, axis_labels, - slicing, slicing_dir ): + slicing, slice_across ): """ Extract a given field from an HDF5 file in the openPMD format, when the geometry is cartesian (1d, 2d or 3d). @@ -34,12 +34,12 @@ def read_field_cartesian( filename, field_path, axis_labels, slicing : list of float or None Number(s) between -1 and 1 that indicate where to slice the data, - along the directions in `slicing_dir` + along the directions in `slice_across` -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box - slicing_dir : list of str or None + slice_across : list of str or None Direction(s) along which to slice the data Elements can be: - 1d: 'z' @@ -65,12 +65,12 @@ def read_field_cartesian( filename, field_path, axis_labels, global_offset = list( group.attrs['gridGlobalOffset'] ) # Slice selection - if slicing_dir is not None: + if slice_across is not None: # Get the integer that correspond to the slicing direction list_slicing_index = [] list_i_cell = [] - for count, slicing_dir_item in enumerate(slicing_dir): - slicing_index = axis_labels.index(slicing_dir_item) + for count, slice_across_item in enumerate(slice_across): + slicing_index = axis_labels.index(slice_across_item) list_slicing_index.append(slicing_index) # Number of cells along the slicing direction n_cells = shape[ slicing_index ] @@ -108,7 +108,7 @@ def read_field_cartesian( filename, field_path, axis_labels, return( F, info ) -def read_field_circ( filename, field_path, slicing, slicing_dir, m=0, +def read_field_circ( filename, field_path, slicing, slice_across, m=0, theta=0. ): """ Extract a given field from an HDF5 file in the openPMD format, @@ -134,12 +134,12 @@ def read_field_circ( filename, field_path, slicing, slicing_dir, m=0, slicing : list of float or None Number(s) between -1 and 1 that indicate where to slice the data, - along the directions in `slicing_dir` + along the directions in `slice_across` -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box - slicing_dir : list of str or None + slice_across : list of str or None Direction(s) along which to slice the data Elements can be 'r' and/or 'z' Returned array is reduced by 1 dimension per slicing. @@ -223,12 +223,12 @@ def read_field_circ( filename, field_path, slicing, slicing_dir, m=0, F_total[:Nr, :] = (-1) ** m * F[::-1, :] # Perform slicing if needed - if slicing_dir is not None: + if slice_across is not None: # Slice field and clear metadata inverted_axes_dict = {info.axes[key]: key for key in info.axes.keys()} - for count, slicing_dir_item in enumerate(slicing_dir): - slicing_index = inverted_axes_dict[slicing_dir_item] - coord_array = getattr( info, slicing_dir_item ) + for count, slice_across_item in enumerate(slice_across): + slicing_index = inverted_axes_dict[slice_across_item] + coord_array = getattr( info, slice_across_item ) # Number of cells along the slicing direction n_cells = len(coord_array) # Index of the slice (prevent stepping out of the array) @@ -238,8 +238,8 @@ def read_field_circ( filename, field_path, slicing, slicing_dir, m=0, F_total = np.take( F_total, [i_cell], axis=slicing_index ) F_total = np.squeeze(F_total) # Remove the sliced labels from the FieldMetaInformation - for slicing_dir_item in slicing_dir: - info._remove_axis(slicing_dir_item) + for slice_across_item in slice_across: + info._remove_axis(slice_across_item) # Close the file dfile.close() diff --git a/openpmd_viewer/openpmd_timeseries/interactive.py b/openpmd_viewer/openpmd_timeseries/interactive.py index 73dcf6d7..33a529b5 100644 --- a/openpmd_viewer/openpmd_timeseries/interactive.py +++ b/openpmd_viewer/openpmd_timeseries/interactive.py @@ -112,17 +112,17 @@ def refresh_field(change=None, force=False): fld_vrange_button.get_range() ] # Handle slicing direction - if slicing_dir_button.value == 'None': - slicing_dir = None + if slice_across_button.value == 'None': + slice_across = None else: - slicing_dir = slicing_dir_button.value + slice_across = slice_across_button.value # Call the method get_field self.get_field( iteration=self.current_iteration, plot=True, field=fieldtype_button.value, coord=coord_button.value, m=convert_to_int(mode_button.value), slicing=slicing_button.value, theta=theta_button.value, - slicing_dir=slicing_dir, + slice_across=slice_across, plot_range=plot_range, **kw_fld ) def refresh_ptcl(change=None, force=False): @@ -218,13 +218,13 @@ def refresh_field_type(change): theta_button.disabled = True # Activate the right slicing options if self.fields_metadata[new_field]['geometry'] == '3dcartesian': - slicing_dir_button.options = \ + slice_across_button.options = \ self.fields_metadata[new_field]['axis_labels'] - slicing_dir_button.value = 'y' + slice_across_button.value = 'y' else: - slicing_dir_button.options = ['None'] + \ + slice_across_button.options = ['None'] + \ self.fields_metadata[new_field]['axis_labels'] - slicing_dir_button.value = 'None' + slice_across_button.value = 'None' # Put back the previous value of the refreshing button fld_refresh_toggle.value = saved_refresh_value @@ -356,12 +356,12 @@ def step_bw(b): # Slicing buttons axis_labels = self.fields_metadata[field]['axis_labels'] if self.fields_metadata[field]['geometry'] == '3dcartesian': - slicing_dir_button = create_toggle_buttons( value='y', + slice_across_button = create_toggle_buttons( value='y', options=axis_labels ) else: - slicing_dir_button = create_toggle_buttons( value='None', + slice_across_button = create_toggle_buttons( value='None', options=['None'] + axis_labels ) - slicing_dir_button.observe( refresh_field, 'value', 'change' ) + slice_across_button.observe( refresh_field, 'value', 'change' ) slicing_button = widgets.FloatSlider( min=-1., max=1., value=0.) set_widget_dimensions( slicing_button, width=180 ) slicing_button.observe( refresh_field, 'value', 'change') @@ -397,8 +397,8 @@ def step_bw(b): # Slicing container slices_widget_list = [ add_description("Slice normal:", - slicing_dir_button, width=100), - add_description("Slicing:", slicing_button) ] + slice_across_button, width=100), + add_description("Slicing position:", slicing_button) ] if "thetaMode" in self.avail_geom: # Add widgets specific to azimuthal modes slices_widget_list += [ mode_button, diff --git a/openpmd_viewer/openpmd_timeseries/main.py b/openpmd_viewer/openpmd_timeseries/main.py index e4461458..f8a0d7f9 100644 --- a/openpmd_viewer/openpmd_timeseries/main.py +++ b/openpmd_viewer/openpmd_timeseries/main.py @@ -355,7 +355,7 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, return(data_list) def get_field(self, field=None, coord=None, t=None, iteration=None, - m='all', theta=0., slicing=None, slicing_dir=None, + m='all', theta=0., slicing=None, slice_across=None, plot=False, plot_range=[[None, None], [None, None]], **kw): """ @@ -395,14 +395,14 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, slicing : float or list of float, optional Number(s) between -1 and 1 that indicate where to slice the data, - along the directions in `slicing_dir` + along the directions in `slice_across` -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box Default: None, which results in slicing at 0 in all direction - of `slicing_dir`. + of `slice_across`. - slicing_dir : str or list of str, optional + slice_across : str or list of str, optional Direction(s) along which to slice the data + In cartesian geometry, elements can be: - 1d: 'z' @@ -442,15 +442,15 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, "The available fields are: \n - %s\nPlease set the `field` " "argument accordingly." % field_list) # Check slicing - slicing_dir, slicing = sanitize_slicing(slicing_dir, slicing) - if slicing_dir is not None: + slice_across, slicing = sanitize_slicing(slice_across, slicing) + if slice_across is not None: # Check that the elements are valid axis_labels = self.fields_metadata[field]['axis_labels'] - for axis in slicing_dir: + for axis in slice_across: if axis not in axis_labels: axes_list = '\n - '.join(axis_labels) raise OpenPMDException( - 'The `slicing_dir` argument is erroneous: contains %s\n' + 'The `slice_across` argument is erroneous: contains %s\n' 'The available axes are: \n - %s' % (axis, axes_list) ) # Check the coordinate (for vector fields) @@ -494,21 +494,21 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, # - For cartesian if geometry in ["1dcartesian", "2dcartesian", "3dcartesian"]: F, info = read_field_cartesian( - filename, field_path, axis_labels, slicing, slicing_dir) + filename, field_path, axis_labels, slicing, slice_across) # - For thetaMode elif geometry == "thetaMode": if (coord in ['x', 'y']) and \ (self.fields_metadata[field]['type'] == 'vector'): # For Cartesian components, combine r and t components Fr, info = read_field_circ(filename, field + '/r', slicing, - slicing_dir, m, theta) + slice_across, m, theta) Ft, info = read_field_circ(filename, field + '/t', slicing, - slicing_dir, m, theta) + slice_across, m, theta) F = combine_cylindrical_components(Fr, Ft, theta, coord, info) else: # For cylindrical or scalar components, no special treatment F, info = read_field_circ(filename, field_path, slicing, - slicing_dir, m, theta) + slice_across, m, theta) # Plot the resulting field # Deactivate plotting when there is no slice selection @@ -517,7 +517,7 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, self.plotter.show_field_1d(F, info, field_label, self._current_i, plot_range=plot_range, **kw) elif F.ndim == 2: - self.plotter.show_field_2d(F, info, slicing_dir, m, + self.plotter.show_field_2d(F, info, slice_across, m, field_label, geometry, self._current_i, plot_range=plot_range, **kw) else: diff --git a/openpmd_viewer/openpmd_timeseries/plotter.py b/openpmd_viewer/openpmd_timeseries/plotter.py index f2342c4a..89d7a30f 100644 --- a/openpmd_viewer/openpmd_timeseries/plotter.py +++ b/openpmd_viewer/openpmd_timeseries/plotter.py @@ -318,7 +318,7 @@ def show_field_1d( self, F, info, field_label, current_i, plot_range, ax.get_xaxis().set_major_formatter( tick_formatter ) ax.get_yaxis().set_major_formatter( tick_formatter ) - def show_field_2d(self, F, info, slicing_dir, m, field_label, geometry, + def show_field_2d(self, F, info, slice_across, m, field_label, geometry, current_i, plot_range, **kw): """ Plot the given field in 2D @@ -331,9 +331,9 @@ def show_field_2d(self, F, info, slicing_dir, m, field_label, geometry, info: a FieldMetaInformation object Contains the information about the plotted field - slicing_dir : str, optional + slice_across : str, optional Only used for 3dcartesian geometry - The direction along which the data is sliced + The direction across which the data is sliced m: int Only used for thetaMode geometry diff --git a/openpmd_viewer/openpmd_timeseries/utilities.py b/openpmd_viewer/openpmd_timeseries/utilities.py index f98bea2d..dc024628 100644 --- a/openpmd_viewer/openpmd_timeseries/utilities.py +++ b/openpmd_viewer/openpmd_timeseries/utilities.py @@ -16,43 +16,43 @@ from .data_reader.particle_reader import read_species_data from .numba_wrapper import jit -def sanitize_slicing(slicing_dir, slicing): +def sanitize_slicing(slice_across, slicing): """ - Return standardized format for `slicing_dir` and `slicing`: - - either `slicing_dir` and `slicing` are both `None` (no slicing) - - or `slicing_dir` and `slicing` are both lists, + Return standardized format for `slice_across` and `slicing`: + - either `slice_across` and `slicing` are both `None` (no slicing) + - or `slice_across` and `slicing` are both lists, with the same number of elements Parameters ---------- slicing : float, or list of float, or None - slicing_dir : str, or list of str, or None + slice_across : str, or list of str, or None Direction(s) along which to slice the data """ # Skip None and empty lists - if slicing_dir is None or slicing_dir == []: + if slice_across is None or slice_across == []: return None, None # Convert to lists - if not isinstance(slicing_dir, list): - slicing_dir = [slicing_dir] + if not isinstance(slice_across, list): + slice_across = [slice_across] if slicing is None: - slicing = [0]*len(slicing_dir) + slicing = [0]*len(slice_across) if not isinstance(slicing, list): slicing = [slicing] # Check that the length are matching - if len(slicing_dir) != len(slicing): + if len(slice_across) != len(slicing): raise ValueError( 'The `slicing` argument is erroneous: \nIt should have' - 'the same number of elements as `slicing_dir`.') + 'the same number of elements as `slice_across`.') # Return a copy. This is because the rest of the `openPMD-viewer` code # sometimes modifies the objects returned by `sanitize_slicing`. # Using a copy avoids directly modifying objects that the user may pass # to this function (and live outside of openPMD-viewer, e.g. directly in # a user's notebook) - return copy.copy(slicing_dir), copy.copy(slicing) + return copy.copy(slice_across), copy.copy(slicing) def list_h5_files(path_to_dir): diff --git a/tutorials/2_Specific-field-geometries.ipynb b/tutorials/2_Specific-field-geometries.ipynb index a16ab2bd..49e66452 100644 --- a/tutorials/2_Specific-field-geometries.ipynb +++ b/tutorials/2_Specific-field-geometries.ipynb @@ -104,7 +104,7 @@ "## 3D Cartesian geometry\n", "\n", "For 3D Cartesian geometry, the `get_field` method has additional arguments, in order to select a 2D slice into the 3D volume:\n", - "- `slicing_dir` allows to choose the axis across which the slice is taken. See the examples below:" + "- `slice_across` allows to choose the axis across which the slice is taken. See the examples below:" ] }, { @@ -115,7 +115,7 @@ "source": [ "# Slice across y (i.e. in a plane parallel to x-z)\n", "Ez1, info_Ez1 = ts_3d.get_field( field='E', coord='z', iteration=500, \n", - " slicing_dir='y', plot=True )" + " slice_across='y', plot=True )" ] }, { @@ -126,7 +126,7 @@ "source": [ "# Slice across z (i.e. in a plane parallel to x-y)\n", "Ez2, info_Ez2 = ts_3d.get_field( field='E', coord='z', iteration=500,\n", - " slicing_dir='z', plot=True )" + " slice_across='z', plot=True )" ] }, { @@ -137,14 +137,14 @@ "source": [ "# Slice across x and y (i.e. along a line parallel to the z axis)\n", "Ez2, info_Ez2 = ts_3d.get_field( field='E', coord='z', iteration=500,\n", - " slicing_dir=['x','y'], plot=True )" + " slice_across=['x','y'], plot=True )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "- For one given slicing direction, `slicing` allows to select which slice to take: `slicing` is a number between -1 and 1, where -1 indicates to take the slice at the lower bound of the slicing range (e.g. $z_min$ if `slicing_dir` is `z`) and 1 indicates to take the slice at the upper bound of the slicing range (e.g. $z_{max}$ if `slicing_dir` is `z`). For example:" + "- For one given slicing direction, `slicing` allows to select which slice to take: `slicing` is a number between -1 and 1, where -1 indicates to take the slice at the lower bound of the slicing range (e.g. $z_min$ if `slice_across` is `z`) and 1 indicates to take the slice at the upper bound of the slicing range (e.g. $z_{max}$ if `slice_across` is `z`). For example:" ] }, { @@ -155,7 +155,7 @@ "source": [ "# Slice across z, very close to zmin.\n", "Ez2, info_Ez2 = ts_3d.get_field( field='E', coord='z', iteration=500, \n", - " slicing_dir='z', slicing=-0.9, plot=True )" + " slice_across='z', slicing=-0.9, plot=True )" ] }, { @@ -255,7 +255,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "- Finally, in cylindrical geometry, fields can also be sliced, by using the `r` and `z` direction. (Keep in mind that `slicing_dir` is the direction **orthogonal** to the slice.)" + "- Finally, in cylindrical geometry, fields can also be sliced, by using the `r` and `z` direction. (Keep in mind that `slice_across` is the direction **orthogonal** to the slice.)" ] }, { @@ -264,7 +264,7 @@ "metadata": {}, "outputs": [], "source": [ - "Er_slice, info = ts_circ.get_field( field='E', coord='r', iteration=500, plot=True, slicing_dir='r' )" + "Er_slice, info = ts_circ.get_field( field='E', coord='r', iteration=500, plot=True, slice_across='r' )" ] }, { @@ -273,7 +273,7 @@ "metadata": {}, "outputs": [], "source": [ - "Er_slice, info = ts_circ.get_field( field='E', coord='r', iteration=500, plot=True, slicing_dir='z' )" + "Er_slice, info = ts_circ.get_field( field='E', coord='r', iteration=500, plot=True, slice_across='z' )" ] } ], From 15f8059a14c04f967b4763bd124aaf20c1115fb2 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 30 Jan 2020 20:51:09 -0800 Subject: [PATCH 86/90] Start replacing `slicing` with `slice_relative_position` --- tutorials/2_Specific-field-geometries.ipynb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tutorials/2_Specific-field-geometries.ipynb b/tutorials/2_Specific-field-geometries.ipynb index 49e66452..355e84b2 100644 --- a/tutorials/2_Specific-field-geometries.ipynb +++ b/tutorials/2_Specific-field-geometries.ipynb @@ -144,7 +144,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "- For one given slicing direction, `slicing` allows to select which slice to take: `slicing` is a number between -1 and 1, where -1 indicates to take the slice at the lower bound of the slicing range (e.g. $z_min$ if `slice_across` is `z`) and 1 indicates to take the slice at the upper bound of the slicing range (e.g. $z_{max}$ if `slice_across` is `z`). For example:" + "- For one given slicing direction, `slice_relative_position` allows to select which slice to take: `slice_relative_position` is a number between -1 and 1, where -1 indicates to take the slice at the lower bound of the slicing range (e.g. $z_{min}$ if `slice_across` is `z`) and 1 indicates to take the slice at the upper bound of the slicing range (e.g. $z_{max}$ if `slice_across` is `z`). For example:" ] }, { @@ -155,14 +155,14 @@ "source": [ "# Slice across z, very close to zmin.\n", "Ez2, info_Ez2 = ts_3d.get_field( field='E', coord='z', iteration=500, \n", - " slice_across='z', slicing=-0.9, plot=True )" + " slice_across='z', slice_relative_position=-0.9, plot=True )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "When passing `slicing=None`, `get_field` returns a full 3D Cartesian array. This can be useful for further analysis by hand, with `numpy` (e.g. calculating the total energy in the field)." + "When passing `slice_across=None`, `get_field` returns a full 3D Cartesian array. This can be useful for further analysis by hand, with `numpy` (e.g. calculating the total energy in the field)." ] }, { @@ -172,7 +172,7 @@ "outputs": [], "source": [ "# Get the full 3D Cartesian array\n", - "Ez_3d, info_Ez_3d = ts_3d.get_field( field='E', coord='z', iteration=500, slicing=None )\n", + "Ez_3d, info_Ez_3d = ts_3d.get_field( field='E', coord='z', iteration=500, slice_across=None )\n", "print( Ez_3d.ndim )" ] }, From e6fcb71a2c10080e25bb3adc2a619df2baf2bdd5 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 30 Jan 2020 21:11:24 -0800 Subject: [PATCH 87/90] Replace `slicing` by `slice_relative_position` --- openpmd_viewer/addons/pic/lpa_diagnostics.py | 32 +++++++------- .../data_reader/field_reader.py | 36 ++++++++-------- .../openpmd_timeseries/interactive.py | 3 +- openpmd_viewer/openpmd_timeseries/main.py | 43 ++++++++++--------- .../openpmd_timeseries/utilities.py | 24 +++++------ 5 files changed, 71 insertions(+), 67 deletions(-) diff --git a/openpmd_viewer/addons/pic/lpa_diagnostics.py b/openpmd_viewer/addons/pic/lpa_diagnostics.py index 5604a6fb..a45988d0 100644 --- a/openpmd_viewer/addons/pic/lpa_diagnostics.py +++ b/openpmd_viewer/addons/pic/lpa_diagnostics.py @@ -444,8 +444,8 @@ def get_current( self, t=None, iteration=None, species=None, select=None, return(current, info) def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', - theta=0, slicing=None, slice_across=None, - plot=False, + theta=0, slice_across=None, + slice_relative_position=None, plot=False, plot_range=[[None, None], [None, None]], **kw ): """ Calculate a laser field by filtering out high frequencies. Can either @@ -474,14 +474,6 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', Only used for thetaMode geometry The angle of the plane of observation, with respect to the x axis - slicing : float or list of float, optional - Number(s) between -1 and 1 that indicate where to slice the data, - along the directions in `slice_across` - -1 : lower edge of the simulation box - 0 : middle of the simulation box - 1 : upper edge of the simulation box - Default is 0. - slice_across : str or list of str, optional Direction(s) along which to slice the data + In cartesian geometry, elements can be: @@ -493,6 +485,14 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', If slice_across is None, the full grid is returned. Default is None. + slice_relative_position : float or list of float, optional + Number(s) between -1 and 1 that indicate where to slice the data, + along the directions in `slice_across` + -1 : lower edge of the simulation box + 0 : middle of the simulation box + 1 : upper edge of the simulation box + Default is 0. + plot : bool, optional Whether to plot the requested quantity @@ -519,19 +519,21 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', # Prevent slicing across z, when extracting the raw electric field # (z axis is needed for calculation of envelope) # but record whether the user asked for slicing across z, - # and whether a corresponding `slicing` coordinate along z was given, - # so as to perform this slicing later in this function. + # and whether a corresponding `slice_relative_position` coordinate + # along z was given, so as to perform this slicing later in this function. slicing_coord_z = None if slice_across is not None: - slice_across, slicing = sanitize_slicing(slice_across, slicing) + slice_across, slice_relative_position = \ + sanitize_slicing(slice_across, slice_relative_position) if 'z' in slice_across: index_slicing_z = slice_across.index('z') slice_across.pop(index_slicing_z) - slicing_coord_z = slicing.pop(index_slicing_z) + slicing_coord_z = slice_relative_position.pop(index_slicing_z) # Get field data, and perform Hilbert transform field, info = self.get_field( t=t, iteration=iteration, field='E', coord=pol, theta=theta, m=m, - slicing=slicing, slice_across=slice_across ) + slice_across=slice_across, + slice_relative_position=slice_relative_position ) e_complx = hilbert(field, axis=-1) envelope = np.abs(e_complx) # If the user asked for slicing along z, do it now diff --git a/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py index e56a08be..7dd31c56 100644 --- a/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -15,7 +15,7 @@ from ..utilities import construct_3d_from_circ def read_field_cartesian( filename, field_path, axis_labels, - slicing, slice_across ): + slice_relative_position, slice_across ): """ Extract a given field from an HDF5 file in the openPMD format, when the geometry is cartesian (1d, 2d or 3d). @@ -32,13 +32,6 @@ def read_field_cartesian( filename, field_path, axis_labels, axis_labels: list of strings The name of the dimensions of the array (e.g. ['x', 'y', 'z']) - slicing : list of float or None - Number(s) between -1 and 1 that indicate where to slice the data, - along the directions in `slice_across` - -1 : lower edge of the simulation box - 0 : middle of the simulation box - 1 : upper edge of the simulation box - slice_across : list of str or None Direction(s) along which to slice the data Elements can be: @@ -47,6 +40,13 @@ def read_field_cartesian( filename, field_path, axis_labels, - 3d: 'x' and/or 'y' and/or 'z' Returned array is reduced by 1 dimension per slicing. + slice_relative_position : list of float or None + Number(s) between -1 and 1 that indicate where to slice the data, + along the directions in `slice_across` + -1 : lower edge of the simulation box + 0 : middle of the simulation box + 1 : upper edge of the simulation box + Returns ------- A tuple with @@ -75,7 +75,7 @@ def read_field_cartesian( filename, field_path, axis_labels, # Number of cells along the slicing direction n_cells = shape[ slicing_index ] # Index of the slice (prevent stepping out of the array) - i_cell = int( 0.5 * (slicing[count] + 1.) * n_cells ) + i_cell = int( 0.5 * (slice_relative_position[count] + 1.) * n_cells ) i_cell = max( i_cell, 0 ) i_cell = min( i_cell, n_cells - 1) list_i_cell.append(i_cell) @@ -108,8 +108,8 @@ def read_field_cartesian( filename, field_path, axis_labels, return( F, info ) -def read_field_circ( filename, field_path, slicing, slice_across, m=0, - theta=0. ): +def read_field_circ( filename, field_path, slice_relative_position, + slice_across, m=0, theta=0. ): """ Extract a given field from an HDF5 file in the openPMD format, when the geometry is thetaMode @@ -132,18 +132,18 @@ def read_field_circ( filename, field_path, slicing, slice_across, m=0, corresponding to the plane of observation given by `theta` ; otherwise it returns a full 3D Cartesian array - slicing : list of float or None + slice_across : list of str or None + Direction(s) along which to slice the data + Elements can be 'r' and/or 'z' + Returned array is reduced by 1 dimension per slicing. + + slice_relative_position : list of float or None Number(s) between -1 and 1 that indicate where to slice the data, along the directions in `slice_across` -1 : lower edge of the simulation box 0 : middle of the simulation box 1 : upper edge of the simulation box - slice_across : list of str or None - Direction(s) along which to slice the data - Elements can be 'r' and/or 'z' - Returned array is reduced by 1 dimension per slicing. - Returns ------- A tuple with @@ -232,7 +232,7 @@ def read_field_circ( filename, field_path, slicing, slice_across, m=0, # Number of cells along the slicing direction n_cells = len(coord_array) # Index of the slice (prevent stepping out of the array) - i_cell = int( 0.5 * (slicing[count] + 1.) * n_cells ) + i_cell = int( 0.5 * (slice_relative_position[count] + 1.) * n_cells ) i_cell = max( i_cell, 0 ) i_cell = min( i_cell, n_cells - 1) F_total = np.take( F_total, [i_cell], axis=slicing_index ) diff --git a/openpmd_viewer/openpmd_timeseries/interactive.py b/openpmd_viewer/openpmd_timeseries/interactive.py index 33a529b5..9b546755 100644 --- a/openpmd_viewer/openpmd_timeseries/interactive.py +++ b/openpmd_viewer/openpmd_timeseries/interactive.py @@ -121,7 +121,8 @@ def refresh_field(change=None, force=False): self.get_field( iteration=self.current_iteration, plot=True, field=fieldtype_button.value, coord=coord_button.value, m=convert_to_int(mode_button.value), - slicing=slicing_button.value, theta=theta_button.value, + slice_relative_position=slicing_button.value, + theta=theta_button.value, slice_across=slice_across, plot_range=plot_range, **kw_fld ) diff --git a/openpmd_viewer/openpmd_timeseries/main.py b/openpmd_viewer/openpmd_timeseries/main.py index f8a0d7f9..fa9e9ccb 100644 --- a/openpmd_viewer/openpmd_timeseries/main.py +++ b/openpmd_viewer/openpmd_timeseries/main.py @@ -355,8 +355,8 @@ def get_particle(self, var_list=None, species=None, t=None, iteration=None, return(data_list) def get_field(self, field=None, coord=None, t=None, iteration=None, - m='all', theta=0., slicing=None, slice_across=None, - plot=False, + m='all', theta=0., slice_across=None, + slice_relative_position=None, plot=False, plot_range=[[None, None], [None, None]], **kw): """ Extract a given field from an HDF5 file in the openPMD format. @@ -393,15 +393,6 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, corresponding to the plane of observation given by `theta` ; otherwise it returns a full 3D Cartesian array - slicing : float or list of float, optional - Number(s) between -1 and 1 that indicate where to slice the data, - along the directions in `slice_across` - -1 : lower edge of the simulation box - 0 : middle of the simulation box - 1 : upper edge of the simulation box - Default: None, which results in slicing at 0 in all direction - of `slice_across`. - slice_across : str or list of str, optional Direction(s) along which to slice the data + In cartesian geometry, elements can be: @@ -412,6 +403,15 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, Returned array is reduced by 1 dimension per slicing. If slicing is None, the full grid is returned. + slice_relative_position : float or list of float, optional + Number(s) between -1 and 1 that indicate where to slice the data, + along the directions in `slice_across` + -1 : lower edge of the simulation box + 0 : middle of the simulation box + 1 : upper edge of the simulation box + Default: None, which results in slicing at 0 in all direction + of `slice_across`. + plot : bool, optional Whether to plot the requested quantity @@ -442,7 +442,8 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, "The available fields are: \n - %s\nPlease set the `field` " "argument accordingly." % field_list) # Check slicing - slice_across, slicing = sanitize_slicing(slice_across, slicing) + slice_across, slice_relative_position = \ + sanitize_slicing(slice_across, slice_relative_position) if slice_across is not None: # Check that the elements are valid axis_labels = self.fields_metadata[field]['axis_labels'] @@ -493,22 +494,22 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, axis_labels = self.fields_metadata[field]['axis_labels'] # - For cartesian if geometry in ["1dcartesian", "2dcartesian", "3dcartesian"]: - F, info = read_field_cartesian( - filename, field_path, axis_labels, slicing, slice_across) + F, info = read_field_cartesian( filename, field_path, + axis_labels, slice_relative_position, slice_across) # - For thetaMode elif geometry == "thetaMode": if (coord in ['x', 'y']) and \ (self.fields_metadata[field]['type'] == 'vector'): # For Cartesian components, combine r and t components - Fr, info = read_field_circ(filename, field + '/r', slicing, - slice_across, m, theta) - Ft, info = read_field_circ(filename, field + '/t', slicing, - slice_across, m, theta) + Fr, info = read_field_circ(filename, field + '/r', + slice_relative_position, slice_across, m, theta) + Ft, info = read_field_circ(filename, field + '/t', + slice_relative_position, slice_across, m, theta) F = combine_cylindrical_components(Fr, Ft, theta, coord, info) else: # For cylindrical or scalar components, no special treatment - F, info = read_field_circ(filename, field_path, slicing, - slice_across, m, theta) + F, info = read_field_circ(filename, field_path, + slice_relative_position, slice_across, m, theta) # Plot the resulting field # Deactivate plotting when there is no slice selection @@ -522,7 +523,7 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, plot_range=plot_range, **kw) else: raise OpenPMDException('Cannot plot %d-dimensional data.\n' - 'Use slicing, or set `plot=False`' % F.ndim) + 'Use the argument `slice_across`, or set `plot=False`' % F.ndim) # Return the result return(F, info) diff --git a/openpmd_viewer/openpmd_timeseries/utilities.py b/openpmd_viewer/openpmd_timeseries/utilities.py index dc024628..391aa3ca 100644 --- a/openpmd_viewer/openpmd_timeseries/utilities.py +++ b/openpmd_viewer/openpmd_timeseries/utilities.py @@ -16,16 +16,16 @@ from .data_reader.particle_reader import read_species_data from .numba_wrapper import jit -def sanitize_slicing(slice_across, slicing): +def sanitize_slicing(slice_across, slice_relative_position): """ - Return standardized format for `slice_across` and `slicing`: - - either `slice_across` and `slicing` are both `None` (no slicing) - - or `slice_across` and `slicing` are both lists, + Return standardized format for `slice_across` and `slice_relative_position`: + - either `slice_across` and `slice_relative_position` are both `None` (no slicing) + - or `slice_across` and `slice_relative_position` are both lists, with the same number of elements Parameters ---------- - slicing : float, or list of float, or None + slice_relative_position : float, or list of float, or None slice_across : str, or list of str, or None Direction(s) along which to slice the data @@ -37,14 +37,14 @@ def sanitize_slicing(slice_across, slicing): # Convert to lists if not isinstance(slice_across, list): slice_across = [slice_across] - if slicing is None: - slicing = [0]*len(slice_across) - if not isinstance(slicing, list): - slicing = [slicing] + if slice_relative_position is None: + slice_relative_position = [0]*len(slice_across) + if not isinstance(slice_relative_position, list): + slice_relative_position = [slice_relative_position] # Check that the length are matching - if len(slice_across) != len(slicing): + if len(slice_across) != len(slice_relative_position): raise ValueError( - 'The `slicing` argument is erroneous: \nIt should have' + 'The argument `slice_relative_position` is erroneous: \nIt should have' 'the same number of elements as `slice_across`.') # Return a copy. This is because the rest of the `openPMD-viewer` code @@ -52,7 +52,7 @@ def sanitize_slicing(slice_across, slicing): # Using a copy avoids directly modifying objects that the user may pass # to this function (and live outside of openPMD-viewer, e.g. directly in # a user's notebook) - return copy.copy(slice_across), copy.copy(slicing) + return copy.copy(slice_across), copy.copy(slice_relative_position) def list_h5_files(path_to_dir): From 071874783bc1b1f320bb06d51b136f99aefcced0 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 30 Jan 2020 21:31:43 -0800 Subject: [PATCH 88/90] Change documentation --- CHANGELOG.md | 6 ++++-- openpmd_viewer/addons/pic/lpa_diagnostics.py | 2 +- .../openpmd_timeseries/data_reader/field_reader.py | 4 ++-- openpmd_viewer/openpmd_timeseries/main.py | 2 +- openpmd_viewer/openpmd_timeseries/utilities.py | 2 +- opmd_viewer/__init__.py | 3 ++- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa450d64..cee1c6c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,12 +15,14 @@ meters ``` x, y, z = ts.get_particle(['x', 'y', 'z'], iteration=1000) ``` -- In `ts.get_field`, slicing can now be done in several directions -(by passing a list as the argument `slicing_dir`), and for +- In `ts.get_field`, slicing can now be done in several directions, and for 1d, 2d, 3d, and circ geometries. As a consequence, this breaks backward compatibility for 3d field: ```get_field(field=field, coord=coord, iteration=iteration)``` used to return the central slice along `y` while it now returns the full 3d field. +In addition, the name of the argument of `get_field` that triggers slicing +has been changed from `slicing_dir` to `slice_across` (and `slicing` has been +changed to `slice_relative_position`). - `openPMD-viewer` does not rely on Cython anymore. Instead, it uses `numba` for functions that perform a substantial amount of computation. - A new function (`ts.iterate`) was introduced in order to quickly apply a diff --git a/openpmd_viewer/addons/pic/lpa_diagnostics.py b/openpmd_viewer/addons/pic/lpa_diagnostics.py index a45988d0..e50ea593 100644 --- a/openpmd_viewer/addons/pic/lpa_diagnostics.py +++ b/openpmd_viewer/addons/pic/lpa_diagnostics.py @@ -475,7 +475,7 @@ def get_laser_envelope( self, t=None, iteration=None, pol=None, m='all', The angle of the plane of observation, with respect to the x axis slice_across : str or list of str, optional - Direction(s) along which to slice the data + Direction(s) across which the data should be sliced + In cartesian geometry, elements can be: - 1d: 'z' - 2d: 'x' and/or 'z' diff --git a/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py b/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py index 7dd31c56..ceb005fa 100644 --- a/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py +++ b/openpmd_viewer/openpmd_timeseries/data_reader/field_reader.py @@ -33,7 +33,7 @@ def read_field_cartesian( filename, field_path, axis_labels, The name of the dimensions of the array (e.g. ['x', 'y', 'z']) slice_across : list of str or None - Direction(s) along which to slice the data + Direction(s) across which the data should be sliced Elements can be: - 1d: 'z' - 2d: 'x' and/or 'z' @@ -133,7 +133,7 @@ def read_field_circ( filename, field_path, slice_relative_position, otherwise it returns a full 3D Cartesian array slice_across : list of str or None - Direction(s) along which to slice the data + Direction(s) across which the data should be sliced Elements can be 'r' and/or 'z' Returned array is reduced by 1 dimension per slicing. diff --git a/openpmd_viewer/openpmd_timeseries/main.py b/openpmd_viewer/openpmd_timeseries/main.py index fa9e9ccb..ca1bd747 100644 --- a/openpmd_viewer/openpmd_timeseries/main.py +++ b/openpmd_viewer/openpmd_timeseries/main.py @@ -394,7 +394,7 @@ def get_field(self, field=None, coord=None, t=None, iteration=None, otherwise it returns a full 3D Cartesian array slice_across : str or list of str, optional - Direction(s) along which to slice the data + Direction(s) across which the data should be sliced + In cartesian geometry, elements can be: - 1d: 'z' - 2d: 'x' and/or 'z' diff --git a/openpmd_viewer/openpmd_timeseries/utilities.py b/openpmd_viewer/openpmd_timeseries/utilities.py index 391aa3ca..daced34a 100644 --- a/openpmd_viewer/openpmd_timeseries/utilities.py +++ b/openpmd_viewer/openpmd_timeseries/utilities.py @@ -28,7 +28,7 @@ def sanitize_slicing(slice_across, slice_relative_position): slice_relative_position : float, or list of float, or None slice_across : str, or list of str, or None - Direction(s) along which to slice the data + Direction(s) across which the data should be sliced """ # Skip None and empty lists if slice_across is None or slice_across == []: diff --git a/opmd_viewer/__init__.py b/opmd_viewer/__init__.py index 5c45d149..f588b9a3 100644 --- a/opmd_viewer/__init__.py +++ b/opmd_viewer/__init__.py @@ -20,7 +20,8 @@ Please have a look at the list of the changes introduced in version 1.X here: https://github.com/openPMD/openPMD-viewer/blob/upcoming-1.0/CHANGELOG.md#10 In particular, note that `get_particle` now returns particle positions in -meters (not in microns anymore). +meters (not in microns anymore) and that the syntax for slicing fields has +changed. * If you wish to go back to the old openPMD-viewer version 0.X, use: ``` From 99ea06e81721a9368e8a0453d22e946b6a1732c1 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Mon, 3 Feb 2020 12:38:18 -0800 Subject: [PATCH 89/90] Remove instructions and files for conda build --- RELEASING.md | 19 ------------------ conda_recipe/Dockerfile | 21 -------------------- conda_recipe/meta.yaml | 43 ----------------------------------------- 3 files changed, 83 deletions(-) delete mode 100644 conda_recipe/Dockerfile delete mode 100644 conda_recipe/meta.yaml diff --git a/RELEASING.md b/RELEASING.md index b9c188c8..5a686632 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -57,22 +57,3 @@ twine upload dist/* -r pypi (NB: You can also first test this by uploading the package to [test PyPI](https://testpypi.python.org/pypi) ; to do so, simply replace `pypi` by `pypitest` in the above set of commands) - -## Uploading the package to Anaconda.org - -- `cd` into the folder `conda_recipe`. - -- Still in the folder `conda_recipe`, run -``` -docker build -t openpmd_build . -docker run -it -v $PWD:/home/ openpmd_build -``` -This builds the conda packages for Python 2.7, 3.4, 3.5 and 3.6, using a -reproduceable environment. - -- After the build, the Docker container will **not** exit. From the container, type the following commands: -``` -anaconda login -anaconda upload osx-64/* -anaconda upload /opt/conda/conda-bld/linux-64/openpmd_viewer* -``` diff --git a/conda_recipe/Dockerfile b/conda_recipe/Dockerfile deleted file mode 100644 index e5cf7b31..00000000 --- a/conda_recipe/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -FROM continuumio/miniconda -MAINTAINER Remi Lehe - -RUN apt-get update \ - && apt-get install -y \ - gcc \ - libgl1-mesa-glx \ - && rm -rf /var/lib/apt/lists/* - -RUN conda install --yes conda conda-build anaconda-client - -CMD cd /home/ \ - && conda build --python=2.7 . \ - && conda convert $(conda build --python=2.7 . --output) -p osx-64 \ - && conda build --python=3.4 . \ - && conda convert $(conda build --python=3.4 . --output) -f -p osx-64 \ - && conda build --python=3.5 . \ - && conda convert $(conda build --python=3.5 . --output) -f -p osx-64 \ - && conda build --python=3.6 . \ - && conda convert $(conda build --python=3.6 . --output) -f -p osx-64 \ - && /bin/bash diff --git a/conda_recipe/meta.yaml b/conda_recipe/meta.yaml deleted file mode 100644 index fe9e8de1..00000000 --- a/conda_recipe/meta.yaml +++ /dev/null @@ -1,43 +0,0 @@ - -{% set version = "1.0.0" %} - -package: - name: openpmd_viewer - version: {{ version }} - -source: - git_rev: {{ version }} - git_url: https://github.com/openPMD/openPMD-viewer.git - -build: - script: python setup.py install - -requirements: - build: - - python - - setuptools - - numpy - - scipy - - matplotlib - - numba - - h5py - - tqdm - run: - - python - - numpy - - scipy - - matplotlib - - numba - - h5py - - jupyter - - tqdm - -test: - imports: - - openpmd_viewer - -about: - home: https://github.com/openPMD/openPMD-viewer - license: BSD-3-clause - license_file: LICENSE.txt - summary: "Visualization tools for openPMD files" From b92697808f1a1253c8908905c92b99e85ec60102 Mon Sep 17 00:00:00 2001 From: Remi Lehe Date: Thu, 6 Feb 2020 09:54:51 -0800 Subject: [PATCH 90/90] Update installation instructions --- README.md | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b416b4ac..ecbfdb7f 100644 --- a/README.md +++ b/README.md @@ -52,12 +52,12 @@ browser**. To use this executable, simply type in a regular terminal: ### Installation on a local computer -#### Installation with conda (recommended) +#### Installation with conda In order to install `openPMD-viewer` with `conda`, please install the [Anaconda distribution](https://docs.anaconda.com/anaconda/install/), and then type ``` -conda install -c rlehe openpmd_viewer +conda install -c conda-forge openpmd-viewer ``` If you are using JupyterLab, please also install the `jupyter-matplotlib` extension (See installation instructions @@ -65,14 +65,9 @@ extension (See installation instructions #### Installation with pip -If you cannot install `openPMD-viewer` with `conda`, the alternative -is to use `pip`. However, you need to first make sure that `h5py` is -installed on your local computer. This can be done for instance by -typing `pip install h5py`, though this may require you to install `hdf5` separately. - -Once `h5py` is installed, simply type +You can also install `openPMD-viewer` using `pip` ``` -pip install openPMD-viewer +pip install openpmd-viewer ``` In addition, if you wish to use the interactive GUI, please type ```