I. How to: RawData

The main objective of this document is to present the RawData class without going into too much detail, but presenting all the most important skills in order to understand the philosophy of panaSKImg.

For this howto it is important to have looked at the documentation related with the configuration parameters (see previous howto on this serie). It is not necessary to go into detail, but to know their existence, format and what they are used for.

From the fits file to the RawData object

Here we will learn the representation of a fits file image within pysimdamicm. The data (i.e. the fits file image) is an instance of the RawData class, which represents our understanding of a CCD skipper image:

  • a well defined number of columns and rows
  • a fix number of skips
  • a set of different well defined regions: an active area, and overscan and prescan regions in rows and columns
  • a 2D array with the pixel-charge

Configuration parameters for RawData

There are a large set of parameters to properly interpret the data input. All of them have been introduced for the Config howto, see input section of the configuration JSON file. In short, we would have

  • Ncols
  • Nrows
  • Nskips
  • Npbin
  • Nsbin
  • axis_to_compress
  • id_col_end
  • id_col_start
  • id_row_end
  • id_row_start
  • id_skip_end
  • id_skip_start
  • correct_leach_bug
  • correct_polarity

Some of the will be explained again throughout this document.

Attributes of RawData

An instance of RawData will have several data members, the most important are:

image data member

This is created during instanciation containing all pixel charge values in a 3D array: (rows, cols, skips). The third dimensions for the skipper measurements. The image is therefore an array of dimension 3, where this thrid dimensiono corresponds to the k-th measure of the pixel in the position (y,x), i.e.

image[row,col,k]

mask_image_active_region

mask_image_overscan_cols, mask_image_overscan_rows

mask_image_prescan_cols, mask_image_prescan_rows

These are the 5 regions that any CCD image can have. Corresponds to the active region, the overscan in columns and rows (where no exposure time have been taken providing an snapshot of the baseline or pedestan of an image) and prescan in columns and rows (respectively).

These data members are created for method RawData.prepare_data being $\color{red}{\text{boolean arrays of dimension 2}}$ with shape number of rows per number of columns:

(Nrows,Ncols)

Note that all the data members has the same shape: they are just masks with True and False values, to define which pixels belongs to which region.

Along panaSKImg masked arrays will be used to select any of these regions. For instance, to compute the average pixel charge on the overscan on columns is as simple as

numpy.ma.array( RawData.image, mask=RawData.mask_image_overscan_cols).mean()

Index

In this howto there are two main sections:

  • Image as the instance of the RawData class

    • using the default configuration
    • using the configuration JSON file
  • Learn a little bit more about the data members of RawData, and how to get the mask for each region

In this howto we will use the CompressionSkipperProcess class to get the averaged class and play a little bit with the mask for the serveral regions.

This howto will only be done from a Python Interpreter, meaning that we will not use panaSKImg, since the main objective is to learn a little about the data structure as an instance of RawData.

Overview of this howto

  1. Load all modules needed for this howto
  2. Define which data to be used
  3. Instanciation of RawData

    • using default configuration file
    • uisng a configuration json file
  4. image data member

  5. Use of RawData for already compressed images (averaged image)
  6. Define CCCD regions: active area, overscan and prescan regions

0. Load all needed modules

In [1]:
%matplotlib inline

import pysimdamicm as ccd

import numpy as np
from matplotlib import pyplot as plt
Welcome to JupyROOT 6.14/06

2. Define which data to be used

The data we will use along this serie of How to notebooks is sotred in fits files format with a pattern file name Image_Am241_Source_27_XXX_fits being XXX the file number.

To access for instance to file number 25, we will use the function format as follows:

  1. define the main path where raw data is sotred: path_to_raw_data
  2. define an string with the pattern file name: img_pattern_file_name
  3. access to the file name by the concatenation of both strings: file_name
  4. use format to 'fill' the file number you are interested in
In [2]:
# where raw data is
path_to_raw_data = "/media/ncastello/WORK/damicm/compton/calidaq_backup/DataTaking/Am241/Run_55"

# patter file name
img_pattern_file_name = "Image_Am241_Source_55_{}.fits"

# absolute path to the file name
file_name = "{}/{}".format(path_to_raw_data,img_pattern_file_name)

# see how looks like the concatenation
print( file_name )
/media/ncastello/WORK/damicm/compton/calidaq_backup/DataTaking/Am241/Run_55/Image_Am241_Source_55_{}.fits

Note that, this string contains the symbol {} which is used to tell format where its inputs should be placed.

See that with an example: the name for file number 25 can be build as follows

In [3]:
print( "Name for file number 25 is: ", file_name.format(25) )
Name for file number 25 is:  /media/ncastello/WORK/damicm/compton/calidaq_backup/DataTaking/Am241/Run_55/Image_Am241_Source_55_25.fits

3. Instanciation of RawData

Loading a fits file using the BuilderRawData function

In this section we will learn how data from a fits file is structured as a RawData object.

The raw data file can be loaded by using the BuilderRawData function provided for pysimdamicm.io.rawdata. There are two parametrized constructors for this class:

  1. with only the input fits file name (file_name)
  2. with the input fits file name, and as a second argument, a dictionary to properly interpret the data recorded in the fits file (file_config).

With the former there is no information about how data is recorded on the fits file, and necessary information to properly interpret the data will be missed. Like for instance

  • where overscan starts and end or the same for the active area,
  • how many skips, and in which of the axis skips are taken
  • data taken bugs that should be corrected before starting the data processing
  • is the image inverted or not
  • ...

All this parameters can be defined in a dictionary, and pass to the contructor as a second argument (we will learn how to do that later on).

A way to see how looks like the contructor is by typing

In [4]:
help(ccd.io.rawdata.BuilderRawData)
Help on function BuilderRawData in module pysimdamicm.io.rawdata:

BuilderRawData(file_name, file_config=None)

3.1 Using the default configuration

Using the string file_name pointing to a fits file data, we can load this existing FITS file:

In [5]:
rdata = ccd.io.rawdata.BuilderRawData( file_name.format(25) )
Print INFO.
General info of the fits file
****************************************************************************
Filename: /media/ncastello/WORK/damicm/compton/calidaq_backup/DataTaking/Am241/Run_55/Image_Am241_Source_55_25.fits
No.    Name         Type      Cards   Dimensions   Format
  0  PRIMARY     PrimaryHDU      84   (17600, 150)   int16 (rescales to uint16)   
