예제 #1
0
def is_proper_unit(vendor_name, unit, row, row_count):
    ureg = UnitRegistry()
    try:
        ureg.parse_expression(row[unit])
    except UndefinedUnitError:
        flash("Error parsing {}'s CSV file. Bad entry in the {} column, at row {} "
              .format(vendor_name, unit, row_count),'form-error')
        return False
    return True
예제 #2
0
 def test_issue25(self):
     x = ParserHelper.from_string('10 %')
     self.assertEqual(x, ParserHelper(10, {'%': 1}))
     x = ParserHelper.from_string('10 ‰')
     self.assertEqual(x, ParserHelper(10, {'‰': 1}))
     ureg = UnitRegistry()
     ureg.define('percent = [fraction]; offset: 0 = %')
     ureg.define('permille = percent / 10 = ‰')
     x = ureg.parse_expression('10 %')
     self.assertEqual(x, ureg.Quantity(10, {'%': 1}))
     y = ureg.parse_expression('10 ‰')
     self.assertEqual(y, ureg.Quantity(10, {'‰': 1}))
     self.assertEqual(x.to('‰'), ureg.Quantity(1, {'‰': 1}))
예제 #3
0
 def test_issue25(self):
     x = ParserHelper.from_string("10 %")
     self.assertEqual(x, ParserHelper(10, {"%": 1}))
     x = ParserHelper.from_string("10 ‰")
     self.assertEqual(x, ParserHelper(10, {"‰": 1}))
     ureg = UnitRegistry()
     ureg.define("percent = [fraction]; offset: 0 = %")
     ureg.define("permille = percent / 10 = ‰")
     x = ureg.parse_expression("10 %")
     self.assertEqual(x, ureg.Quantity(10, {"%": 1}))
     y = ureg.parse_expression("10 ‰")
     self.assertEqual(y, ureg.Quantity(10, {"‰": 1}))
     self.assertEqual(x.to("‰"), ureg.Quantity(1, {"‰": 1}))
def parse_units_from_str(input_str):
    """Matches an input string to the closest matching scientific unit using Pint Package
    """
    unit_reg = UnitRegistry()
    
    if input_str:
        cleaned_str = re.sub('\*', '', input_str)
        cleaned_str = re.sub(u'μ', 'u', cleaned_str) # weird issue with Pint Package choking on mu signs
        cleaned_str = re.sub(u'Ω', 'ohm', cleaned_str) # weird issue with Pint Package choking on Omega signs
        cleaned_str = re.sub(u'\u2126', 'ohm', cleaned_str) # converting unicode sign for Omega
        cleaned_str = re.sub(u'\u03a9', 'ohm', cleaned_str) # converting unicode sign for Omega
        cleaned_str = re.sub(u'mohm', 'Mohm', cleaned_str) # deals with mOhm not being MOhm
        cleaned_str = re.sub('\%', 'ratio', cleaned_str) # weird issue with Pint Package choking on percent signs
        cleaned_str = re.sub('\s+', '', cleaned_str) # removing all whitespace in string
        # TODO: make below code more robust
        # check whether last character in string is capital M, if so assume it means mole
        if input_str[-1] == 'M':
            cleaned_str = re.sub(r'(\w)+M$', 'mole', cleaned_str) # adding M as synonym for mole

        try:
            matched_unit = unit_reg.parse_expression(cleaned_str)
            if hasattr(matched_unit, 'units'):
                return input_str, matched_unit
        except UndefinedUnitError:
            #print u'UndefinedUnitError during unit parsing : %s' % cleaned_str
            return None
        except AttributeError:
            #print u'Attribute Error during unit parsing : %s' % cleaned_str
            return None
        except Exception:
            #print u'unit parsing failed for some unexplained reason: %s' % cleaned_str
            return None
    else:
        return None
예제 #5
0
파일: rail.py 프로젝트: vishnubob/camrail
import time
import math
import pigpio

# units
from pint import UnitRegistry
units = UnitRegistry()
units.define('steps = in / 254 = step')

DEFAULT_UNIT = units.parse_expression("steps")

def unit(val, **kw):
    _unit = kw.get("unit", DEFAULT_UNIT)
    val = units.parse_expression(val)
    if type(val) != units.Quantity:
        if type(val) in (int, float):
            assert _unit, "value %r of type '%r' requires a unit definition" % (val, type(val))
            val = val * _unit
        else:
            raise TypeError, "I don't know how to convert type '%s' to a unit" % str(type(val))
    assert type(val) == units.Quantity, "%r != %r" % (type(val), units.Quantity)
    if _unit:
        val = val.to(_unit)
    return val

