RIMSEval Processor and Utilities

CRDFileProcessor: Processor class

class rimseval.processor.CRDFileProcessor(fname: Path)

Process a CRD file in this class, dead time corrections, etc.

Computationally expensive routines are sourced out into processor_utils.py for jitting.

Example:
>>> my_file = Path("crd_files/my_file.crd")
>>> crd = CRDFileProcessor(my_file)  # open the file
>>> crd.spectrum_full()  # create a spectrum
adjust_overlap_background_peaks(other_peaks: bool = False) None

Routine to adjust overlaps of backgrounds and peaks.

By default, this routine checks if the backgrounds overlap with the peaks they are defined for and removes any background values that interfer with the peak that is now defined. It also checks for overlap with other peaks and if it finds any, warns the user. If other_peaks is set to True, the routine will not warn the user, but automatically correct these bad overlaps.

Parameters:

other_peaks – Automatically correct for overlap with other peaks?

Returns:

None

apply_individual_shots_filter(shots_rejected: ndarray)

Routine to finish filtering for individual shots.

This will end up setting all the data. All routines that filter shots only have to provide a list of rejected shots. This routine does the rest, including. the handling of the data if packages exist.

ToDo: rejected shots should be stored somewhere.

Parameters:

shots_rejected – Indices of rejected shots.

calculate_applied_filters()

Check for which filters are available and then recalculate all from start.

dead_time_correction(dbins: int) None

Perform a dead time correction on the whole spectrum.

If packages were set, the dead time correction is performed on each package individually as well. :param dbins: Number of dead bins after original bin (total - 1).

Warning.warn:

There are no shots left in the package. No deadtime correction can be applied.

property def_backgrounds: Tuple[List[str], ndarray]

Background definitions for integrals.

The definitions consist of a tuple of a list and a np.ndarray. The list contains first the names of the integrals. The np.ndarray then contains in each row the lower and upper limit in amu of the peak that needs to be integrated.

Note

The format for defining backgrounds is the same as the format for defining integrals, except that peaks can occur multiple times for multiple backgrounds.

Returns:

Background definitions.

Raises:

ValueError – Data Shape is wrong

Example:
>>> data = CRDFileProcessor("my_data.crd")
>>> peak_names = ["54Fe", "54Fe"]
>>> peak_limits = np.array([[53.4, 53.6], [54.4, 54.6]])
>>> data.def_integrals = (peak_names, peak_limits)
property def_integrals: Tuple[List[str], ndarray]

Integral definitions.

The definitions consist of a tuple of a list and a np.ndarray. The list contains first the names of the integrals. The np.ndarray then contains in each row the lower and upper limit in amu of the peak that needs to be integrated. If backgrounds overlap with the peaks themselves, they will be automatically adjusted.

Returns:

Integral definitions.

Raises:
  • ValueError – Data Shape is wrong

  • ValueError – More than one definition exist for a given peak.

Example:
>>> data = CRDFileProcessor("my_data.crd")
>>> peak_names = ["54Fe", "64Ni"]
>>> peak_limits = np.array([[53.8, 54.2], [63.5, 64.5]])
>>> data.def_integrals = (peak_names, peak_limits)
property def_mcal: ndarray

Mass calibration definitions.

Returns:

Mass calibration definitions. The columns are as following: 1st: ToF (us) 2nd: Mass (amu)

Raises:
  • TypeError – Value is not a numpy ndarray

  • ValueError – At least two parameters must be given for a mass calibration.

  • ValueError – The array is of the wrong shape.

filter_max_ions_per_pkg(max_ions: int) None

Filter out packages with too many ions.

Note

Only run more than once if filtering out more. Otherwise, you need to reset the dataset first.

Parameters:

max_ions – Maximum number of ions per package.

Raises:
  • ValueError – Invalid range for number of ions.

  • OSError – No package data available.

filter_max_ions_per_shot(max_ions: int) None

Filter out shots that have more than the max_ions defined.

Note

Only run more than once if filtering out more. Otherwise, you need to reset the dataset first.

Parameters:

max_ions – Maximum number of ions allowed in a shot.

Raises:

ValueError – Invalid range for number of ions.

filter_max_ions_per_time(max_ions: int, time_us: float) None

Filter shots with >= max ions per time, i.e., due to ringing.

Parameters:
  • max_ions – Maximum number of ions that is allowed within a time window.

  • time_us – Width of the time window in microseconds (us)

filter_max_ions_per_tof_window(max_ions: int, tof_window: ndarray) None

Filer out maximum number of ions in a given ToF time window.

Parameters:
  • max_ions – Maximum number of ions in the time window.

  • tof_window – The time of flight window that the ions would have to be in. Array of start and stop time of flight (2 entries).

Raises:

ValueError – Length of tof_window is wrong.

filter_pkg_peirce_countrate() None

Filter out packages based on Peirce criterion for total count rate.

Fixme: This needs more thinking and testing Now we are going to directly use all the integrals to get the sum of the counts, which we will then feed to the rejection routine. Maybe this can detect blasts.

Warning

Running this more than once might lead to weird results. You have been warned!

integrals_calc(bg_corr=True) None

Calculate integrals for data and packages (if present).