None
Displaying full header ext= 0
****************************************************************************
SIMPLE  =                    T / file does conform to FITS standard             
BITPIX  =                   16 / number of bits per data pixel                  
NAXIS   =                    2 / number of data axes                            
NAXIS1  =                17600 / length of data axis 1                          
NAXIS2  =                  150 / length of data axis 2                          
EXTEND  =                    T / FITS dataset may contain extensions            
COMMENT   FITS (Flexible Image Transport System) format is defined in 'Astronomy
COMMENT   and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H 
BZERO   =                32768 / offset data range to that of unsigned short    
BSCALE  =                    1 / default scaling factor                         
COMMENT This image was taken by a DAMIC UW CCD. The various settings used are st
COMMENT ored as keys in the FITS file.Processed by CCDDrone - Pitam Mitra @ UW. 
COMMENT If you have questions, please send them to pitamm@uw.edu                
CCDTYPE = 'SK      '           / CCD Type (DES or SK)                           
EXP     =                   3. / Exposure time (s)                              
NDCMS   =                   64 / Number of charge measurements                  
AMPL    = 'L       '           / Amplifier(s) used                              
COMMENT ASMFILE: Sequencer file used /home/Leach/CCDSequencer/firmware_super_seq
COMMENT uencer_Paolo_Aug2020_inverted.lod                                       
SUPERSE =                    1 / Super sequencer (SSeq) used?                   
INVRG   =                    0 / Is RG inverted                                 
HCKDIRN = 'U       '           / Serial register h-clock direction (SSEq only)  
VCKDIRN = '2       '           / Vertical clock direction (SSeq only)           
ITGTIME =                   5. / Integration time (SSeq only)                   
VIDGAIN =                    1 / Video gain                                     
ITGSPD  =                    0 / Integrator speed (0=slow, 1=fast)              
PRETIME =                  0.5 / Pedestal settling + video ADC refresh time     
POSTIME =                  0.5 / Signal settling time                           
DGWIDTH =                 0.24 / DG Width (SK only)                             
RGWIDTH =                 0.24 / Reset width (SK only)                          
OGWIDTH =                 0.24 / OG Width (SK only)                             
SWWIDTH =                 0.24 / SW Pulse Width (SK only)                       
HWIDTH  =                 0.24 / H-Clock Width (SK only)                        
HOWIDTH =                 0.24 / H-Clock overlap Width (SK only)                
VWIDTH  =                  20. / V-Clock Width (SK only)                        
VOWIDTH =                  20. / V-Clock overlap Width (SK only)                
NPBIN   =                    4 / Binning in the V-direction (parallel clocks)   
NSBIN   =                    4 / Binning in the H-direction (serial clocks)     
SECSTG  = 'UW2     '           / Second stage board revision (SSeq only)        
ONEVCKHI=                  1.5 / V1 clock Hi                                    
ONEVCKLO=                 -0.5 / V1 clock Lo                                    
TWOVCKHI=                  1.5 / V2 clock Hi                                    
TWOVCKLO=                 -0.5 / V2 clock Lo                                    
ONETGHI =                  1.5 / Transfer Gate SR1 Hi                           
ONETGLO =                 -0.5 / Transfer Gate SR1 Lo                           
TWOTGHI =                  1.5 / Transfer Gate SR2 Hi                           
TWOTGLO =                 -0.5 / Transfer Gate SR2 Lo                           
HUHI    =                   1. / U Serial Register H-Clocks Hi                  
HULO    =                 -2.5 / U Serial Register H-Clocks Lo                  
HLHI    =                   1. / L Serial Register H-Clocks Hi                  
HLLO    =                 -2.5 / L Serial Register H-Clocks Lo                  
ONERGHI =                  5.5 / Reset Gates on SR1 Hi                          
ONERGLO =                   3. / Reset Gates on SR1 Lo                          
TWORGHI =                   5. / Reset Gates on SR2 Hi                          
TWORGLO =                   3. / Reset Gates on SR2 Lo                          
ONESWHI =                  -3. / Summing Wells on SR1 Hi                        
ONESWLO =                 -11. / Summing Wells on SR1 Lo                        
TWOSWHI =                  -3. / Summing Wells on SR2 Hi                        
TWOSWLO =                  -9. / Summing Wells on SR2 Lo                        
ONEDGHI =                  -3. / DGs on SR1 Hi (SK only)                        
ONEDGLO =                 -11. / DGs on SR1 Lo (SK only)                        
TWODGHI =                  -4. / DGs on SR2 Hi (SK only)                        
TWODGLO =                  -8. / DGs on SR2 Lo (SK only)                        
ONEOGHI =                  -4. / OGs on SR1 Hi (SK only)                        
ONEOGLO =                 -11. / OGs on SR1 Lo (SK only)                        
TWOOGHI =                  -4. / OGs on SR2 Hi (SK only)                        
TWOOGLO =                  -9. / OGs on SR2 Lo (SK only)                        
BATTR   =                   5. / Battery box relay TTL Line                     
VDD1    =                 -19. / Vdd                                            
VDD2    =                 -19. / Vdd                                            
VIDOFFL =                 2200 / Video pedestal offset L                        
VIDOFFU =                 2200 / Video pedestal offset U                        
DRAIN1  =                -24.5 / Drain1 (Relevant to SK)                        
DRAIN2  =                -24.5 / Drain2 (Relevant to SK)                        
VREF1   =                  -7. / VRef                                           
VREF2   =                  -7. / VRef                                           
OPG1    =                 2.21 / OpG1 (Relevant to DES)                         
OPG2    =                 2.21 / OpG2 (Relevant to DES)                         
PROGSTRT= 'Sun Nov 15 23:31:53 2020' / Program start time                       
EXPSTART= 'Sun Nov 15 23:31:53 2020' / Exposure start time                      
RDSTRT  = 'Sun Nov 15 23:31:56 2020' / Readout start time                       
RDEND   = 'Sun Nov 15 23:32:34 2020' / Readout end time                         
MEXP    =          3005.961078 / Measured exposure time (ms)                    
MREAD   =         37318.667586 / Measured readout time (ms)                     
****************************************************************************
Summary: 

N. rows=150 columns=275 skips=64 
Image ndim:  2
Image shape: (150, 17600)
Image size:  2640000
Image dtype: uint16
****************************************************************************
Correction INFO. Correcting data for Leach bug:
 	 the first two column moved to the end,
 	 move one-row down (only the two last columns).

This will return an object from class FitsRawData. BuilderRawData is a general class that accepts different formats for the input data. For each format there is a class to properly read the input data.

In this example, the input file is recorded as a fits and BuilderRawData will return a FitsRawData object. A FitsRawData is the highest level component of the RawData structure, consisting of a serie of attributes (some of them coming from the header of the fits file, in this example) and a data array image containing the data of the image.

In [6]:
type(rdata)
Out[6]:
pysimdamicm.io.rawdata.FitsRawData

The Rawdata has a useful method Rawdata.info(), which summarizes the content of the loaded and semi-processed data fits file:

In [7]:
rdata.info()
 * active_region_cols = None 
 * active_region_rows = None 
 * ampl = L 
 * ampl_keyword = AMPL 
 * avg_output = /media/ncastello/WORK/damicm/compton/calidaq_backup/DataTaking/Am241/Run_55/Image_Am241_Source_55_25_ 
 * axis_to_compress = 1 
 * block_compression = [ 1 64] 
 * compressed = False 
 * correct_leach_bug = True 
 * correct_polarity = False 
 * exposure_time = 3.005961078 
 * exposure_time_keyword = MEXP 
 * extension = 0 
 * extensions = 0 
 * figure_id = 0 
 * file_name = /media/ncastello/WORK/damicm/compton/calidaq_backup/DataTaking/Am241/Run_55/Image_Am241_Source_55_25.fits 
 * id_col_end = -1 
 * id_col_start = 0 
 * id_row_end = -1 
 * id_row_start = 0 
 * id_skip_end = -1 
 * id_skip_start = 0 
 * me_output = /media/ncastello/WORK/damicm/compton/calidaq_backup/DataTaking/Am241/Run_55/ 
 * n_cols_overscan = 0 
 * n_cols_prescan = 0 
 * n_rows_overscan = 0 
 * n_rows_prescan = 0 
 * nallcols = 17600 
 * ncols = 275 
 * ncols_keyword = NAXIS1 
 * npbin = 4 
 * npbin_keyword = NPBIN 
 * nrows = 150 
 * nrows_keyword = NAXIS2 
 * nsbin = 4 
 * nsbin_keyword = NSBIN 
 * nskips = 64 
 * nskips_keyword = NDCMS 
 * output = /media/ncastello/WORK/damicm/compton/calidaq_backup/DataTaking/Am241/Run_55/Image_Am241_Source_55_25_ 
 * read_time = 37.318667586000004 
 * read_time_keyword = MREAD 
 * skip_image = True 
 * tot_time = 40.324628664 
 * image.shape =  (150, 275, 64)

