xtcav/src/GenerateDarkBackground.py

Go to the documentation of this file.
00001 #(c) Coded by Alvaro Sanchez-Gonzalez 2014
00002 
00003 
00004 import os
00005 import time
00006 import psana
00007 import numpy as np
00008 import glob
00009 import sys
00010 import getopt
00011 import warnings
00012 import Utils as xtu
00013 import UtilsPsana as xtup
00014 from DarkBackground import *
00015 from CalibrationPaths import *
00016 
00017 
00018 class GenerateDarkBackground(object):
00019     """
00020     Class that generates a dark background image for XTCAV reconstruction purposes
00021     Attributes:
00022         experiment (str): String with the experiment reference to use. E.g. 'amoc8114'
00023         runs (str): String with a run number, or a run interval. E.g. '123'  '134-156' 145,136'
00024         maxshots (int): Maximum number of images to use for the reference.
00025         calibrationpath (str): Custom calibration directory in case the default is not intended to be used.
00026     """
00027 
00028     def __init__(self):
00029     
00030         #Handle warnings
00031         warnings.filterwarnings('always',module='Utils',category=UserWarning)
00032         warnings.filterwarnings('ignore',module='Utils',category=RuntimeWarning, message="invalid value encountered in divide")
00033         
00034         self._experiment='amoc8114'
00035         self._maxshots=100
00036         self._runs='85'
00037         self._validityrange=[]
00038         self._calpath=''
00039                        
00040     def Generate(self,savetofile=True):
00041         """
00042         After setting all the parameters, this method has to be called to generate the dark reference and save it in the proper location. It not set, the validity range for the reference will go from the first run number used to generate the reference and the last run.
00043         """
00044         print 'dark background reference'
00045         print '\t Experiment: %s' % self._experiment
00046         print '\t Runs: %s' % self._runs
00047         print '\t Valid shots to process: %d' % self._maxshots
00048         
00049         #Loading the dataset from the "dark" run, this way of working should be compatible with both xtc and hdf5 files
00050         dataSource=psana.DataSource("exp=%s:run=%s:idx" % (self._experiment,self._runs))
00051         
00052         #Camera and type for the xtcav images
00053         xtcav_camera = psana.Source('DetInfo(XrayTransportDiagnostic.0:Opal1000.0)')
00054         xtcav_type=psana.Camera.FrameV1
00055         
00056         #Stores for environment variables    
00057         configStore=dataSource.env().configStore();
00058         epicsStore=dataSource.env().epicsStore();
00059 
00060         n=0  #Counter for the total number of xtcav images processed
00061          
00062         runs=numpy.array([],dtype=int) #Array that contains the run processed run numbers
00063 
00064         #for r,run in enumerate(dataSource.runs()): 
00065         for r in [0]:
00066             run=dataSource.runs().next(); #This line and the previous line are a temporal hack to go only through the first run, that avoids an unexpected block when calling next at the iterator, when there are not remaining runs.
00067             runs = numpy.append(runs,run.run());
00068             n_r=0        #Counter for the total number of xtcav images processed within the run
00069             
00070             #for e, evt in enumerate(dataSource.events()):
00071             times = run.times()
00072             for t in range(len(times)-1,-1,-1): #Starting from the back, to avoid waits in the cases where there are not xtcav images for the first shots
00073                 evt=run.event(times[t])
00074             
00075                 #ignore shots without xtcav, because we can get
00076                 #incorrect EPICS information (e.g. ROI).  this is
00077                 #a workaround for the fact that xtcav only records
00078                 #epics on shots where it has camera data, as well
00079                 #as an incorrect design in psana where epics information
00080                 #is not stored per-shot (it is in a more global object
00081                 #called "Env")
00082                 frame = evt.get(xtcav_type, xtcav_camera) 
00083                 if frame is None: continue
00084 
00085                 if not 'ROI_XTCAV' in locals():   #After the first event the epics store should contain the ROI of the xtcav images, that let us get the x and y vectors
00086                     ROI_XTCAV,ok=xtup.GetXTCAVImageROI(epicsStore)             
00087                     if not ok: #If the information is not good, we try next event
00088                         del ROI_XTCAV
00089                         continue
00090                     accumulator_xtcav=np.zeros(( ROI_XTCAV['yN'],ROI_XTCAV['xN']), dtype=np.float64)
00091                             
00092                 if frame:                       #For each shot that contains an xtcav frame we retrieve it and add it to the accumulators
00093                     img=frame.data16().astype(np.float64)
00094                     
00095                     n=n+1
00096                     n_r=n_r+1
00097                     
00098                     accumulator_xtcav=accumulator_xtcav+img 
00099                     
00100                 if n_r % 5 == 0:
00101                     sys.stdout.write('\r%.1f %% done, %d / %d' % ( float(n_r) / self._maxshots*100, n_r,self._maxshots ))
00102                     sys.stdout.flush()   
00103                 if n_r>=self._maxshots:                    #After a certain number of shots we stop (Ideally this would be an argument, rather than a hardcoded value)
00104                     sys.stdout.write('\n')
00105                     break                          
00106         #At the end of the program the total accumulator is saved     
00107         db=DarkBackground()
00108         db.n=n
00109         db.image=accumulator_xtcav/n
00110         db.ROI=ROI_XTCAV
00111         db.runs=runs
00112         
00113         if not self._validityrange:
00114             validityrange=[runs[0], 'end']
00115         else:
00116             validityrange=self._validityrange
00117             
00118         cp=CalibrationPaths(dataSource.env(),self._calpath)
00119         file=cp.newCalFileName('pedestals',validityrange[0],validityrange[1])
00120         
00121         if savetofile:
00122             db.Save(file)
00123         
00124     def SetValidityRange(self,runBegin,runEnd='end'):
00125         """Sets the validity range for the generated reference.
00126 
00127         Args:
00128             runBegin (int): First run in the range.
00129             runEnd (int or str): Last run in the range (use 'end' to leave the range open)..
00130 
00131         """
00132         self._validityrange=[runBegin, runEnd];
00133     
00134     #Access to the different properties: here we can change flags when a parameter is changed, or check the validity of the property
00135     @property
00136     def maxshots(self):
00137         return self._maxshots
00138     @maxshots.setter
00139     def maxshots(self, maxshots):
00140         self._maxshots = maxshots     
00141     @property        
00142     def experiment(self):
00143         return self._experiment
00144     @experiment.setter
00145     def experiment(self, experiment):
00146         self._experiment = experiment
00147     @property
00148     def runs(self):
00149         return self._runs
00150     @runs.setter
00151     def runs(self, runs):
00152         self._runs = runs       
00153     @property
00154     def calibrationpath(self):
00155         return self._calpath
00156     @calibrationpath.setter
00157     def calibrationpath(self, calpath):
00158         self._calpath = calpath
00159 

Generated on 19 Dec 2016 for PSDMSoftware by  doxygen 1.4.7