| 1 | #!/usr/bin/python2.6
 | 
|---|
| 2 | #
 | 
|---|
| 3 | # Werner Lustermann
 | 
|---|
| 4 | # ETH Zurich
 | 
|---|
| 5 | #
 | 
|---|
| 6 | from ctypes import *
 | 
|---|
| 7 | 
 | 
|---|
| 8 | # get the ROOT stuff + my shared libs
 | 
|---|
| 9 | from ROOT import gSystem
 | 
|---|
| 10 | gSystem.Load('pyfits_h.so')
 | 
|---|
| 11 | from ROOT import *
 | 
|---|
| 12 | 
 | 
|---|
| 13 | import numpy as np
 | 
|---|
| 14 | 
 | 
|---|
| 15 | 
 | 
|---|
| 16 | class rawdata( object ):
 | 
|---|
| 17 |     """
 | 
|---|
| 18 |     raw data access and calibration
 | 
|---|
| 19 |     """
 | 
|---|
| 20 |     def __init__( self, dfname,  calfname ):
 | 
|---|
| 21 |         """
 | 
|---|
| 22 |         open data file and calibration data file
 | 
|---|
| 23 |         get basic information about the data inf dfname
 | 
|---|
| 24 |         allocate buffers for data access
 | 
|---|
| 25 | 
 | 
|---|
| 26 |         dfname   - fits or fits.gz file containing the data including the path
 | 
|---|
| 27 |         calfname - fits or fits.gz file containing DRS calibration data
 | 
|---|
| 28 |         """
 | 
|---|
| 29 |         self.dfname   = dfname
 | 
|---|
| 30 |         self.calfname = calfname
 | 
|---|
| 31 |         
 | 
|---|
| 32 |         # access data file
 | 
|---|
| 33 |         try:
 | 
|---|
| 34 |             df = fits( self.dfname )
 | 
|---|
| 35 |         except IOError:
 | 
|---|
| 36 |             print 'problem accessing data file: ', dfname
 | 
|---|
| 37 |             raise # stop ! no data
 | 
|---|
| 38 |         self.df = df
 | 
|---|
| 39 |         
 | 
|---|
| 40 |         # get basic information about the data file
 | 
|---|
| 41 |         self.NROI    = df.GetUInt( 'NROI' ) # region of interest (length of DRS pipeline read out)
 | 
|---|
| 42 |         self.NPIX    = df.GetUInt( 'NPIX' ) # number of pixels (should be 1440)
 | 
|---|
| 43 |         self.NEvents = df.GetNumRows()      # find number of events
 | 
|---|
| 44 |         # allocate the data memories
 | 
|---|
| 45 |         self.evNum = c_ulong()
 | 
|---|
| 46 |         self.Data  = np.zeros( self.NPIX * self.NROI, np.int16 ) 
 | 
|---|
| 47 |         self.startCells = np.zeros( self.NPIX, np.int16 )
 | 
|---|
| 48 |         # set the pointers to the data++
 | 
|---|
| 49 |         df.SetPtrAddress( 'EventNum', self.evNum )
 | 
|---|
| 50 |         df.SetPtrAddress( 'StartCellData', self.startCells ) # DRS readout start cell
 | 
|---|
| 51 |         df.SetPtrAddress( 'Data', self.Data ) # this is what you would expect
 | 
|---|
| 52 |         # df.GetNextRow() # access the first event
 | 
|---|
| 53 |         
 | 
|---|
| 54 |         # access calibration file
 | 
|---|
| 55 |         try:
 | 
|---|
| 56 |             calf = fits( self.calfname )
 | 
|---|
| 57 |         except IOError:
 | 
|---|
| 58 |             print 'problem accessing calibration file: ', calfname
 | 
|---|
| 59 |             raise
 | 
|---|
| 60 |         self.calf = calf
 | 
|---|
| 61 |         #
 | 
|---|
| 62 |         BaselineMean      = calf.GetN('BaselineMean')
 | 
|---|
| 63 |         GainMean          = calf.GetN('GainMean')
 | 
|---|
| 64 |         TriggerOffsetMean = calf.GetN('TriggerOffsetMean')
 | 
|---|
| 65 | 
 | 
|---|
| 66 |         self.blm = np.zeros( BaselineMean, np.float32 )
 | 
|---|
| 67 |         self.gm  = np.zeros( GainMean, np.float32 )
 | 
|---|
| 68 |         self.tom = np.zeros( TriggerOffsetMean, np.float32 )
 | 
|---|
| 69 | 
 | 
|---|
| 70 |         self.Nblm = BaselineMean / self.NPIX
 | 
|---|
| 71 |         self.Ngm  = GainMean / self.NPIX
 | 
|---|
| 72 |         self.Ntom  = TriggerOffsetMean / self.NPIX
 | 
|---|
| 73 | 
 | 
|---|
| 74 |         calf.SetPtrAddress( 'BaselineMean', self.blm )
 | 