The integrals to be set per peak are going to be set as an ndarray. Each row will contain one entry in the first column and its associated uncertainty in the second.

Parameters:

bg_corr – If false, will never do background correction. Otherwise (default), background correction will be applied if available. This is a toggle to switch usage while leaving backgrounds defined.

Raises:
  • ValueError – No integrals were set.

  • ValueError – No mass calibration has been applied.

integrals_calc_delta() None

Calculate delta values for integrals and save them in class.

This routine uses the iniabu package to calculate delta values for defined integrals. It reads the peak names and calculates delta values for isotopes that can be understood iniabu, and calculates the delta values with respect to the major isotope. These values are then saved to the class as integrals_delta and integrals_delta_pkg, if packages were defined. Uncertainties are propagated according to Gaussian error propagation. The format of the resulting arrays are identical to the integrals and integrals_pkg arrays.

Raises:

ValueError – No integrals were calculated.

property integrals_overlap: bool

Check if any of the integrals overlap.

Returns:

Do any integrals overlap?

Example:
>>> data = CRDFileProcessor("my_data.crd")
>>> peak_names = ["54Fe", "64Ni"]
>>> peak_limits = np.array([[53.8, 54.2], [63.5, 64.5]])
>>> data.def_integrals = (peak_names, peak_limits)
>>> data.integrals_overlap
False
mass_calibration() None

Perform a mass calibration on the data.

Let m be the mass and t the respective time of flight. We can then write:

\[t \propto \sqrt[a]{m}\]

Usually it is assumed that $a=2$, i.e., that the square root is taken. We don’t have to assume this though. In the generalized form we can now linearize the mass calibration such that:

\[\log(m) = a \log(t) + b\]

Here, \(a\) is, as above, the exponent, and \(b\) is a second constant. With two values or more for \(m\) and \(t\), we can then make a linear approximation for the mass calibration \(m(t)\).

Raises:

ValueError – No mass calibration set.

property name

Get the name of the CRD file.

optimize_mcal(offset: float = None) None

Take an existing mass calibration and finds maxima within a FWHM.

This will act on small corrections for drifts in peaks.

Parameters:

offset – How far do you think the peak has wandered? If None, it will be set to the FWHM value.

packages(shots: int) None

Break data into packages.

Parameters:

shots – Number of shots per package. The last package will have the rest.

Raises:

ValueError – Number of shots out of range

property peak_fwhm: float

Get / Set the FWHM of the peak.

Returns:

FWHM of the peak in us.

run_macro(fname: Path) None

Run your own macro.

The macro will be imported here and then run. Details on how to write a macro can be found in the documentation.

Parameters:

fname – Filename to the macro.

sort_backgrounds() None

Sort all the backgrounds that are defined.

Takes the backgrounds and the names and sorts them by proton number (first order), then by mass (second order), and finally by start of the background (third order). All backgrounds that cannot be identified with a clear proton number are sorted in at the end of the second order sorting, and then sorted by starting mass. If no backgrounds are defined, this routine does nothing.

Example:
>>> crd.def_backgrounds
["56Fe", "54Fe"], array([[55.4, 55.6], [53.4, 53.6]])
>>> crd.sort_backgrounds()
>>> crd.def_backgrounds
["54Fe", "56Fe"], array([[53.4, 53.6], [55.4, 55.6]])
sort_integrals(sort_vals: bool = True) None

Sort all the integrals that are defined by mass.

Takes the integrals and the names and sorts them by proton number (first order), then by mass (second order). All integrals that cannot be identified with a clear proton number (e.g., molecules) are sorted in at the end of the primary sorting, then sorted by mass. The starting mass of each integral is used for sorting. If no integrals are defined, this routine does nothing.

Parameters:

sort_vals – Sort the integrals and integral packages? Default: True

Example:
>>> crd.def_integrals
["Fe-56", "Ti-46"], array([[55.8, 56.2], [45.8, 46.2]])
>>> crd.sort_integrals()
>>> crd.def_integrals
["Ti-46", "Fe-56"], array([[45.8, 46.2], [55.8, 56.2]])
spectrum_full() None

Create ToF and summed ion count array for the full spectrum.

The full spectrum is transfered to ToF and ion counts. The spectrum is then saved to: - ToF array is written to self.tof - Data array is written to self.data

Warnings:

Time of Flight and data have different shape

spectrum_part(rng: Tuple[Any] | List[Any]) None

Create ToF for a part of the spectra.

Select part of the shot range. These ranges will be 1 indexed! Always start with the full data range.

Parameters:

rng – Shot range, either as a tuple (from, to) or as a tuple of multiple ((from1, to1), (from2, to2), …).

Raises:
  • ValueError – Ranges are not defined from, to where from < to

  • ValueError – Tuples are not mutually exclusive.

  • IndexError – One or more indexes are out of range.

property timestamp: datetime

Get the time stamp when the recording was started.

Returns:

Timestamp of the CRD file.

Example:
>>> crd = CRDFileProcessor(Path("my_file.crd"))
>>> crd.timestamp
datetime.datetime(2021, 7, 10, 11, 41, 13)
property us_to_chan: float

Conversion factor for microseconds to channel / bin number.

Returns:

Conversion factor