From this long list, the most relevant attributes of rdata are:

  • When a full row is on the serial register, we can just read more columns than the full real size of our CCD. If we start to read before reading real pixels, we will have a region called prescan on cols. Just after reading this unreal set of pixels, the real data from row r starts. And at the end, we can just continue to read a set of n more pixels, that contributes to the overscan on cols region. The same can be done on rows: read n-rows before starting the real data (known as prescan on rows) or just after reading the full real pixels (known as overscan on rows). This is an information that we must set to properly define our data set

    • n_cols_overscan: to define which columns are the ones that correspondds to the overscan on cols, i.e. [full_data_size_on_cols - n_cols_prescan, full_data_size_on_cols)
    • n_cols_prescan: to define which columns are the ones that corresponds to the prescan on cols, i.e. [0 , n_cols_prescan)
    • n_rows_prescan: to define which rows are the ones that corresponds to the prescan on rows, i.e. [0, n_rows_prescan)
    • n_rows_overscan: to define whih rows are the ones that corresponds to the overscan on rows, i.e. [full_data_size_on_rows - n_rows_overscan, full_data_size_on_rows)
  • For that need also to now the full size of the data set: [full_data_size_on_rows, full_data_size_on_cols]. This is readed from the header of the fits file from

    • ncols_keyword will tell us the name of keyword to get the number of columns from the fits header, this value is then stored as ncols
    • nrows_keyword --> nrows (same as before but for rows)
  • If the data corresponds to an skipper images, we must now how many skips have been done and in which axis axis_to_compress. This kind of information is also on the header of the fits file

    • nskips_keyword pointing to a variable on the fits header to find the number of skips that will be transfered to nskips, and create the variable nallcols is axis_to_compress is 1 (meaning single skips along columns) or to nallrows if axis_to_compress is 0 (meaning single skips are measured along rows).
  • Another useful parameters are the ones that allow the user to use only a specific region of the data that do not corresond to the sensitive region, nether to over- or pre-scan region. And the same for the skips. These are

    • id_col_start and id_col_end
    • id_row_start and id_row_end
    • id_skip_start and id_skip_end
  • There are two paramters that are setup dependent:

    • correct_leach_bug: set to correct from a bug on the data taken (some of the columns are misplaced). Note that this is by default active, and data will be correct from that bug unless you specified the opposite.

    • correct_polarity: set to invert signal (pixels with no signal are recorded with the maximum value of ADC, and a negatibe pulse occures in the passage of an ionizing particle, having then a pixel with charge lower values of ADCs)

All this parameters are the ones the user can just define and pass to BuilderRawData in a dictionary format.

3.2 Using a configuration JSON file

Our data file can be also loaded with the correct configuration.

We can have an example of how looks like the dictionary for the input rawdata configuration at

`ccd.__path`/json/panaSKImg_configuration.json. To load this configuration JSON file we can use the class Config from pysimdamicm.utils.config.

In [8]:
cfg_file = "{}/json/panaSKImg_configuration.json".format(ccd.__path__[0])
print( cfg_file )
cfg = ccd.utils.config.Config(cfg_file, False)
/home/ncastello/.local/lib/python3.5/site-packages/pysimdamicm-3.0.0-py3.5.egg/pysimdamicm/json/panaSKImg_configuration.json
 WARNING: Parameter <FitDarkCurrentProcess> will be ignored (Not implemented) 
 WARNING: Parameter <FitDarkCurrentProcess.sigma_gauss> will be ignored (Not implemented) 
 WARNING: Parameter <FitDarkCurrentProcess.lambda_poisson> will be ignored (Not implemented) 
 WARNING: Parameter <FitCalibrationConstant.image> will be ignored (Not implemented) 
 WARNING: Parameter <FitDarkCurrentProcess.binning_size> will be ignored (Not implemented) 
 WARNING: Parameter <FitDarkCurrentProcess.n_sigma_fit> will be ignored (Not implemented) 
 WARNING: Parameter <FitDarkCurrentProcess.fit_options> will be ignored (Not implemented) 
 WARNING: Parameter <SignalPatternRecognition.image> will be ignored (Not implemented) 
 WARNING: Parameter <FitDarkCurrentProcess.method> will be ignored (Not implemented) 
 WARNING: Parameter <FitDarkCurrentProcess.n_peaks> will be ignored (Not implemented) 
 WARNING: Parameter <MaskImageProcess> will be ignored (Not implemented) 
 WARNING: Parameter <PedestalSubtractionProcess.histequ> will be ignored (Not implemented) 
 WARNING: Parameter <FitDarkCurrentProcess.do_calibration> will be ignored (Not implemented) 
 WARNING: Parameter <FitDarkCurrentProcess.mu_gauss> will be ignored (Not implemented) 
 WARNING: Parameter <MaskImageProcess.n_mad> will be ignored (Not implemented) 
 WARNING: Parameter <FitDarkCurrentProcess.image> will be ignored (Not implemented) 
 WARNING: Parameter <SignalPatternRecognition.isdata> will be ignored (Not implemented) 

This warnings are deprecated and will be removed in the next release of pysimdamicm (so you can just ignore them).

This returns a Config object, with the following attributes and data members:

In [9]:
print( [attr for attr in dir(cfg) if attr[0]!='_'] )
['activate_configuration', 'configuration', 'file_name', 'get_keys', 'read_file', 'validate_json']

The one we care about for this session, is the dictionary cfg.configuration where all parameters from the JSON file are loaded under the structure dictionary of python. There are two main sections:

In [10]:
cfg.configuration.keys()
Out[10]:
dict_keys(['process', 'input'])

Where input is the one relevant for interpreting correctly the input data file. This is another dictionary containing three more sections:

  • conventions: where all the necessary keywords should be inform (variables with relevant information that are recorded in the fits file header)

  • image: parameters to define over- and pre-scan region, skip direction, ...

  • scp: not relevant here

In [11]:
cfg.configuration['input'].keys()
Out[11]:
dict_keys(['convention', 'image', 'scp'])
In [12]:
cfg.configuration['input']['image']
Out[12]:
{'active_region_cols': None,
 'active_region_rows': None,
 'axis_to_compress': 1,
 'correct_leach_bug': True,
 'correct_polarity': False,
 'extensions': 0,
 'id_col_end': -1,
 'id_col_start': 0,
 'id_row_end': -1,
 'id_row_start': 0,
 'id_skip_end': -1,
 'id_skip_start': 3,
 'n_cols_overscan': 15,
 'n_cols_prescan': 2,
 'n_rows_overscan': 0,
 'n_rows_prescan': 0,
 'skip_image': True}
In [13]:
cfg.configuration['input']['convention']
Out[13]:
{'Ncols': 'NAXIS1',
 'Npbin': 'NPBIN',
 'Nrows': 'NAXIS2',
 'Nsbin': 'NSBIN',
 'Nskips': 'NDCMS',
 'ampl': 'AMPL',
 'exposure_time': 'MEXP',
 'read_time': 'MREAD'}

All this parameters are attributes that we already see at rdata.info() . All of them became attributes of the RawData object.

The file we will use in this example has:

  • 15 columns as overscan on cols
  • 3 columns as prescan on cols
  • no prescan on rows, nether overscan on rows
  • the skips are done on columns (as the default option, so nothing to change here)
  • needs to be corrected from the Leach bug (as the default option, so nothing to change here)
  • and the keywords to identify the size on rows, cols and the number of skips are the ones by default (see cfg.configuration['input']['convention'])