|---|
| 75 |         calf.SetPtrAddress( 'GainMean', self.gm )
 | 
|---|
| 76 |         calf.SetPtrAddress( 'TriggerOffsetMean', self.tom )
 | 
|---|
| 77 |         calf.GetRow(0)
 | 
|---|
| 78 | 
 | 
|---|
| 79 |         self.v_bsl = np.zeros( self.NPIX ) # array with baseline values (all ZERO)
 | 
|---|
| 80 | 
 | 
|---|
| 81 |     def next( self ):
 | 
|---|
| 82 |         """
 | 
|---|
| 83 |         load the next event from disk and calibrate it
 | 
|---|
| 84 |         """
 | 
|---|
| 85 |         self.df.GetNextRow()
 | 
|---|
| 86 |         self.calibrate_drsAmplitude()
 | 
|---|
| 87 | 
 | 
|---|
| 88 |         
 | 
|---|
| 89 |     def calibrate_drsAmplitude( self ):
 | 
|---|
| 90 |         """
 | 
|---|
| 91 |         perform amplitude calibration for the event 
 | 
|---|
| 92 |         """
 | 
|---|
| 93 |         tomV = 2000./4096.
 | 
|---|
| 94 |         acalData = self.Data * tomV # convert into mV
 | 
|---|
| 95 | 
 | 
|---|
| 96 |         # reshape arrays: row = pixel, col = drs_slice
 | 
|---|
| 97 |         acalData = np.reshape( acalData, (self.NPIX, self.NROI) )
 | 
|---|
| 98 |         blm = np.reshape( self.blm, (self.NPIX, self.NROI) )
 | 
|---|
| 99 |         tom = np.reshape( self.tom, (self.NPIX, self.NROI) )
 | 
|---|
| 100 |         gm  = np.reshape( self.gm,  (self.NPIX, self.NROI) )
 | 
|---|
| 101 |         
 | 
|---|
| 102 |         # print 'acal Data ', acalData.shape
 | 
|---|
| 103 |         # print 'blm shape ', blm.shape
 | 
|---|
| 104 |         # print 'gm shape  ', gm.shape
 | 
|---|
| 105 |         
 | 
|---|
| 106 |         for pixel in range( self.NPIX ):
 | 
|---|
| 107 |             # rotate the pixel baseline mean to the Data startCell
 | 
|---|
| 108 |             blm_pixel = np.roll( blm[pixel,:], -self.startCells[pixel] )
 | 
|---|
| 109 |             acalData[pixel,:] -= blm_pixel[0:self.NROI]
 | 
|---|
| 110 |             acalData[pixel,:] -= tom[pixel, 0:self.NROI]
 | 
|---|
| 111 |             acalData[pixel,:] /= gm[pixel,  0:self.NROI]
 | 
|---|
| 112 |             
 | 
|---|
| 113 |         self.acalData = acalData * 1907.35
 | 
|---|
| 114 |     
 | 
|---|
| 115 |         # print 'acalData ', self.acalData[0:2,0:20]
 | 
|---|
| 116 | 
 | 
|---|
| 117 |     def ReadBaseline( self, file, bsl_hist = 'bsl_sum/hplt_mean' ):
 | 
|---|
| 118 |         """
 | 
|---|
| 119 |         open ROOT file with baseline histogram and read baseline values
 | 
|---|
| 120 |         file       name of the root file
 | 
|---|
| 121 |         bsl_hist   path to the histogram containing the basline values
 | 
|---|
| 122 |         """
 | 
|---|
| 123 |         try:
 | 
|---|
| 124 |             f = TFile( file )
 | 
|---|
| 125 |         except:
 | 
|---|
| 126 |             print 'Baseline data file could not be read: ', file
 | 
|---|
| 127 |             return
 | 
|---|
| 128 |         
 | 
|---|
| 129 |         h = f.Get( bsl_hist )
 | 
|---|
| 130 | 
 | 
|---|
| 131 |         for i in range( self.NPIX ):
 | 
|---|
| 132 |             self.v_bsl[i] = h.GetBinContent( i+1 )
 | 
|---|
| 133 | 
 | 
|---|
| 134 |         f.Close()
 | 
|---|
| 135 | 
 | 
|---|
| 136 |         
 | 
|---|
| 137 |     def CorrectBaseline( self ):
 | 
|---|
| 138 |         """
 | 
|---|
| 139 |         apply baseline correction
 | 
|---|
| 140 |         """
 | 
|---|
| 141 |         for pixel in range( self.NPIX ):
 | 
|---|
| 142 |             self.acalData[pixel,:] -= self.v_bsl[pixel]
 | 
|---|
| 143 |             
 | 
|---|
| 144 |         
 | 
|---|
| 145 |     def info( self ):
 | 
|---|
| 146 |         """
 | 
|---|
| 147 |         print information
 | 
|---|
| 148 |         """
 | 