def steps(val):
    val = unit(val)
    return int(val.to("steps").magnitude)

class CameraRail(object):
    pin_enable = 2
예제 #6
0
def add_spikes(stimuli, spikefile, spike_times, nix_file, nix_spiketimes):
    if 'stimspikes' in spikefile:
        repro = 'FileStimulus'
    elif 'samallspikes' in spikefile:
        repro = 'SAM'
    else:
        raise Exception('Cannot determine repro')

    print "Assuming RePro=%s" % (repro, )


    ureg = UnitRegistry()

    spikes = load(spikefile)
    spi_meta, spi_key, spi_data = spikes.selectall()


    for run_idx, (spi_d, spi_m) in enumerate(zip(spi_data, spi_meta)):
        print "\t%s run %i" % (repro, run_idx)

        if repro == 'FileStimulus':
            spi_m = add_stimulus_meta(spi_m)
        # match index from stimspikes with run from stimuli.dat
        stim_m, stim_k, stim_d = stimuli.subkey_select(RePro=repro, Run=spi_m['index'])

        if len(stim_m) > 1:
            raise KeyError('%s and index are not unique to identify stimuli.dat block.' % (repro, ))
        else:
            stim_k = stim_k[0]
            stim_m = stim_m[0]
            signal_column = [i for i,k in enumerate(stim_k) if k[:4] == ('stimulus', 'GlobalEField', 'signal', '-')][0]

            valid = []

            if stim_d == [[[0]]]:
                print("\t\tEmpty stimuli data! Continuing ...")
                continue

            for d in stim_d[0]:
                if not d[signal_column].startswith('FileStimulus-value'):
                    valid.append(d)
                else:
                    print("\t\tExcluding a reset trial from stimuli.dat")
            stim_d = valid


        if len(stim_d) != len(spi_d):
            print("""\t\t%s index %i has %i trials, but stimuli.dat has %i. Trial was probably aborted. Not including data.""" % (spikefile, spi_m['index'], len(spi_d), len(stim_d)))
            continue



        start_index, index = [(i, k[-1]) for i,k in enumerate(stim_k) if 'traces' in k and 'V-1' in k][0]
        sample_interval, time_unit = get_number_and_unit(stim_m['analog input traces']['sample interval%i' % (index,)])

        if repro == 'FileStimulus':
            duration = ureg.parse_expression(spi_m['duration']).to(time_unit).magnitude
        elif repro == 'SAM':
            duration = ureg.parse_expression(spi_m['Settings']['Stimulus']['duration']).to(time_unit).magnitude

        start_times = []

        start_indices = [d[start_index] for d in stim_d]
        for begin_index, trial in zip(start_indices, spi_d):
            start_time = begin_index*sample_interval
            start_times.append(start_time)
            spike_times.append(trial+start_time)


        start_times = np.asarray(start_times)
        durations = duration * np.ones(len(stim_d))


        tag_name = "%s-run-%i" % (repro, run_idx)
        positions = recording_block.create_data_array(tag_name+'_starts','nix.event.position', nix.DataType.Double, start_times.shape)
        positions.data.write_direct(start_times)
        positions.append_set_dimension()

        extents = recording_block.create_data_array(tag_name+'_extents','nix.event.extents', nix.DataType.Double, durations.shape)
        extents.data.write_direct(durations)
        extents.append_set_dimension()

        tag = recording_block.create_multi_tag(tag_name, 'nix.experiment_run', positions)
        tag.extents = extents
        tag.references.append(nix_spiketimes)


        for nt in nix_traces:
            tag.references.append(nt)

        sec = nix_file.create_section(tag_name, "nix.metadata")
        tag.metadata = sec

        insert_metadata(sec, stim_m)
        insert_metadata(sec, spi_m)