So, to properly interpret the data on our fits file we will change this values on the configuration file

In [14]:
cfg.configuration['input']['image']['n_cols_prescan'] = 3

Check your changes are updated

In [15]:
cfg.configuration['input']['image']
Out[15]:
{'active_region_cols': None,
 'active_region_rows': None,
 'axis_to_compress': 1,
 'correct_leach_bug': True,
 'correct_polarity': False,
 'extensions': 0,
 'id_col_end': -1,
 'id_col_start': 0,
 'id_row_end': -1,
 'id_row_start': 0,
 'id_skip_end': -1,
 'id_skip_start': 3,
 'n_cols_overscan': 15,
 'n_cols_prescan': 3,
 'n_rows_overscan': 0,
 'n_rows_prescan': 0,
 'skip_image': True}

Once our dictionary to interpret correctly the data is correctly updated load the data file with the second parametrized configuration of BuilderRawData (see 1.2).

In [16]:
rdata = ccd.io.rawdata.BuilderRawData( file_name.format(25), cfg.configuration['input'])
Print INFO.
General info of the fits file
****************************************************************************
Filename: /media/ncastello/WORK/damicm/compton/calidaq_backup/DataTaking/Am241/Run_55/Image_Am241_Source_55_25.fits
No.    Name         Type      Cards   Dimensions   Format
  0  PRIMARY     PrimaryHDU      84   (17600, 150)   int16 (rescales to uint16)   
None
Displaying full header ext= 0
****************************************************************************
SIMPLE  =                    T / file does conform to FITS standard             
BITPIX  =                   16 / number of bits per data pixel                  
NAXIS   =                    2 / number of data axes                            
NAXIS1  =                17600 / length of data axis 1                          
NAXIS2  =                  150 / length of data axis 2                          
EXTEND  =                    T / FITS dataset may contain extensions            
COMMENT   FITS (Flexible Image Transport System) format is defined in 'Astronomy
COMMENT   and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H 
BZERO   =                32768 / offset data range to that of unsigned short    
BSCALE  =                    1 / default scaling factor                         
COMMENT This image was taken by a DAMIC UW CCD. The various settings used are st
COMMENT ored as keys in the FITS file.Processed by CCDDrone - Pitam Mitra @ UW. 
COMMENT If you have questions, please send them to pitamm@uw.edu                
CCDTYPE = 'SK      '           / CCD Type (DES or SK)                           
EXP     =                   3. / Exposure time (s)                              
NDCMS   =                   64 / Number of charge measurements                  
AMPL    = 'L       '           / Amplifier(s) used                              
COMMENT ASMFILE: Sequencer file used /home/Leach/CCDSequencer/firmware_super_seq
COMMENT uencer_Paolo_Aug2020_inverted.lod                                       
SUPERSE =                    1 / Super sequencer (SSeq) used?                   
INVRG   =                    0 / Is RG inverted                                 
HCKDIRN = 'U       '           / Serial register h-clock direction (SSEq only)  
VCKDIRN = '2       '           / Vertical clock direction (SSeq only)           
ITGTIME =                   5. / Integration time (SSeq only)                   
VIDGAIN =                    1 / Video gain                                     
ITGSPD  =                    0 / Integrator speed (0=slow, 1=fast)              
PRETIME =                  0.5 / Pedestal settling + video ADC refresh time     
POSTIME =                  0.5 / Signal settling time                           
DGWIDTH =                 0.24 / DG Width (SK only)                             
RGWIDTH =                 0.24 / Reset width (SK only)                          
OGWIDTH =                 0.24 / OG Width (SK only)                             
SWWIDTH =                 0.24 / SW Pulse Width (SK only)                       
HWIDTH  =                 0.24 / H-Clock Width (SK only)                        
HOWIDTH =                 0.24 / H-Clock overlap Width (SK only)                
VWIDTH  =                  20. / V-Clock Width (SK only)                        
VOWIDTH =                  20. / V-Clock overlap Width (SK only)                
NPBIN   =                    4 / Binning in the V-direction (parallel clocks)   
NSBIN   =                    4 / Binning in the H-direction (serial clocks)     
SECSTG  = 'UW2     '           / Second stage board revision (SSeq only)        
ONEVCKHI=                  1.5 / V1 clock Hi                                    
ONEVCKLO=                 -0.5 / V1 clock Lo                                    
TWOVCKHI=                  1.5 / V2 clock Hi                                    
TWOVCKLO=                 -0.5 / V2 clock Lo                                    
ONETGHI =                  1.5 / Transfer Gate SR1 Hi                           
ONETGLO =                 -0.5 / Transfer Gate SR1 Lo                           
TWOTGHI =                  1.5 / Transfer Gate SR2 Hi                           
TWOTGLO =                 -0.5 / Transfer Gate SR2 Lo                           
HUHI    =                   1. / U Serial Register H-Clocks Hi                  
HULO    =                 -2.5 / U Serial Register H-Clocks Lo                  
HLHI    =                   1. / L Serial Register H-Clocks Hi                  
HLLO    =                 -2.5 / L Serial Register H-Clocks Lo                  
ONERGHI =                  5.5 / Reset Gates on SR1 Hi                          
ONERGLO =                   3. / Reset Gates on SR1 Lo                          
TWORGHI =                   5. / Reset Gates on SR2 Hi                          
TWORGLO =                   3. / Reset Gates on SR2 Lo                          
ONESWHI =                  -3. / Summing Wells on SR1 Hi                        
ONESWLO =                 -11. / Summing Wells on SR1 Lo                        
TWOSWHI =                  -3. / Summing Wells on SR2 Hi                        
TWOSWLO =                  -9. / Summing Wells on SR2 Lo                        
ONEDGHI =                  -3. / DGs on SR1 Hi (SK only)                        
ONEDGLO =                 -11. / DGs on SR1 Lo (SK only)                        
TWODGHI =                  -4. / DGs on SR2 Hi (SK only)                        
TWODGLO =                  -8. / DGs on SR2 Lo (SK only)                        
ONEOGHI =                  -4. / OGs on SR1 Hi (SK only)                        
ONEOGLO =                 -11. / OGs on SR1 Lo (SK only)                        
TWOOGHI =                  -4. / OGs on SR2 Hi (SK only)                        
TWOOGLO =                  -9. / OGs on SR2 Lo (SK only)                        
BATTR   =                   5. / Battery box relay TTL Line                     
VDD1    =                 -19. / Vdd                                            
VDD2    =                 -19. / Vdd                                            
VIDOFFL =                 2200 / Video pedestal offset L                        
VIDOFFU =                 2200 / Video pedestal offset U                        
DRAIN1  =                -24.5 / Drain1 (Relevant to SK)                        
DRAIN2  =                -24.5 / Drain2 (Relevant to SK)                        
VREF1   =                  -7. / VRef                                           
VREF2   =                  -7. / VRef                                           
OPG1    =                 2.21 / OpG1 (Relevant to DES)                         
OPG2    =                 2.21 / OpG2 (Relevant to DES)                         
PROGSTRT= 'Sun Nov 15 23:31:53 2020' / Program start time                       
EXPSTART= 'Sun Nov 15 23:31:53 2020' / Exposure start time                      
RDSTRT  = 'Sun Nov 15 23:31:56 2020' / Readout start time                       
RDEND   = 'Sun Nov 15 23:32:34 2020' / Readout end time                         
MEXP    =          3005.961078 / Measured exposure time (ms)                    
MREAD   =         37318.667586 / Measured readout time (ms)                     
****************************************************************************
Summary: 

