.. _showapi.level0_index: :mod:`showapi.level0` ===================== .. module:: showapi.level0 :synopsis: SHOW Level 0 input. .. moduleauthor:: Nick Lloyd .. sectionauthor:: Nick Lloyd **Source code:**: `showapi.level0` This module is used to read and manipulate SHOW level 0 data. The general processing flow is 1. Create an instance of :class:`~showapi.level0.showlevel0.SHOWLevel0` for the desired instrument and desired data folders. 2. Use the instance of :class:`~showapi.level0.showlevel0.SHOWLevel0` to create an instance :class:`~showapi.level0.l0algorithms.L0Algorithms`. 3. Apply processing algorithms from methods of both :class:`~showapi.level0.l0algorithms.L0Algorithms` and :class:`~showapi.level0.showlevel0.SHOWLevel0` to manipulate the images in the :class:`~showapi.level0.showlevel0.SHOWLevel0` object. The :class:`~showapi.level0.showlevel0.SHOWLevel0` object sorts all images in to an internal dictionary keyed by exposure time expressed in micro-seconds. For each unique exposure time there is one instance of class :class:`~showapi.level0.level0imagearray.Level0_ImageCollection` that stores all the images at that exposure time. Conceptually, each image record is stored in class :class:`~showapi.level0.level0imagearray.Level0_ImageCollection` as a list of :class:`~showapi.level0.level0imagearray.Level0_Image` which can be indexed or iterated over using standard Python constructs. SHOWLevel0 ---------- A class to manage Level 0 file I/O and a few processing operations. SHOW Level 0 objects are created for specific instruments and will load configuration parameters accordingly. The class implements indexing and iterating options for easier implementation. See the :ref:`levelio_examples` at the bottom of the page - :meth:`~showapi.level0.showlevel0.SHOWLevel0.__init__` - :meth:`~showapi.level0.showlevel0.SHOWLevel0.algorithms` - :meth:`~showapi.level0.showlevel0.SHOWLevel0.append_collection` - :meth:`~showapi.level0.showlevel0.SHOWLevel0.average_images` - :meth:`~showapi.level0.showlevel0.SHOWLevel0.image_array` - :meth:`~showapi.level0.showlevel0.SHOWLevel0.instrument_name` - :meth:`~showapi.level0.showlevel0.SHOWLevel0.integration_times` - :meth:`~showapi.level0.showlevel0.SHOWLevel0.make_dark_current` - :meth:`~showapi.level0.showlevel0.SHOWLevel0.make_flat_field` - :meth:`~showapi.level0.showlevel0.SHOWLevel0.read_level0` .. autoclass:: showapi.level0.showlevel0.SHOWLevel0 :members: .. automethod:: __init__ L0Algorithms ------------ A collection of algorithms that can be applied to Level0 data - :meth:`~showapi.level0.l0algorithms.L0Algorithms.apodized_interferogram_with_zero_bias` - :meth:`~showapi.level0.l0algorithms.L0Algorithms.interferogram_subwindow` - :meth:`~showapi.level0.l0algorithms.L0Algorithms.interferogram_to_spectrum` - :meth:`~showapi.level0.l0algorithms.L0Algorithms.fit_cosine_with_gaussian_envelope` - :meth:`~showapi.level0.l0algorithms.L0Algorithms.rms_frequency_error_from_rms_spatial_error` - :meth:`~showapi.level0.l0algorithms.L0Algorithms.rms_signal_error_from_detector_specs` - :meth:`~showapi.level0.l0algorithms.L0Algorithms.subwindow_array` .. autoclass:: showapi.level0.l0algorithms.L0Algorithms :members: Level0_Image ------------ A level 0 record. .. autoclass:: showapi.level0.level0imagearray.Level0_Image :members: Level0_ImageCollection ---------------------- A collection of Level 0 records. The class implements indexing and iterating options for easy implementation. The class only loads image headers when scanning a directory and defers loading image data until required. This works well if you scan through the array of images once but is not so good if you scan through the array multiple times. .. autoclass:: showapi.level0.level0imagearray.Level0_ImageCollection :members: Level1_Spectra -------------- A level 1 record containing the SHOW-SHS spectrum .. autoclass:: showapi.level0.l0algorithms.Level1_Spectra :members: ImageStats ---------- A namedtuple that holds statistics on a collection of Level 0 images, .. autoclass:: showapi.level0.level0imagearray.ImageStats ComplianceTests --------------- The class that maanges the SHOW compliance tests .. autoclass:: showapi.compliancetests.compliancetests.ComplianceTests :members: .. _levelio_examples: Examples -------- A few examples Example 1, Simple Iteration ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Iterating over the exposure times in :class:`~showapi.level0.showlevel0.SHOWLevel0` and the images in :class:`~showapi.level0.level0imagearray.Level0_ImageCollection` using *old-school*, simple indexing:: import argcommon.mjd import showapi.level0 l0 = showapi.level0.SHOWLevel0('er2_2017', r'C:\sdcard0\images\2016-11-28_16-27') # load in all images in this directory for exposuret in l0.integration_times(): # Iteratte over the list of exposure times in the SHowLevel0 object imagecoll = l0[exposuret] # Get the list of images for this exposure time for i in range( len(imagecoll) ): # for each image in the collection record = imagecoll[i] # get the image record using the numerical index mjd = argcommon.mjd.MJD(record.mjd) # print stats on this record print("Time = %s" % (mjd.AsUTCStr(True))) print('Exposure time = %8.3f ms' % (record.exposure_time / 1000.0,)) Example 2, Modern Iteration ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Exactly the same functional code as example 1 but recast into a more modern iterating style using the iterator support built into the objects:: import argcommon.mjd import showapi.level0 l0 = showapi.level0.SHOWLevel0('er2_2017', r'C:\sdcard0\images\2016-11-28_16-27') # load in all images in this directory for imagecoll in l0: # Iterate over the collection of images at each exposure time for record in imagecoll: # for each image in the collection mjd = argcommon.mjd.MJD(record.mjd) # print stats on this record print("Time = %s" % (mjd.AsUTCStr(True))) print('Exposure time = %8.3f ms' % (record.exposure_time / 1000.0,)) Example 3 ^^^^^^^^^ A more extended example that uses the modern iterating style of example 2 but also creates an instance of :class:`~showapi.level0.l0algorithms.L0Algorithms` and applies a method to the record before generating statistics. In summary this code execute sthe following steps, 1. Read a directory of Level 0 images using the *er2_2017* instrument configuration. 2. Create the :class:`~showapi.level0.l0algorithms.L0Algorithms` object and select the useful sub-window imaging region. 3. Generate image min/max statistics 4. Print image header values 5. Plot the image data :: import numpy as np import matplotlib.pyplot as plt import argcommon.mjd import showapi.level0 l0 = showapi.level0.SHOWLevel0('er2_2017', r'C:\sdcard0\images\2016-11-28_16-27') # load in all images in this directory algol = l0.algorithms() # get the level 0 algorithm object N = 0 # Reset the total number of images read in for imagecoll in l0: # Get the collection of images at each exposure time N += len(imagecoll) # Count the total number of images at this exposure for record in imagecoll: # for each record at this exposure time image, error, bounds = algol.interferogram_subwindow(record) # get the sub-window data, only keeps the active area of detector maxsig = np.max(image) # get the maximum signal in the image minsig = np.min(image) # get the minimum signal in the image p2 = np.percentile(record.image, 2) # get the 2 percent percentile value p98 = np.percentile(record.image, 98) # get the 98 percent percentile value # mjd = argcommon.mjd.MJD(record.mjd) # print stats on this record print("Time = %s" % (mjd.AsUTCStr(True))) print("Min, Max, 2%%, 98%% = %7.1f, %7.1f, %7.1f, %7.1f" % (minsig, maxsig, p2, p98)) print('Exposure time = %8.3f ms' % (record.exposure_time / 1000.0,)) print('High Gain = %d' % (int(record.high_gain, ))) print('Sensor Temp = %7.2f C' % (record.sensor_temp,)) print('Set Point Temp = %7.2f C' % (record.setpoint_temp,)) print('PCB temp = %7.2f C' % (record.sensor_pcb_temp,)) print('Top Interferom Temp = %7.2f C' % (record.top_intferom_temp,)) print('Bottom Interferom Temp = %7.2f C' % (record.bottom_intferom_temp,)) print('Opto Box Temp = %7.2f C' % (record.optobox_temp,)) print('Q7 Temp = %7.2f C' % (record.Q7_temp,)) print("--------------------------------------------------------------") plt.imshow( image, clim=[p2,p98], origin='lower') # plot this image, use the 2nd and 98 percentiles for color limits plt.colorbar() # show a colorbar plt.show() # and show the image. Stops execution until user deletes the figure print() print('Finished printing %d records'%(N,)) .. _xiphos_directory_format: XIPHOS directory format ----------------------- The SHOW Level 0 file I/O code uses a custom decoder to read the XIPHOS/OWL640 files and directories generated by the SHOW-SHS instrument. The custom decoder expects the data directories to be laid out in a standard format and it is essential users maintain this structure. The directory structure follows the format:: .... sdcard0 --+-- images ------ 2016-11-28_16-27 |-- telemetry --- 2016-11-28_16-27 In this case, the user would select directory ``.... sdcard0/images/2016-11-28_16-27`` as the directory given to the constructor of :class:`~showapi.level0.showlevel0.SHOWLevel0` when using an instrument name of *er2_2017*. The OWL640 decoding code will automatically step up two folders into ``sdcard0`` and down two folders into directory ``telemetry/2016-11-28_16-27`` to read the corresponding telemetry files. The OWL640 format linearly interpolates variables stored in the telemetry files to the time of each image and stores the result in the image header. Variables not found or not properly interpolated will be set to NaN.