|---|
| 149 |         print 'data file:  ', dfname
 | 
|---|
| 150 |         print 'calib file: ', calfname
 | 
|---|
| 151 |         print '\ncalibration file'
 | 
|---|
| 152 |         print 'N BaselineMean: ', self.Nblm
 | 
|---|
| 153 |         print 'N GainMean: ', self.Ngm
 | 
|---|
| 154 |         print 'N TriggeroffsetMean: ', self.Ntom
 | 
|---|
| 155 |         
 | 
|---|
| 156 | 
 | 
|---|
| 157 | class histogramList( object ):
 | 
|---|
| 158 | 
 | 
|---|
| 159 |     def __init__( self, name ):
 | 
|---|
| 160 |         """ set the name and create empty lists """
 | 
|---|
| 161 |         self.name  = name         # name of the list
 | 
|---|
| 162 |         self.list  = []           # list of the histograms
 | 
|---|
| 163 |         self.dict  = {}           # dictionary of histograms
 | 
|---|
| 164 |         self.hList = TObjArray()  # list a la ROOT of the histograms
 | 
|---|
| 165 | 
 | 
|---|
| 166 |     def add( self, tag, h ):
 | 
|---|
| 167 |         self.list.append( h )
 | 
|---|
| 168 |         self.dict[tag] = h
 | 
|---|
| 169 |         self.hList.Add( h )
 | 
|---|
| 170 | 
 | 
|---|
| 171 | 
 | 
|---|
| 172 | class pixelHisto1d ( object ):
 | 
|---|
| 173 | 
 | 
|---|
| 174 |     def __init__( self, name, title, Nbin, first, last, xtitle, ytitle, NPIX ):
 | 
|---|
| 175 |         """
 | 
|---|
| 176 |         book one dimensional histograms for each pixel
 | 
|---|
| 177 |         """
 | 
|---|
| 178 |         self.name = name
 | 
|---|
| 179 | 
 | 
|---|
| 180 |         self.list = [ x for x in range( NPIX ) ]
 | 
|---|
| 181 |         self.hList = TObjArray()
 | 
|---|
| 182 | 
 | 
|---|
| 183 |         for pixel in range( NPIX ):
 | 
|---|
| 184 | 
 | 
|---|
| 185 |             hname  = name + ' ' + str( pixel )
 | 
|---|
| 186 |             htitle = title + ' ' + str( pixel )
 | 
|---|
| 187 |             self.list[pixel] = TH1F( hname, htitle, Nbin, first, last )
 | 
|---|
| 188 | 
 | 
|---|
| 189 |             self.list[pixel].GetXaxis().SetTitle( xtitle )
 | 
|---|
| 190 |             self.list[pixel].GetYaxis().SetTitle( ytitle )
 | 
|---|
| 191 |             self.hList.Add( self.list[pixel] )
 | 
|---|
| 192 | 
 | 
|---|
| 193 | 
 | 
|---|
| 194 | def SaveHistograms( histogramLists, fname = 'histo.root', opt = 'RECREATE' ):
 | 
|---|
| 195 |     """
 | 
|---|
| 196 |     Saves all histograms in all given histogram lists to a root file
 | 
|---|
| 197 |     Each histogram list is saved to a separate directory
 | 
|---|
| 198 |     """
 | 
|---|
| 199 |     rf = TFile( fname, opt)
 | 
|---|
| 200 |     
 | 
|---|
| 201 |     for list in histogramLists:
 | 
|---|
| 202 |         rf.mkdir( list.name )
 | 
|---|
| 203 |         rf.cd( list.name )
 | 
|---|
| 204 |         list.hList.Write()
 | 
|---|
| 205 | 
 | 
|---|
| 206 |     rf.Close()
 | 
|---|
| 207 | 
 | 
|---|
| 208 | # simple test method
 | 
|---|
| 209 | if __name__ == '__main__':
 | 
|---|
| 210 |     """
 | 
|---|
| 211 |     create an instance
 | 
|---|
| 212 |     """
 | 
|---|
| 213 |     dfname = '/data03/fact-construction/raw/2011/11/24/20111124_121.fits'
 | 
|---|
| 214 |     calfname = '/data03/fact-construction/raw/2011/11/24/20111124_111.drs.fits'
 | 
|---|
| 215 |     rd = rawdata( dfname, calfname )
 | 
|---|
| 216 |     rd.info()
 | 
|---|
| 217 |     rd.next()
 | 
|---|
| 218 |     
 | 
|---|
| 219 | # for i in range(10):
 | 
|---|
| 220 | #    df.GetNextRow() 
 | 
|---|
| 221 | 
 | 
|---|
| 222 | #    print 'evNum: ', evNum.value
 | 
|---|
| 223 | #    print 'startCells[0:9]: ', startCells[0:9]
 | 
|---|
| 224 | #    print 'evData[0:9]: ', evData[0:9]
 | 
|---|