N. rows=150 columns=275 skips=64 
Image ndim:  2
Image shape: (150, 17600)
Image size:  2640000
Image dtype: uint16
****************************************************************************
Correction INFO. Correcting data for Leach bug:
 	 the first two column moved to the end,
 	 move one-row down (only the two last columns).

If we display the relevant attributes of rdata, we can see that this are different from the previous one:

In [17]:
rdata.info()
 * active_region_cols = None 
 * active_region_rows = None 
 * ampl = L 
 * ampl_keyword = AMPL 
 * avg_output = /media/ncastello/WORK/damicm/compton/calidaq_backup/DataTaking/Am241/Run_55/Image_Am241_Source_55_25_ 
 * axis_to_compress = 1 
 * block_compression = [ 1 64] 
 * compressed = False 
 * correct_leach_bug = True 
 * correct_polarity = False 
 * exposure_time = 3.005961078 
 * exposure_time_keyword = MEXP 
 * extension = 0 
 * extensions = 0 
 * figure_id = 0 
 * file_name = /media/ncastello/WORK/damicm/compton/calidaq_backup/DataTaking/Am241/Run_55/Image_Am241_Source_55_25.fits 
 * id_col_end = -1 
 * id_col_start = 0 
 * id_row_end = -1 
 * id_row_start = 0 
 * id_skip_end = -1 
 * id_skip_start = 3 
 * me_output = /media/ncastello/WORK/damicm/compton/calidaq_backup/DataTaking/Am241/Run_55/ 
 * n_cols_overscan = 15 
 * n_cols_prescan = 3 
 * n_rows_overscan = 0 
 * n_rows_prescan = 0 
 * nallcols = 17600 
 * ncols = 275 
 * ncols_keyword = NAXIS1 
 * npbin = 4 
 * npbin_keyword = NPBIN 
 * nrows = 150 
 * nrows_keyword = NAXIS2 
 * nsbin = 4 
 * nsbin_keyword = NSBIN 
 * nskips = 64 
 * nskips_keyword = NDCMS 
 * output = /media/ncastello/WORK/damicm/compton/calidaq_backup/DataTaking/Am241/Run_55/Image_Am241_Source_55_25_ 
 * read_time = 37.318667586000004 
 * read_time_keyword = MREAD 
 * skip_image = True 
 * tot_time = 40.324628664 
 * image.shape =  (150, 275, 64)

4. rdata.image the raw data

The data from the fits files is loaded as a numpy.ndarray under the attribute image of the rdata object. From the output of rdata.info() once can see if the data was loaded correctly.

In our example, the loaded data is interpreted as a np.ndarray of 3 dimensions: 150 rows, 275 columns and 64 skips. See last line from the previous output or just type

In [18]:
rdata.image.shape
Out[18]:
(150, 275, 64)

Up to this point, you only loaded the data as it is in the fits file, and reshpae that to add the skips in a extra dimension (2D --> 3D) to exploit the capabilities of numpy.

For instance, let's said you want to know the mean of all skips values per pixel. In a standard way you just will do:

In [19]:
mean_pixel_charge_f = np.zeros(rdata.image.shape[:2], dtype=np.float64)

for r in range(rdata.image.shape[0]):
    for c in range(rdata.image.shape[1]):
        mean_pixel_charge_f[r,c] = np.mean( rdata.image[r,c,:] )

mean_pixel_charge_f.shape
Out[19]:
(150, 275)

a pixel in the image mean_pixel_charge_f is the mean of all single skips done for this pixel (in our example, the mean of the 64 different measurements).

Or you can just take profit of the nature of the rdata.image object

In [20]:
mean_pixel_charge = np.mean(rdata.image, axis=2)

#plt.figure("Comparing results of mean values per row from two different methods")
#plt.scatter( mean_charge_row, mean_charge_row_f )

mean_pixel_charge.shape
Out[20]:
(150, 275)
In [21]:
fig, ax = plt.subplots()
iax = ax.imshow( mean_pixel_charge_f - mean_pixel_charge, aspect='auto' )
fig.colorbar(iax)
Out[21]:
<matplotlib.colorbar.Colorbar at 0x7fbc5ba9aa58>

From the image, we see that both procedure reach the same output. Another way to check is also by sum up all differences, and check it is zero

In [22]:
( mean_pixel_charge_f - mean_pixel_charge ).sum()
Out[22]:
0.0

4.1 CompressSkipperImage

There is a process that does this operation of compressin the skippers to end with a single image of dimension 2: CompressSkipperImage. We will explore in more detail this class in the How to Process for Analysis.

Here an example of how to do it:

In [23]:
comp = ccd.processes.skipper_analysis.CompressSkipperProcess()
In [24]:
comp.info()
<CompressSkipsProcess> with sequence id 10.
 List of public data members: 
	 * __sequence_id__ = 10 
	 * __verbose__ = False 
	 * func_to_compress = ['mean', 'std'] 
	 * id_col_end = nan 
	 * id_col_start = nan 
	 * id_row_end = nan 
	 * id_row_start = nan 
	 * id_skip_end = nan 
	 * id_skip_start = nan 
	 * image = raw 
	 * save_image = False 
	 * save_plots = False 

With this process we can just limit the region of the skips to take into account. For each statiscal function listed on the attribute func_to_compress (statistic that must exist on numpy) a new image will be created and returned as a new attribute on the object rdata.

Let's see it with an example

Let's said we are only want to consider skip measurements from skip id 10 up to skip id 63, using only the mean function:

In [25]:
comp.id_skip_start = 10
comp.id_skip_end = 63
comp.func_to_compress = ['mean']

Now we only need to execute this process on our data:

In [26]:
comp.execute_process( rdata )
Process <CompressSkipsProcess> INFO. Compressing raw image data using the following statistics: ['mean']
     - used skip range 10:63
     - image (150, 275, 53) have been reduced to 150x275

This process return the compressed image as a new attribute on our data: rdata.image_mean_compressed

In [27]:
rdata.image_mean_compressed.shape
Out[27]:
(150, 275)

When object mean_pixel_charge was done, the full set of skips where used, but not here. In this example, the skippe compression process take into consideration only skip measurements from 10 to 63,

In [28]:
(rdata.image_mean_compressed - mean_pixel_charge).sum()
Out[28]:
652172.6813089622

To get the same results just consider all skips

In [29]:
comp.id_skip_end = -1
comp.id_skip_start = 0
comp.execute_process(rdata)
Process <CompressSkipsProcess> INFO. Compressing raw image data using the following statistics: ['mean']
     - used skip range 0:64
     - image (150, 275, 64) have been reduced to 150x275

In [30]:
(rdata.image_mean_compressed - mean_pixel_charge).sum()
Out[30]:
0.0

And now we get the same result!

If you set the attribute comp.__verbose__ you will get an ouptu image:

In [31]:
comp.__verbose__
Out[31]:
False
In [32]:
comp.__verbose__ = True
comp.execute_process(rdata)
Process <CompressSkipsProcess> INFO. Compressing raw image data using the following statistics: ['mean']
     - used skip range 0:64
     - image (150, 275, 64) have been reduced to 150x275

/home/ncastello/.local/lib/python3.5/site-packages/matplotlib/figure.py:98: MatplotlibDeprecationWarning: 
Adding an axes using the same arguments as a previous axes currently reuses the earlier instance.  In a future version, a new instance will always be created and returned.  Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.
  "Adding an axes using the same arguments as a previous axes "