예제 #7
0
    def statistics(self,
                   sb_position=None,
                   sb='lower',
                   high_cf=False,
                   fringe_contrast_algorithm='statistical',
                   apodization='hanning',
                   single_values=True,
                   show_progressbar=False,
                   parallel=None):
        """
        Calculates following statistics for off-axis electron holograms:

        1. Fringe contrast using either statistical definition or
        Fourier space approach (see description of `fringe_contrast_algorithm` parameter)
        2. Fringe sampling (in pixels)
        3. Fringe spacing (in calibrated units)
        4. Carrier frequency (in calibrated units, radians and 1/px)

        Parameters
        ----------
        sb_position : tuple, :class:`~hyperspy.signals.Signal1D, None
            The sideband position (y, x), referred to the non-shifted FFT.
            It has to be tuple or to have the same dimensionality as the hologram.
            If None, sideband is determined automatically from FFT.
        sb : str, None
            Select which sideband is selected. 'upper', 'lower', 'left' or 'right'.
        high_cf : bool, optional
            If False, the highest carrier frequency allowed for the sideband location is equal to
            half of the Nyquist frequency (Default: False).
        fringe_contrast_algorithm : str
            Select fringe contrast algorithm between:

            'fourier'
                fringe contrast is estimated as:
                2 * <I(k_0)> / <I(0)>,
                where I(k_0) is intensity of sideband and I(0) is the intensity of central band (FFT origin).
                This method delivers also reasonable estimation if
                interference pattern do not cover full field of view.
            'statistical'
                fringe contrast is estimated by dividing standard deviation by mean
                of the hologram intensity in real space. This algorithm relays on that the fringes are regular and
                covering entire field of view.

            (Default: 'statistical')
        apodization: str or None, optional
            Used with `fringe_contrast_algorithm='fourier'`. If 'hanning' or 'hamming' apodization window
            will be applied in real space before FFT for estimation of fringe contrast.
            Apodization is typically needed to suppress striking  due to sharp edges of the image,
            which often results in underestimation of the fringe contrast. (Default: 'hanning')
        single_values : bool, optional
            If True calculates statistics only for the first navigation pixels and
            returns the values as single floats (Default: True)
        show_progressbar : bool, optional
            Shows progressbar while iterating over different slices of the
            signal (passes the parameter to map method). (Default: False)
        parallel : bool, None, optional
            Run the reconstruction in parallel

        Returns
        -------
        statistics_dict :
            Dictionary with the statistics

        Examples
        --------
        >>> import hyperspy.api as hs
        >>> s = hs.datasets.example_signals.reference_hologram()
        >>> sb_position = s.estimate_sideband_position(high_cf=True)
        >>> s.statistics(sb_position=sb_position)
        {'Fringe spacing (nm)': 3.4860442674236256,
        'Carrier frequency (1/px)': 0.26383819985575441,
        'Carrier frequency (mrad)': 0.56475154609203482,
        'Fringe contrast': 0.071298357213623778,
        'Fringe sampling (px)': 3.7902017241882331,
        'Carrier frequency (1 / nm)': 0.28685808994016415}
        """

        # Testing match of navigation axes of reference and self
        # (exception: reference nav_dim=1):

        # Parsing sideband position:
        (sb_position, sb_position_temp) = _parse_sb_position(
            self, None, sb_position, sb, high_cf, parallel)

        # Calculate carrier frequency in 1/px and fringe sampling:
        fourier_sampling = 1. / np.array(self.axes_manager.signal_shape)
        if single_values:
            carrier_freq_px = calculate_carrier_frequency(_first_nav_pixel_data(self),
                                                          sb_position=_first_nav_pixel_data(
                                                              sb_position),
                                                          scale=fourier_sampling)
        else:
            carrier_freq_px = self.map(calculate_carrier_frequency,
                                       sb_position=sb_position,
                                       scale=fourier_sampling,
                                       inplace=False,
                                       ragged=False,
                                       show_progressbar=show_progressbar,
                                       parallel=parallel)
        fringe_sampling = np.divide(1., carrier_freq_px)

        ureg = UnitRegistry()
        try:
            units = ureg.parse_expression(
                str(self.axes_manager.signal_axes[0].units))
        except UndefinedUnitError:
            raise ValueError('Signal axes units should be defined.')

        # Calculate carrier frequency in 1/units and fringe spacing in units:
        f_sampling_units = np.divide(
            1.,
            [a * b for a, b in
             zip(self.axes_manager.signal_shape,
                 (self.axes_manager.signal_axes[0].scale,
                  self.axes_manager.signal_axes[1].scale))]
        )
        if single_values:
            carrier_freq_units = calculate_carrier_frequency(_first_nav_pixel_data(self),
                                                             sb_position=_first_nav_pixel_data(
                                                                 sb_position),
                                                             scale=f_sampling_units)
        else:
            carrier_freq_units = self.map(calculate_carrier_frequency,
                                          sb_position=sb_position,
                                          scale=f_sampling_units,
                                          inplace=False,
                                          ragged=False,
                                          show_progressbar=show_progressbar,
                                          parallel=parallel)
        fringe_spacing = np.divide(1., carrier_freq_units)

        # Calculate carrier frequency in mrad:
        try:
            ht = self.metadata.Acquisition_instrument.TEM.beam_energy
        except BaseException:
            raise AttributeError("Please define the beam energy."
                                 "You can do this e.g. by using the "
                                 "set_microscope_parameters method.")

        momentum = 2 * constants.m_e * constants.elementary_charge * ht * \
            1000 * (1 + constants.elementary_charge * ht *
                    1000 / (2 * constants.m_e * constants.c ** 2))
        wavelength = constants.h / np.sqrt(momentum) * 1e9  # in nm
        carrier_freq_quantity = wavelength * \
            ureg('nm') * carrier_freq_units / units * ureg('rad')
        carrier_freq_mrad = carrier_freq_quantity.to('mrad').magnitude

        # Calculate fringe contrast:
        if fringe_contrast_algorithm == 'fourier':
            if single_values:
                fringe_contrast = estimate_fringe_contrast_fourier(_first_nav_pixel_data(self),
                                                                   sb_position=_first_nav_pixel_data(
                                                                       sb_position),
                                                                   apodization=apodization)
            else:
                fringe_contrast = self.map(estimate_fringe_contrast_fourier,
                                           sb_position=sb_position,
                                           apodization=apodization,
                                           inplace=False,
                                           ragged=False,
                                           show_progressbar=show_progressbar,
                                           parallel=parallel)
        elif fringe_contrast_algorithm == 'statistical':
            if single_values:
                fringe_contrast = _first_nav_pixel_data(
                    self).std() / _first_nav_pixel_data(self).mean()
            else:
                fringe_contrast = _estimate_fringe_contrast_statistical(self)
        else:
            raise ValueError(
                "fringe_contrast_algorithm can only be set to fourier or statistical.")

        return {'Fringe contrast': fringe_contrast,
                'Fringe sampling (px)': fringe_sampling,
                'Fringe spacing ({:~})'.format(units.units): fringe_spacing,
                'Carrier frequency (1/px)': carrier_freq_px,
                'Carrier frequency ({:~})'.format((1. / units).units): carrier_freq_units,
                'Carrier frequency (mrad)': carrier_freq_mrad}
