experiments.show_spectrum module¶
Providing the “Show Spectrum” experiment. It displays the (linearized) intensities on the MCT detector averaged over the amount of samples that should be acquired. The unit of the intensity, typically some kind of energy, is determined by the linearization and in which unit the reference data for that linearization was measured. Additionally it displays the standard deviation of the pseudo shot to shot difference signal for each pixel. (It is called pseudo because the sample - if there is any - is not being pumped. This implies that there should the resulting difference signal should be 0.)
The “Show Spectrum” experiment is mainly used to adjust the laser setup and the OPAs. This includes optimizing for stability, moving the wavelength of the OPAs and optimizing the alignment of the beams onto the detector.
Note
This is the only experiment that does not use a secondary processing class. It would be unnecessarily complicated to pass data from primary processing to secondary processing just to calculate standard deviations.
Step by Step Algorithm:¶
Acquisition:
Preallocate dictionary (data container) which will contain data and information about scan index, delay index etc.
Start the ADC task (in later experiments this was done differently. See the source code for further details)
Read the data from the ADC
Place data into dictionary and hand over to primary processing
Primary Processing:
Preallocate arrays for data and weights
Subtract background from raw data (dark noise)
Linearize response of pixels
Calculate average intensity for each pixel
Since for show spectrum we are only interested in the intensities, the data preparation for plotting is already done here
Calculate the standard deviation of the intensities
Calculate transmission, or more precisely, relative intensity (probe intensity / reference intensity) for each laser shot for each pixel pair
Calculate the pseudo shot to shot difference signal (pseudo because the sample - if there is any - is not being pumped and thus no chopper is being used) and its statistical information
Put this information into data container and hand it over to Pyqtplotting thread
Calculate the numbers which are displayed in the “statistics box” on the GUI
Save data (and raw data) if respective checkboxes on GUI were checked
Pyqt Plotting:
Remove old plots
Setup the plot that displays:
Average intensities for each pixel
Standard deviation of intensities times 5 as errorbars
Standard deviation of pseudo shot to shot difference spectrum
Plot the plots for the first time
Update plots
Saving:
programming data dimension: [(2 ([0] is current average scan, [1] is last single scan), n_pixels)] saving dimension: [(n_pixels)] raw data dimension: [(n_channels, samples_to_acquire)]
Folder Structure¶
scans/ contains the collected data for each scan in the dimensions which “saving dimension” suggests.
The data in /averaged_data is averaged equally. It contains the non normalized averaged intensities.
The /figure folder is currently empty. It is possible to implement plotting of figures which are saved here while the experiment is running. This is however not implemented yet.
The /hardware config folder holds every file which contains hardware configuration parameters. This folder is a compressed copy of the hardware configuration folder in the software’s directory. Here it is possible to look up the ADC configuration to obtain what channel was connected to which hardware element (e.g. chopper - ai78). It is also possible to obtain the R-2R values, the FPAS configuration, the linearization parameters, etc.
The /raw data folder is in the experiments directory only if the “save raw data” checkbox on the GUI was checked. It contains the raw (unedited… as raw as it can get) data. Basically, the voltages which the ADC measured for each channel. The dimensions are as “raw data dimensions” suggests.
The background.npy file is a copy of the most recently collected dark noise background of the MCT detector array. It corrects for dark noise. If no new background was collected before the experiment was started the code will use the latest available background and display a warning in the log.
setupinfo.txt is a ReadMe file that contains the most relevant experimental parameters at first glance. Additionally, the user can decide to write a comment in the readme editor of the GUI. The content of this is written to the notes.txt file.
username/
├── date1_experimentname1_000/
│ ├── averaged_data
│ │ └── date1_experimentname1_000.npy
│ ├── figures
│ ├── hardware config
│ ├── raw data
│ │ ├── s000000_date1_experimentname1_000_raw.npy
│ │ ├── ...
│ │ └── s000099_date1_experimentname1_000_raw.npy
│ ├── scans
│ │ ├── s000000_date1_experimentname1_000.npy
│ │ ├── ...
│ │ └── s000099_date1_experimentname1_000.npy
│ ├── setupinfo_date1_experimentname1_000.txt
│ ├── notes_date1_experimentname1_000.txt
│ └── background_date1_experimentname1_000.npy
├── date1_experimentname1_001/
├── date2_experimentname1_000/
└── date2_experimentname2_000/
-
class
Acquisition(adc: analog_digital_converter.AnalogDigitalConverter, spectrometer: triax.Triax, acq_queue)[source]¶ Bases:
threading.ThreadAcquisition class (python multithreaded). This is where the actual experiment is conducted.
This class is used to control the hardware devices required for the experiment. The sole purpose of it is to collect the data according to the parameters specified for the experiment by moving the delay stages, opening and closing shutters etc.
A dictionary which will contain data and other information (scan index etc.) is instantiated here. The acquisition class passes the collected information (raw data, scan index etc.) to the primary processing class.
Note
No data processing beyond what is required to conduct the experiment should be implemented in this class. The rationale behind this is to minimize down time/ maximize laser time. Data processing costs computation time and will, generally speaking, slow down the measurement process because the computer is busy while the rest of the hardware is idle. If implemented correctly the data processing could be carried out while the data acquisition is waiting for all data to become available. But even in this scenario the problem that the data processing takes longer than the acquisition time can occur and is thus best avoided through parallelisation.
The reason why this class is a child of the threading module instead of the multiprocessing module is that to use multiprocessing all objects passed to the function must be picklable. This is not the case for some of the objects interfacing with the hardware (e.g. ADC). In an ideal scenario the acquisition too, would run in its own process seperated from the GUI thread but this would only be possible with major restructuring of the software.
- Parameters
adc (ADC) – Analog to digital converter hardware object which is used to communicate with and read data from the ADC.
spectrometer (Spectrometer) – Spectrometer/Triax hardware class which grants functionality to control the triax spectrometer. Needed to obtain e.g. wavenumber axis etc.
acq_queue (Queue) – Multiprocessing queue object that the acquisition thread uses to pass data to the primary processing process.
-
run()[source]¶ Method representing the thread’s activity.
You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.
-
class
MplPlotting(mpl_widget, adc: analog_digital_converter.AnalogDigitalConverter, plot_queue)[source]¶ Bases:
threading.ThreadDeprecated. Works but is too slow for our purposes.
-
run()[source]¶ Method representing the thread’s activity.
You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.
-
-
class
PrimaryProcessing(acq_queue: multiprocessing.context.BaseContext.Queue, plot_queue: multiprocessing.context.BaseContext.Queue, info_queue: multiprocessing.context.BaseContext.Queue, processing_queue: multiprocessing.context.BaseContext.Queue, pixel_idx: numpy.ndarray, probe_pixel_idx: numpy.ndarray, reference_pixel_idx: numpy.ndarray, prl: data_processing.PixelResponseLinearization, background_handler: save_data.Background, saver: Optional[save_data.SaveData] = None)[source]¶ Bases:
multiprocessing.context.ProcessPrimary processing class (python multiprocess). This class’ purpose is to process the raw data to a state where it can be saved onto the hard drive as npy (binary) files. Generally, background corrected intensities are saved. This is different from all other experiments, where background corrected transmissions (normalized intensities) are saved. Saving raw data yields npy files which contain what the ADC collects at each laser shot (intensities/voltages/ADC counts). After this class was executed the important data is saved. Even if the processes later on break, the data is secured and can be analysed in post processing. The primary processed data is handed over to the secondary processing process.
- Parameters
acq_queue (Queue) – Multiprocessing queue object that the acquisition thread uses to pass data to the primary processing process.
processing_queue (Queue) – Multiprocessing queue object that the primary processing process uses to pass data to the secondary processing process.
plot_queue (Queue) – Multiprocessing queue object that the primary processing process uses to pass data to the plot thread.
info_queue (Queue) – Multiprocessing queue object which is used to transfer/hand over information to lineEdits on GUI. Contains (if applicable) scan index, delay index, interleave index, values for statistics groupBox etc.
pixel_idx (ndarray) –
Array that contains the indices of the rows in the ADCs’ data that correspond to pixel input channels. These are specified in the “analog input configuration.json” for each laboratory and can be easily accessed with the attribute “pixel_idx” of the ADC.
shape: 1D
E.g.: (64) or (128)
probe_pixel_idx (ndarray) –
Array that contains the indices of the rows in the ADCs’ data that correspond to probe pixel input channels. These are specified in the “analog input configuration.json” for each laboratory and can be easily accessed with the attribute “probe_pixel_idx” of the ADC. It is highly relevant that the order the pixels are listed in this array match the order of the array in the reference_pixel_idx argument. This means that if reference pixel 3 is listed first in the other array here probe pixel 3 needs to be listed first as well and so on. Otherwise the intensities on the probe array are not going to be normalized correctly. For the plotting to work correctly the pixels also need to be listed in the order of the wavenumber axis array of the spectrometer.
shape: 1D
E.g.: (32) or (64)
reference_pixel_idx (ndarray) –
Array that contains the indices of the rows in the ADCs’ data that correspond to reference pixel input channels. These are specified in the “analog input configuration.json” for each laboratory and can be easily accessed with the attribute “reference_pixel_idx” of the ADC. It is highly relevant that the order the pixels are listed in this array match the order of the array in the probe_pixel_idx argument. This means that if probe pixel 10 is listed first in the other array here reference pixel 10 needs to be listed first as well and so on. Otherwise the intensities on the probe array are not going to be normalized correctly. For the plotting to work correctly the pixels also need to be listed in the order of the wavenumber axis array of the spectrometer.
shape: 1D
E.g.: (32) or (64)
index_dict (dict) – Dictionary that maps the names of the input channels to their corresponding row in the ADCs’ data as they are specified in the “analog input configuration.json” for each laboratory. I.e.: It contains the information which entries of the ADCs’ data array belong choppers, wobblers etc. This dictionary can be easily accessed with the attribute “index_dict” of the ADC.
prl (PRL) – Pixel response linearization object which grants the functionality to linearize raw data according to the linearization parameters specified in the corresponding pixel_linearization_fit_parameters.json file (for each lab).
background_handler (Background) – Instance of Background class which can access the most recently collected background. This background is later subtracted from the raw data as dark noise correction.
saver (SaveData) – Object that manages saving of data (including counts, weights, probe wavenumber axis etc.) into their respective directories. If None is passed, no data is going to be saved. If the raw data checkbox was checked on the GUI the savers raw data attribute is set to True and the raw data is saved automatically. Defaults to None.
-
class
PyqtPlotting(widget_pyqtgraph, adc: analog_digital_converter.AnalogDigitalConverter, plot_queue)[source]¶ Bases:
objectPyqt Plotting class (Qt multithreaded). This class is necessary for displaying plots on the GUI. PyQtGraph is used as the plotting engine. Generally the plots are set up first (type of plot, layout, title etc.). On the first run, the plots are drawn for the first time. Then the plots are updated every iteration. We update the same plot references every time to make it more efficient.
- Args:
widget_pyqtgraph (QWidget): WidgetPyqtgraph object on which the plots are going to be displayed. Has methods for plot manipulation (i.e. removal of plots, autoscale). adc (ADC): Analog to digital converter hardware object which is used to communicate with and read data from the ADC. plot_queue (Queue): Multiprocessing queue object that the primary processing process uses to pass data to the plot thread.
-
class
SecondaryProcessing(processing_queue: multiprocessing.context.BaseContext.Queue)[source]¶ Bases:
multiprocessing.context.ProcessIn the Show Spectrum experiment this process is not used.
Secondary processing class (python multiprocess). This class is used to process the data from the primary processing class such that it can be displayed on the GUI within plots and lineEdits. This generally implies (if applicable):
calculation of signals
calculation of statistics like standard deviation of intensities and shot to shot standard deviation of signal
interpolation for 2D / heatmap plots (see comments in code why this is necessary)
Fourier transform and phasing for time domain data
This data is handed over to the plotting thread.
Note
The feature of saving figures/plots to the hard drive should be implemented here if it is needed.
- Parameters
processing_queue (Queue) – Multiprocessing queue object that the primary processing process uses to pass data to the secondary processing process.
-
class
ShowSpectrum(widget_pyqtgraph, adc: analog_digital_converter.AnalogDigitalConverter, prl: data_processing.PixelResponseLinearization, background_handler: save_data.Background, spectrometer: triax.Triax, info_queue: multiprocessing.context.BaseContext.Queue, saver: Optional[save_data.SaveData] = None)[source]¶ Bases:
object- Parameters
widget_pyqtgraph (QWidget) – WidgetPyqtgraph object on which the plots are going to be displayed. Has methods for plot manipulation (i.e. removal of plots, autoscale).
adc (ADC) – Analog to digital converter hardware object which is used to communicate with and read data from the ADC.
prl (PRL) – Pixel response linearization object which grants the functionality to linearize raw data according to the linearization parameters specified in the corresponding pixel_linearization_fit_parameters.json file (for each lab).
background_handler (Background) – Instance of Background class which can access the most recently collected background. This background is later subtracted from the raw data as dark noise correction.
spectrometer (Spectrometer) – Spectrometer/Triax hardware class which grants functionality to control the triax spectrometer. Needed to obtain e.g. wavenumber axis etc.
info_queue (Queue) – Multiprocessing queue object which is used to transfer/hand over information to lineEdits on GUI. Contains (if applicable) scan index, delay index, interleave index, values for statistics groupBox etc.
saver (SaveData) – Object that manages saving of data (including counts, weights, probe wavenumber axis etc.) into their respective directories. If None is passed, no data is going to be saved. If the raw data checkbox was checked on the GUI the savers raw data attribute is set to True and the raw data is saved automatically. Defaults to None.