The warning is just because one of the used axis was re-used (not important right now, and will be removed in the next version of pysimdamicm)

5. Use of RawData for already compressed images

Up to now, we learn how to read our data properly using a configuration file. We have seen that the method used to load the image modifies its dimension to be an array of 3-dimensions: rows, cols and skips (in this order).

What happen if the image we want to load has no skips (or is already a compressed one)?

The keyword on the fits file header NCDMS must point to 1 to properly load the data. So you can just change the parameter cfg.configuration['input']['convention']['Nskips'] to point to a variable with value int(1). If the image you use is the output of the previous process CompressSkipperImage you do not need to do nothing beause this is already done!

Let's see it.

For this, I will use an image that was compressed by using CompressSkipperImage and stored by this process too.

As before I will use a variable to define the path, and the patter for the fits file name. You can just use a single variable with the absolute path to the fits file (I am using that in case we want to play with other images from the same path).

In [33]:
path_to_avgimg = "/data/workdir/compton/data/calidaq_backup/DataTaking/Am241/outputs/run027/avgimg"
patter_file_name = "Image_Am241_Source_27_{}_compressed.fits"

cfile_name = "{}/{}".format(path_to_avgimg,patter_file_name)
In [34]:
cdata = ccd.io.rawdata.BuilderRawData(cfile_name.format(205),cfg.configuration['input'])
Print INFO.
General info of the fits file
****************************************************************************
Filename: /data/workdir/compton/data/calidaq_backup/DataTaking/Am241/outputs/run027/avgimg/Image_Am241_Source_27_205_compressed.fits
No.    Name         Type      Cards   Dimensions   Format
  0  PRIMARY     PrimaryHDU      82   (275, 150)   float64   
None
Displaying full header ext= 0
****************************************************************************
SIMPLE  =                    T / conforms to FITS standard                      
BITPIX  =                  -64 / array data type                                
NAXIS   =                    2 / number of array dimensions                     
NAXIS1  =                  275                                                  
NAXIS2  =                  150                                                  
COMMENT   FITS (Flexible Image Transport System) format is defined in 'Astronomy
COMMENT   and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H 
COMMENT This image was taken by a DAMIC UW CCD. The various settings used are st
COMMENT ored as keys in the FITS file.Processed by CCDDrone - Pitam Mitra @ UW. 
COMMENT If you have questions, please send them to pitamm@uw.edu                
CCDTYPE = 'SK      '           / CCD Type (DES or SK)                           
EXP     =                   3. / Exposure time (s)                              
NDCMS   =                    1 / Number of charge measurements                  
AMPL    = 'U       '           / Amplifier(s) used                              
COMMENT ASMFILE: Sequencer file used /home/Leach/CCDSequencer/firmware_super_seq
COMMENT uencer_Paolo_Aug2020_inverted.lod                                       
SUPERSE =                    1 / Super sequencer (SSeq) used?                   
INVRG   =                    0 / Is RG inverted                                 
HCKDIRN = 'U       '           / Serial register h-clock direction (SSEq only)  
VCKDIRN = '1       '           / Vertical clock direction (SSeq only)           
ITGTIME =                   5. / Integration time (SSeq only)                   
VIDGAIN =                    1 / Video gain                                     
ITGSPD  =                    0 / Integrator speed (0=slow, 1=fast)              
PRETIME =                  0.5 / Pedestal settling + video ADC refresh time     
POSTIME =                  0.5 / Signal settling time                           
DGWIDTH =                 0.24 / DG Width (SK only)                             
RGWIDTH =                 0.24 / Reset width (SK only)                          
OGWIDTH =                 0.24 / OG Width (SK only)                             
SWWIDTH =                 0.24 / SW Pulse Width (SK only)                       
HWIDTH  =                 0.24 / H-Clock Width (SK only)                        
HOWIDTH =                 0.24 / H-Clock overlap Width (SK only)                
VWIDTH  =                  20. / V-Clock Width (SK only)                        
VOWIDTH =                  20. / V-Clock overlap Width (SK only)                
NPBIN   =                    4 / Binning in the V-direction (parallel clocks)   
NSBIN   =                    4 / Binning in the H-direction (serial clocks)     
SECSTG  = 'UW2     '           / Second stage board revision (SSeq only)        
ONEVCKHI=                  1.5 / V1 clock Hi                                    
ONEVCKLO=                 -0.5 / V1 clock Lo                                    
TWOVCKHI=                  1.5 / V2 clock Hi                                    
TWOVCKLO=                 -0.5 / V2 clock Lo                                    
ONETGHI =                  1.5 / Transfer Gate SR1 Hi                           
ONETGLO =                 -0.5 / Transfer Gate SR1 Lo                           
TWOTGHI =                  1.5 / Transfer Gate SR2 Hi                           
TWOTGLO =                 -0.5 / Transfer Gate SR2 Lo                           
HUHI    =                   1. / U Serial Register H-Clocks Hi                  
HULO    =                 -2.5 / U Serial Register H-Clocks Lo                  
HLHI    =                   1. / L Serial Register H-Clocks Hi                  
HLLO    =                 -2.5 / L Serial Register H-Clocks Lo                  
ONERGHI =                  5.5 / Reset Gates on SR1 Hi                          
ONERGLO =                   3. / Reset Gates on SR1 Lo                          
TWORGHI =                   5. / Reset Gates on SR2 Hi                          
TWORGLO =                   3. / Reset Gates on SR2 Lo                          
ONESWHI =                  -3. / Summing Wells on SR1 Hi                        
ONESWLO =                 -11. / Summing Wells on SR1 Lo                        
TWOSWHI =                  -3. / Summing Wells on SR2 Hi                        
TWOSWLO =                  -9. / Summing Wells on SR2 Lo                        
ONEDGHI =                  -3. / DGs on SR1 Hi (SK only)                        
ONEDGLO =                 -11. / DGs on SR1 Lo (SK only)                        
TWODGHI =                  -4. / DGs on SR2 Hi (SK only)                        
TWODGLO =                  -8. / DGs on SR2 Lo (SK only)                        
ONEOGHI =                  -4. / OGs on SR1 Hi (SK only)                        
ONEOGLO =                 -11. / OGs on SR1 Lo (SK only)                        
TWOOGHI =                  -4. / OGs on SR2 Hi (SK only)                        
TWOOGLO =                  -9. / OGs on SR2 Lo (SK only)                        
BATTR   =                   5. / Battery box relay TTL Line                     
VDD1    =                 -19. / Vdd                                            
VDD2    =                 -19. / Vdd                                            
VIDOFFL =                 2000 / Video pedestal offset L                        
VIDOFFU =                 2000 / Video pedestal offset U                        
DRAIN1  =                -24.5 / Drain1 (Relevant to SK)                        
DRAIN2  =                -24.5 / Drain2 (Relevant to SK)                        
VREF1   =                  -7. / VRef                                           
VREF2   =                  -7. / VRef                                           
OPG1    =                 2.21 / OpG1 (Relevant to DES)                         
OPG2    =                 2.21 / OpG2 (Relevant to DES)                         
PROGSTRT= 'Mon Oct 26 23:04:26 2020' / Program start time                       
EXPSTART= 'Mon Oct 26 23:04:26 2020' / Exposure start time                      
RDSTRT  = 'Mon Oct 26 23:04:29 2020' / Readout start time                       
RDEND   = 'Mon Oct 26 23:05:07 2020' / Readout end time                         
MEXP    =           3005.68657 / Measured exposure time (ms)                    
MREAD   =         37318.026539 / Measured readout time (ms)                     
NSKIPS  =                   64 / Number of charge measurements for the raw data 
****************************************************************************
Summary: 