예제 #8
0
def valid_uom(uom):
    ureg = UnitRegistry()
    if not ureg.parse_expression(uom).unitless:
        raise serializers.ValidationError('Invalid unit %s'.format(uom))
print('Data files included: ')
for folder in glob.glob("data/*"):  
    print(folder)
      
    dataLists[folder.split("/")[1]] = []  
      
    for datafile in glob.glob(folder + "/*.csv"):
        print(datafile)
        dataLists[folder.split("/")[1]].append(read_csv(datafile))
print('import completed', '\n')

## convert units to desired

for author in dataLists.keys():
    for index in dataLists[author]:
        n = float(index[normalize][1]) * ureg.parse_expression(str(index[normalize][0]))
        if n.magnitude:                 # only normalize if normalization quantity is in the csv file
            print(str(author) + ' ' + str(index['Sample Description'][0]) +  ' normalized by: ' + str(unit['normalize']))
            Ptemplist = []
            Ptemplist.append(str(unit['Power'] + '/' + unit['normalize']))        
            for element in index['Power'][1:]:
                a = float(element) * ureg.parse_expression(str(index['Power'][0]))
                b = a / n
                c = b.to(ureg.parse_expression(Ptemplist[0]))
                Ptemplist.append(c)
            index['P_norm'] = Ptemplist
            
            Etemplist = []
            Etemplist.append(str(unit['Energy'] + '/' + unit['normalize']))
            for element in index['Energy'][1:]:
                a = float(element) * ureg.parse_expression(str(index['Energy'][0]))