N. rows=150 columns=275 skips=1 
Image ndim:  2
Image shape: (150, 275)
Image size:  41250
Image dtype: >f8
****************************************************************************
Correction INFO. Correcting data for Leach bug:
 	 the first two column moved to the end,
 	 move one-row down (only the two last columns).

In [35]:
cdata.image.shape
Out[35]:
(150, 275)

The data is then a 2D ndarray.

Note that this time a new image has also been created:

cdata.image_mean_compressed

this is because some process (see How to Process for Analysis) will search for that attribute (like for instance

In [36]:
cdata.image_mean_compressed.shape
Out[36]:
(150, 275)

Both images, image and image_mean_compressed are the same:

In [37]:
(cdata.image_mean_compressed - cdata.image).sum()
Out[37]:
0.0

What would happen if we wanted to compress that image?

In [38]:
comp.execute_process(cdata)
Process <CompressSkipsProcess> INFO. Compressing raw image data using the following statistics: ['mean']
  WARNING. Number of skips = 1, nothing to do!

As we should expect!

The number of skips in the input fits file header (NCDMS) was changed to be 1. The data member image_header of the RawData object contains the header of the input fits file. Let's see the values for this variables

In [39]:
print(repr(cdata.image_header))
SIMPLE  =                    T / conforms to FITS standard                      
BITPIX  =                  -64 / array data type                                
NAXIS   =                    2 / number of array dimensions                     
NAXIS1  =                  275                                                  
NAXIS2  =                  150                                                  
COMMENT   FITS (Flexible Image Transport System) format is defined in 'Astronomy
COMMENT   and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H 
COMMENT This image was taken by a DAMIC UW CCD. The various settings used are st
COMMENT ored as keys in the FITS file.Processed by CCDDrone - Pitam Mitra @ UW. 
COMMENT If you have questions, please send them to pitamm@uw.edu                
CCDTYPE = 'SK      '           / CCD Type (DES or SK)                           
EXP     =                   3. / Exposure time (s)                              
NDCMS   =                    1 / Number of charge measurements                  
AMPL    = 'U       '           / Amplifier(s) used                              
COMMENT ASMFILE: Sequencer file used /home/Leach/CCDSequencer/firmware_super_seq
COMMENT uencer_Paolo_Aug2020_inverted.lod                                       
SUPERSE =                    1 / Super sequencer (SSeq) used?                   
INVRG   =                    0 / Is RG inverted                                 
HCKDIRN = 'U       '           / Serial register h-clock direction (SSEq only)  
VCKDIRN = '1       '           / Vertical clock direction (SSeq only)           
ITGTIME =                   5. / Integration time (SSeq only)                   
VIDGAIN =                    1 / Video gain                                     
ITGSPD  =                    0 / Integrator speed (0=slow, 1=fast)              
PRETIME =                  0.5 / Pedestal settling + video ADC refresh time     
POSTIME =                  0.5 / Signal settling time                           
DGWIDTH =                 0.24 / DG Width (SK only)                             
RGWIDTH =                 0.24 / Reset width (SK only)                          
OGWIDTH =                 0.24 / OG Width (SK only)                             
SWWIDTH =                 0.24 / SW Pulse Width (SK only)                       
HWIDTH  =                 0.24 / H-Clock Width (SK only)                        
HOWIDTH =                 0.24 / H-Clock overlap Width (SK only)                
VWIDTH  =                  20. / V-Clock Width (SK only)                        
VOWIDTH =                  20. / V-Clock overlap Width (SK only)                
NPBIN   =                    4 / Binning in the V-direction (parallel clocks)   
NSBIN   =                    4 / Binning in the H-direction (serial clocks)     
SECSTG  = 'UW2     '           / Second stage board revision (SSeq only)        
ONEVCKHI=                  1.5 / V1 clock Hi                                    
ONEVCKLO=                 -0.5 / V1 clock Lo                                    
TWOVCKHI=                  1.5 / V2 clock Hi                                    
TWOVCKLO=                 -0.5 / V2 clock Lo                                    
ONETGHI =                  1.5 / Transfer Gate SR1 Hi                           
ONETGLO =                 -0.5 / Transfer Gate SR1 Lo                           
TWOTGHI =                  1.5 / Transfer Gate SR2 Hi                           
TWOTGLO =                 -0.5 / Transfer Gate SR2 Lo                           
HUHI    =                   1. / U Serial Register H-Clocks Hi                  
HULO    =                 -2.5 / U Serial Register H-Clocks Lo                  
HLHI    =                   1. / L Serial Register H-Clocks Hi                  
HLLO    =                 -2.5 / L Serial Register H-Clocks Lo                  
ONERGHI =                  5.5 / Reset Gates on SR1 Hi                          
ONERGLO =                   3. / Reset Gates on SR1 Lo                          
TWORGHI =                   5. / Reset Gates on SR2 Hi                          
TWORGLO =                   3. / Reset Gates on SR2 Lo                          
ONESWHI =                  -3. / Summing Wells on SR1 Hi                        
ONESWLO =                 -11. / Summing Wells on SR1 Lo                        
TWOSWHI =                  -3. / Summing Wells on SR2 Hi                        
TWOSWLO =                  -9. / Summing Wells on SR2 Lo                        
ONEDGHI =                  -3. / DGs on SR1 Hi (SK only)                        
ONEDGLO =                 -11. / DGs on SR1 Lo (SK only)                        
TWODGHI =                  -4. / DGs on SR2 Hi (SK only)                        
TWODGLO =                  -8. / DGs on SR2 Lo (SK only)                        
ONEOGHI =                  -4. / OGs on SR1 Hi (SK only)                        
ONEOGLO =                 -11. / OGs on SR1 Lo (SK only)                        
TWOOGHI =                  -4. / OGs on SR2 Hi (SK only)                        
TWOOGLO =                  -9. / OGs on SR2 Lo (SK only)                        
BATTR   =                   5. / Battery box relay TTL Line                     
VDD1    =                 -19. / Vdd                                            
VDD2    =                 -19. / Vdd                                            
VIDOFFL =                 2000 / Video pedestal offset L                        
VIDOFFU =                 2000 / Video pedestal offset U                        
DRAIN1  =                -24.5 / Drain1 (Relevant to SK)                        
DRAIN2  =                -24.5 / Drain2 (Relevant to SK)                        
VREF1   =                  -7. / VRef                                           
VREF2   =                  -7. / VRef                                           
OPG1    =                 2.21 / OpG1 (Relevant to DES)                         
OPG2    =                 2.21 / OpG2 (Relevant to DES)                         
PROGSTRT= 'Mon Oct 26 23:04:26 2020' / Program start time                       
EXPSTART= 'Mon Oct 26 23:04:26 2020' / Exposure start time                      
RDSTRT  = 'Mon Oct 26 23:04:29 2020' / Readout start time                       
RDEND   = 'Mon Oct 26 23:05:07 2020' / Readout end time                         
MEXP    =           3005.68657 / Measured exposure time (ms)                    
MREAD   =         37318.026539 / Measured readout time (ms)                     
NSKIPS  =                   64 / Number of charge measurements for the raw data 

We can see here that the parameter 'NDCMS' is set to 1 and a new one has been included 'NSKIPS' pointing to the number of measurements of the original raw data.

Note that we did not change the configuration options, and 'Nskips' points to 'NDCMS' which now is set to 1, as should be.

6. Define CCD regions: over[pre]-scan and active regions

Up to now we learn how to load our data with the correct configuration options. By default when a RawData is created it only reads the header and the data from the fits files, and re-shape the data to properly diferenciate between rows, columns and skips (if necessary).

But, how do we access the different regions of the data? How to get only the overscan on rows? or the active region?

If the configuration options has the correct values for this regions you just need to run

In [40]:
rdata.prepare_data()
RawData INFO.
 *********************************************************************** 
 ********* Define mask for sensor and over/pre-scan regions 'Image_Am241_Source_55_25.fits' ********* 
 *********************************************************************** 

 * Active region: 
		rows=0:150
		cols=3:260

 * Overscan  in cols: 
		rows=0:150
		cols=260:275

 * Prescan  in cols: 
		rows=0:150
		cols=0:3

 * NO Overscan  in rows

 * NO Prescan in rows
 ***********************************************************************. 

If the configuration options has not the correct one, and you do not want to re-load the data, you can just change the values on the rdata object.

6.1 Modify regions

Let's assume that the overscan on cols comprises the last 30 columns, instead of the 15 we have reported through the configuration options.

In [41]:
rdata.n_cols_overscan 
Out[41]:
15
In [42]:
rdata.n_cols_overscan = 30
rdata.n_cols_overscan
Out[42]:
30
In [43]:
rdata.prepare_data()
RawData INFO.
 *********************************************************************** 
 ********* Define mask for sensor and over/pre-scan regions 'Image_Am241_Source_55_25.fits' ********* 
 *********************************************************************** 

 * Active region: 
		rows=0:150
		cols=3:245

 * Overscan  in cols: 
		rows=0:150
		cols=245:275

 * Prescan  in cols: 
		rows=0:150
		cols=0:3

 * NO Overscan  in rows

 * NO Prescan in rows
 ***********************************************************************. 

6.2 Access to the different regions

This method create several atributes on the object rdata to properly point to the different regions. These are

  • mask_image_active_region
  • mask_image_overscan_cols
  • mask_image_overscan_rows
  • mask_image_prescan_cols
  • mask_image_prescan_rows

    These objects are boolean np.ndarray with the same shape as rdata.image. Those pixels with value True corresponds to values that are masked pixels, while the ones with value False are not masked pixels.

In [44]:
type(rdata.mask_image_prescan_cols)
rdata.mask_image_prescan_cols
Out[44]:
array([[False, False, False, ...,  True,  True,  True],
       [False, False, False, ...,  True,  True,  True],
       [False, False, False, ...,  True,  True,  True],
       ...,
       [False, False, False, ...,  True,  True,  True],
       [False, False, False, ...,  True,  True,  True],
       [False, False, False, ...,  True,  True,  True]])

Internally when any function/process wants to access to some specific region of the CCD will create a masked numpy array uisng this boolean arrrays as mask.

Let's see that with a plot: plotting only the active region by using a masked array from numpy.
In [45]:
plt.figure("sensitive region")
plt.imshow(np.ma.array( rdata.image_mean_compressed, mask= rdata.mask_image_active_region))
print( " There are {} pixels that have been masked".format(rdata.mask_image_active_region.sum()))
 There are 4950 pixels that have been masked

or only the overscan on columns

In [46]:
plt.figure("overscan on cols")
plt.imshow(np.ma.array( rdata.image_mean_compressed, mask= rdata.mask_image_overscan_cols))
print( " There are {} pixels that have been masked".format(rdata.mask_image_overscan_cols.sum()))
 There are 36750 pixels that have been masked

Pay attention when use masked array for numerical operations:

Instead of using functions from the main package numpy is recomended to use the module ma from numpy (i.e. numpy.ma) to properly perorme any numerical operation without worrying about masked values.

How looks like a masked array ?

Let's display only the first row of the overscan masked image

In [47]:
mimg = np.ma.array( rdata.image_mean_compressed, mask= rdata.mask_image_overscan_cols)

mimg[0,:]
Out[47]:
masked_array(data=[--, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, --, --, --, --, --, --, --,
                   --, --, --, --, --, --, --, 1086.03125, 1078.09375,
                   1083.765625, 1079.875, 1086.484375, 1090.078125,
                   1084.859375, 1084.734375, 1087.421875, 1087.0, 1089.0,
                   1089.6875, 1084.875, 1085.078125, 1084.8125,
                   1091.21875, 1083.734375, 1090.796875, 1076.1875,
                   1085.71875, 1076.109375, 1079.546875, 1075.359375,
                   1087.140625, 1089.640625, 1085.4375, 1084.96875,
                   1081.453125, 1086.765625, 1085.8125],
             mask=[ True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True,  True,  True,  True,
                    True,  True,  True,  True,  True, False, False, False,
                   False, False, False, False, False, False, False, False,
                   False, False, False, False, False, False, False, False,
                   False, False, False, False, False, False, False, False,
                   False, False, False],
       fill_value=1e+20)

This object has two main attributes: data and mask. The data for those masked pixels appears as '--', and will not be used.

Despite it has part of the data masked, it still contain the original shape

In [48]:
mimg.shape
Out[48]:
(150, 275)

An example of numerical operations with masked arrays

In [49]:
mimg**0.5 
Out[49]:
masked_array(
  data=[[--, --, --, ..., 32.885454611423576, 32.96612845027453,
         32.95166915347385],
        [--, --, --, ..., 32.95427703652441, 32.85051369461367,
         32.91537444720932],
        [--, --, --, ..., 32.90018047062964, 33.00307750801431,
         32.84099952802899],
        ...,
        [--, --, --, ..., 32.95238041477429, 32.88854283789417,
         32.890918199405746],
        [--, --, --, ..., 32.936966314461934, 32.94479283589442,
         32.965654475529526],
        [--, --, --, ..., 32.91489974160638, 32.95569943120613,
         32.875712920026544]],
  mask=[[ True,  True,  True, ..., False, False, False],
        [ True,  True,  True, ..., False, False, False],
        [ True,  True,  True, ..., False, False, False],
        ...,
        [ True,  True,  True, ..., False, False, False],
        [ True,  True,  True, ..., False, False, False],
        [ True,  True,  True, ..., False, False, False]],
  fill_value=1e+20)

Be careful with some statistics from numpy over masked array!

In [50]:
np.mean( mimg )
Out[50]:
1245.1978020833333
In [51]:
np.median( mimg )
/home/ncastello/.local/lib/python3.5/site-packages/numpy/core/fromnumeric.py:746: UserWarning: Warning: 'partition' will ignore the 'mask' of the MaskedArray.
  a.partition(kth, axis=axis, kind=kind, order=order)
Out[51]:
1083.296875
pointing to bad values

This warning tell us that function np.median is not taking into account the masked values, and we will get a non desired value for the median of our masked image. The proper way to operate with masked array is then by using the module ma, as already mentioned!

Wee see that some of the functions on numpy are override to work with masked arrays, but not all of them. So be really careful, and when the input array is masked just use ma functions instead of numpy.

In [52]:
np.ma.median( mimg ) - np.median( mimg )
/home/ncastello/.local/lib/python3.5/site-packages/numpy/core/fromnumeric.py:746: UserWarning: Warning: 'partition' will ignore the 'mask' of the MaskedArray.
  a.partition(kth, axis=axis, kind=kind, order=order)
Out[52]:
0.125
In [53]:
np.mean(mimg) - mimg.mean()
Out[53]:
0.0
In [54]:
np.mean(mimg) - np.ma.mean(mimg)
Out[54]:
0.0