def main(data_dir):
    ureg = UnitRegistry()
    food_description_file = os.path.join(data_dir, "FOOD_DES.txt")
    nutrient_definition_file = os.path.join(data_dir, "NUTR_DEF.txt")
    nutrition_data_file = os.path.join(data_dir, "NUT_DATA.txt")
    weight_data_file = os.path.join(data_dir, "WEIGHT.txt")

    food_descriptions = pandas.read_csv(food_description_file, quotechar='~', delimiter='^', encoding='latin-1',
                                        header=None, names=food_description_columns)
    nutrient_definitions = pandas.read_csv(nutrient_definition_file, quotechar='~', delimiter='^', encoding='latin-1',
                                           header=None, names=nutrient_definition_columns)
    nutrition_data = pandas.read_csv(nutrition_data_file, quotechar='~', delimiter='^', encoding='latin-1', header=None,
                                     names=nutrition_data_columns)
    weight_data = pandas.read_csv(weight_data_file, quotechar='~', delimiter='^', encoding='latin-1', header=None,
                                  names=weight_data_columns)

    # Pandas is retarded when it comes to handling text in csv files...
    food_descriptions.fillna('', inplace=True)
    nutrient_definitions.fillna('', inplace=True)
    nutrition_data.fillna('', inplace=True)
    weight_data.fillna('', inplace=True)

    with app.test_request_context():
        ingredients = {}
        ingredient_preparations = []
        nutrients = {}
        ingredient_nutrients = []

        for entry in food_descriptions.itertuples():
            if entry.food_group in ignored_food_groups:
                continue
            ingredient = models.Ingredient(ingredient_id=int(entry.ndb_id))
            ingredients[entry.ndb_id] = ingredient
            ingredient.names.append(models.IngredientName(name=entry.description, canonical=True))

        for entry in nutrient_definitions.itertuples():
            nutrient_id = int(entry.nutrient_id)
            display_name = nutrient_display_names.get(nutrient_id)
            scientific_name = nutrient_scientific_names.get(nutrient_id)
            recommended_daily_intake = nutrient_rdi.get(nutrient_id)
            display = display_nutrient.get(nutrient_id, False)
            nutrient = models.Nutrient(nutrient_id=nutrient_id, display_name=display_name,
                                       scientific_name=scientific_name, measurement_unit=entry.units,
                                       recommended_daily_intake=recommended_daily_intake, display=display)
            nutrients[nutrient_id] = nutrient

        # Most entries in the weights file conform to this pattern
        weight_re = re.compile(r"([\w\s]+?)(?:\s+\(.*\))?(?:,\s+(.*))?\Z")
        for weight_entry in weight_data.itertuples():
            if weight_entry.ndb_id not in ingredients:
                continue
            # Pint thinks fl oz is femtolitre ounces
            if weight_entry.measure_description == "fl oz":
                description = "fluid ounces"
                # US regulation defines a fluid ounce as equivalent to 30mL for nutrition labeling purposes
                volume = weight_entry.amount * ureg.parse_expression("30 ml").to_base_units()
                # Convert the gram weight to kilograms so density is in standard units
                mass = weight_entry.gram_weight / 1000 * ureg.kilogram
                density = float((mass / volume).magnitude)
            # Special case, as pat matches a unit, but in this context should not be interpreted as such
            elif weight_entry.measure_description.startswith("pat "):
                description = weight_entry.measure_description
                density = None
            else:
                match = weight_re.match(weight_entry.measure_description)
                if match:
                    (unit_name, preparation) = match.groups()
                    # First determine that this weight contains units rather than something nebulous like a "serving"
                    try:
                        quantity = weight_entry.amount * ureg.parse_expression(unit_name)
                        description = preparation
                        # Convert to base units so volume measurements are in cubic meters
                        volume = quantity.to_base_units()
                        # Discard entries with non-volume measurements
                        if not volume.units.get("meter") == 3:
                            continue
                        # Convert the gram weight to kilograms so density is in standard units
                        mass = weight_entry.gram_weight / 1000 * ureg.kilogram
                        density = float((mass / volume).magnitude)
                    except UndefinedUnitError:
                        description = weight_entry.measure_description
                        density = None
                else:
                    description = weight_entry.measure_description
                    density = None
            ingredient_preparation = models.IngredientMeasure(ingredient_id=int(weight_entry.ndb_id),
                                                              description=description, density=density,
                                                              amount=float(weight_entry.amount),
                                                              weight=float(weight_entry.gram_weight))
            ingredient_preparations.append(ingredient_preparation)

        for entry in nutrition_data.itertuples():
            if entry.ndb_id not in ingredients:
                continue
            ingredient_nutrient = models.IngredientNutrient(nutrient_id=int(entry.nutrient_id),
                                                            ingredient_id=int(entry.ndb_id),
                                                            quantity=float(entry.nutrient_value))
            ingredient_nutrients.append(ingredient_nutrient)
        db.session.add_all(ingredients.values())
        db.session.add_all(nutrients.values())
        db.session.commit()

        db.session.add_all(ingredient_preparations)
        db.session.add_all(ingredient_nutrients)
        db.session.commit()
예제 #11
0
    def statistics(
        self,
        sb_position=None,
        sb='lower',
        high_cf=False,
        fringe_contrast_algorithm='statistical',
        apodization='hanning',
        single_values=True,
        show_progressbar=False,
        parallel=None,
        max_workers=None,
    ):
        """
        Calculates following statistics for off-axis electron holograms:

        1. Fringe contrast using either statistical definition or
        Fourier space approach (see description of `fringe_contrast_algorithm` parameter)
        2. Fringe sampling (in pixels)
        3. Fringe spacing (in calibrated units)
        4. Carrier frequency (in calibrated units, radians and 1/px)

        Parameters
        ----------
        sb_position : tuple, Signal1D, None
            The sideband position (y, x), referred to the non-shifted FFT.
            It has to be tuple or to have the same dimensionality as the hologram.
            If None, sideband is determined automatically from FFT.
        sb : str, None
            Select which sideband is selected. 'upper', 'lower', 'left' or 'right'.
        high_cf : bool, optional
            If False, the highest carrier frequency allowed for the sideband location is equal to
            half of the Nyquist frequency (Default: False).
        fringe_contrast_algorithm : str
            Select fringe contrast algorithm between:

            * 'fourier': fringe contrast is estimated as 2 * <I(k_0)> / <I(0)>,
              where I(k_0) is intensity of sideband and I(0) is the intensity of central band (FFT origin).
              This method delivers also reasonable estimation if the
              interference pattern do not cover full field of view.
            * 'statistical': fringe contrast is estimated by dividing the 
              standard deviation by the mean of the hologram intensity in real
              space. This algorithm relies on regularly spaced fringes and
              covering the entire field of view.

            (Default: 'statistical')
        apodization: str or None, optional
            Used with `fringe_contrast_algorithm='fourier'`. If 'hanning' or 'hamming' apodization window
            will be applied in real space before FFT for estimation of fringe contrast.
            Apodization is typically needed to suppress striking  due to sharp edges of the image,
            which often results in underestimation of the fringe contrast. (Default: 'hanning')
        single_values : bool, optional
            If True calculates statistics only for the first navigation pixels and
            returns the values as single floats (Default: True)
        %s
        %s
        %s

        Returns
        -------
        statistics_dict :
            Dictionary with the statistics

        Examples
        --------
        >>> import hyperspy.api as hs
        >>> s = hs.datasets.example_signals.reference_hologram()
        >>> sb_position = s.estimate_sideband_position(high_cf=True)
        >>> s.statistics(sb_position=sb_position)
        {'Fringe spacing (nm)': 3.4860442674236256,
        'Carrier frequency (1/px)': 0.26383819985575441,
        'Carrier frequency (mrad)': 0.56475154609203482,
        'Fringe contrast': 0.071298357213623778,
        'Fringe sampling (px)': 3.7902017241882331,
        'Carrier frequency (1 / nm)': 0.28685808994016415}
        """

        # Testing match of navigation axes of reference and self
        # (exception: reference nav_dim=1):

        # Parsing sideband position:
        (sb_position,
         sb_position_temp) = _parse_sb_position(self, None, sb_position, sb,
                                                high_cf, parallel)

        # Calculate carrier frequency in 1/px and fringe sampling:
        fourier_sampling = 1. / np.array(self.axes_manager.signal_shape)
        if single_values:
            carrier_freq_px = calculate_carrier_frequency(
                _first_nav_pixel_data(self),
                sb_position=_first_nav_pixel_data(sb_position),
                scale=fourier_sampling)
        else:
            carrier_freq_px = self.map(calculate_carrier_frequency,
                                       sb_position=sb_position,
                                       scale=fourier_sampling,
                                       inplace=False,
                                       ragged=False,
                                       show_progressbar=show_progressbar,
                                       parallel=parallel,
                                       max_workers=max_workers)
        fringe_sampling = np.divide(1., carrier_freq_px)

        ureg = UnitRegistry()
        try:
            units = ureg.parse_expression(
                str(self.axes_manager.signal_axes[0].units))
        except UndefinedUnitError:
            raise ValueError('Signal axes units should be defined.')

        # Calculate carrier frequency in 1/units and fringe spacing in units:
        f_sampling_units = np.divide(1., [
            a * b for a, b in zip(self.axes_manager.signal_shape, (
                self.axes_manager.signal_axes[0].scale,
                self.axes_manager.signal_axes[1].scale))
        ])
        if single_values:
            carrier_freq_units = calculate_carrier_frequency(
                _first_nav_pixel_data(self),
                sb_position=_first_nav_pixel_data(sb_position),
                scale=f_sampling_units)
        else:
            carrier_freq_units = self.map(calculate_carrier_frequency,
                                          sb_position=sb_position,
                                          scale=f_sampling_units,
                                          inplace=False,
                                          ragged=False,
                                          show_progressbar=show_progressbar,
                                          parallel=parallel,
                                          max_workers=max_workers)
        fringe_spacing = np.divide(1., carrier_freq_units)

        # Calculate carrier frequency in mrad:
        try:
            ht = self.metadata.Acquisition_instrument.TEM.beam_energy
        except BaseException:
            raise AttributeError("Please define the beam energy."
                                 "You can do this e.g. by using the "
                                 "set_microscope_parameters method.")

        momentum = 2 * constants.m_e * constants.elementary_charge * ht * \
            1000 * (1 + constants.elementary_charge * ht *
                    1000 / (2 * constants.m_e * constants.c ** 2))
        wavelength = constants.h / np.sqrt(momentum) * 1e9  # in nm
        carrier_freq_quantity = wavelength * \
            ureg('nm') * carrier_freq_units / units * ureg('rad')
        carrier_freq_mrad = carrier_freq_quantity.to('mrad').magnitude

        # Calculate fringe contrast:
        if fringe_contrast_algorithm == 'fourier':
            if single_values:
                fringe_contrast = estimate_fringe_contrast_fourier(
                    _first_nav_pixel_data(self),
                    sb_position=_first_nav_pixel_data(sb_position),
                    apodization=apodization)
            else:
                fringe_contrast = self.map(estimate_fringe_contrast_fourier,
                                           sb_position=sb_position,
                                           apodization=apodization,
                                           inplace=False,
                                           ragged=False,
                                           show_progressbar=show_progressbar,
                                           parallel=parallel,
                                           max_workers=max_workers)
        elif fringe_contrast_algorithm == 'statistical':
            if single_values:
                fringe_contrast = _first_nav_pixel_data(
                    self).std() / _first_nav_pixel_data(self).mean()
            else:
                fringe_contrast = _estimate_fringe_contrast_statistical(self)
        else:
            raise ValueError(
                "fringe_contrast_algorithm can only be set to fourier or statistical."
            )

        return {
            'Fringe contrast': fringe_contrast,
            'Fringe sampling (px)': fringe_sampling,
            'Fringe spacing ({:~})'.format(units.units): fringe_spacing,
            'Carrier frequency (1/px)': carrier_freq_px,
            'Carrier frequency ({:~})'.format((1. / units).units):
            carrier_freq_units,
            'Carrier frequency (mrad)': carrier_freq_mrad
        }
예제 #12
0
def get_coreshield_particlegroup(settings_input,
                                 DISTGEN_INPUT_FILE,
                                 verbose=False,
                                 distgen_verbose=False):
    unit_registry = UnitRegistry()
    settings = copy.copy(settings_input)

    all_settings = yaml.safe_load(open(DISTGEN_INPUT_FILE))
    for k, v in settings.items():
        all_settings = update_nested_dict(all_settings, {k: v},
                                          verbose=False,
                                          create_new=True)

    if ('coreshield' not in all_settings):
        raise ValueError('No coreshield settings specificed.')

    coreshield_settings = all_settings['coreshield']

    if ('n_core' in coreshield_settings):
        n_core = coreshield_settings['n_core']
    else:
        raise ValueError('Please specify n_core.')

    if ('n_shield' in coreshield_settings):
        n_shield = coreshield_settings['n_shield']
    else:
        raise ValueError('Please specify n_shield.')

    if ('core_charge_fraction' in coreshield_settings):
        raise ValueError(
            'core_charge_fraction is deprecated, please use core_charge instead.'
        )
    if ('core_charge' not in coreshield_settings):
        if ('final_charge' in all_settings):
            if (verbose):
                print('Defaulting to core charge = final charge.')
            core_charge = all_settings['final_charge'][
                'value'] * unit_registry.parse_expression(
                    all_settings['final_charge']['units'])
            core_charge_fraction = core_charge.to(
                all_settings['total_charge']
                ['units']).magnitude / all_settings['total_charge']['value']
        else:
            if (verbose):
                print('Defaulting to half of the charge in the core.')
            core_charge_fraction = 0.5
    else:
        core_charge = coreshield_settings['core_charge'][
            'value'] * unit_registry.parse_expression(
                coreshield_settings['core_charge']['units'])
        core_charge_fraction = core_charge.to(
            all_settings['total_charge']
            ['units']).magnitude / all_settings['total_charge']['value']
    if (core_charge_fraction < 0.0 or core_charge_fraction > 1.0):
        core_charge_fraction = 0.5
        if (verbose):
            print('Invalid core charge fraction, defaulting to 0.5')

    sigma_xy = None
    if ('cathode:sigma_xy' in settings):
        raise ValueError(
            'cathode:sigma_xy is deprecated, please specify value and units instead.'
        )
    if ('cathode:sigma_xy:value' in settings
            and 'cathode:sigma_xy:units' in settings):
        sigma_xy_value = settings.pop(
            'cathode:sigma_xy:value'
        )  # Remove from dictionary so that calls to get_cathode_particlegroup do not see it
        sigma_xy_units = settings.pop(
            'cathode:sigma_xy:units'
        )  # Remove from dictionary so that calls to get_cathode_particlegroup do not see it
        sigma_xy = sigma_xy_value * unit_registry.parse_expression(
            sigma_xy_units)
        sigma_xy = sigma_xy.to('m').magnitude  # convert to meters

    PG = get_cathode_particlegroup(settings, DISTGEN_INPUT_FILE, verbose=False)

    sx = PG['sigma_x']
    sig_ratio = 1.0
    if (sigma_xy is not None):
        sig_ratio = sigma_xy / sx
    r_i = np.argsort(PG.r)
    r = PG.r[r_i]
    w = PG.weight[r_i]
    w_sum = np.cumsum(w)
    n_core_orig = np.argmax(w_sum > core_charge_fraction * w_sum[-1])
    n_shield_orig = len(w) - n_core_orig
    r_cut = r[n_core_orig]

    if (n_core is None):
        n_core = n_core_orig

    if (n_shield is None):
        n_shield = n_shield_orig

    settings_1 = copy.copy(settings)
    settings_1['r_dist:sigma_xy:value'] = sig_ratio * settings[
        'r_dist:sigma_xy:value']
    settings_1['r_dist:truncation_radius_right:value'] = sig_ratio * settings[
        'r_dist:truncation_radius_right:value']
    settings_1['r_dist:truncation_radius_left:value'] = sig_ratio * r_cut
    settings_1['r_dist:truncation_radius_left:units'] = 'm'
    settings_1['n_particle'] = n_shield
    settings_1['total_charge:value'] = (
        1.0 - core_charge_fraction) * settings['total_charge:value']

    settings_2 = copy.copy(settings)
    settings_2['r_dist:sigma_xy:value'] = sig_ratio * settings[
        'r_dist:sigma_xy:value']
    settings_2['r_dist:truncation_radius_right:value'] = sig_ratio * r_cut
    settings_2['r_dist:truncation_radius_right:units'] = 'm'
    settings_2['r_dist:truncation_radius_left:value'] = sig_ratio * settings[
        'r_dist:truncation_radius_left:value']
    settings_2['n_particle'] = n_core
    settings_2['total_charge:value'] = core_charge_fraction * settings[
        'total_charge:value']

    PG_shield = get_cathode_particlegroup(settings_1,
                                          DISTGEN_INPUT_FILE,
                                          verbose=False,
                                          id_start=n_core + 1)
    PG_core = get_cathode_particlegroup(settings_2,
                                        DISTGEN_INPUT_FILE,
                                        verbose=False,
                                        id_start=1)

    PG = PG_core + PG_shield

    if (verbose):
        if (sigma_xy is not None):
            print(
                f'Rescaling sigma_xy from {sx} -> {sigma_xy}. Achieved: {PG["sigma_x"]}'
            )

    return PG