source: fact/tools/pyscripts/pyfact/pyfact.py@ 13323

Last change on this file since 13323 was 13323, checked in by lusterma, 12 years ago
set a data path which would run at the cluster
  • Property svn:executable set to *
File size: 11.9 KB
Line 
1#!/usr/bin/python -tt
2#
3# Werner Lustermann
4# ETH Zurich
5#
6from ctypes import *
7import numpy as np
8from scipy import signal
9
10# get the ROOT stuff + my shared libs
11from ROOT import gSystem
12# fitslib.so is made from fits.h and is used to access the data
13gSystem.Load('fits_h.so')
14from ROOT import *
15
16
17class RawData( object ):
18 """ raw data access and calibration
19
20 - open raw data file and drs calibration file
21 - performs amplitude calibration
22 - performs baseline substraction if wanted
23 - provides all data in an array:
24 row = number of pixel
25 col = length of region of interest
26
27 """
28
29 def __init__(self, data_file_name, calib_file_name,
30 user_action_calib=lambda acal_data, data, blm, tom, gm, scells, nroi: None,
31 baseline_file_name='',
32 return_dict = None):
33 """ initialize object
34
35 open data file and calibration data file
36 get basic information about the data in data_file_name
37 allocate buffers for data access
38
39 data_file_name : fits or fits.gz file of the data including the path
40 calib_file_name : fits or fits.gz file containing DRS calibration data
41 baseline_file_name : npy file containing the baseline values
42 """
43 # manual implementation of default value, but I need to find out
44 # if the user of this class is aware of the new option
45 if return_dict == None:
46 print 'Warning: Rawdata.__init__() has a new option "return_dict"'
47 print 'the default value of this option is False, so nothing changes for you at the moment.'
48 print
49 print 'you probably want, to get a dictionary out of the next() method anyway'
50 print ' so please change your scripts and set this option to True, for the moment'
51 print 'e.g. like this: run = RawData(data_filename, calib_filename, return_dict = True)'
52 print "after a while, the default value, will turn to True .. so you don't have to give the option anymore"
53 print 'and some time later, the option will not be supported anymore'
54 return_dict = False
55
56 self.return_dict = return_dict
57
58 self.data_file_name = data_file_name
59 self.calib_file_name = calib_file_name
60 self.baseline_file_name = baseline_file_name
61
62 self.user_action_calib = user_action_calib
63
64 # baseline correction: True / False
65 if len(baseline_file_name) == 0:
66 self.correct_baseline = False
67 else:
68 self.correct_baseline = True
69
70 # access data file
71 try:
72 data_file = fits(self.data_file_name)
73 except IOError:
74 print 'problem accessing data file: ', data_file_name
75 raise # stop ! no data
76 #: data file (fits object)
77 self.data_file = data_file
78
79 # get basic information about the data file
80 #: region of interest (number of DRS slices read)
81 self.nroi = data_file.GetUInt('NROI')
82 #: number of pixels (should be 1440)
83 self.npix = data_file.GetUInt('NPIX')
84 #: number of events in the data run
85 self.nevents = data_file.GetNumRows()
86
87 # allocate the data memories
88 self.event_id = c_ulong()
89 self.trigger_type = c_ushort()
90 #: 1D array with raw data
91 self.data = np.zeros( self.npix * self.nroi, np.int16 )
92 #: slice where drs readout started
93 self.start_cells = np.zeros( self.npix, np.int16 )
94 #: time when the FAD was triggered, in some strange units...
95 self.board_times = np.zeros( 40, np.int32 )
96
97 # set the pointers to the data++
98 data_file.SetPtrAddress('EventNum', self.event_id)
99 data_file.SetPtrAddress('TriggerType', self.trigger_type)
100 data_file.SetPtrAddress('StartCellData', self.start_cells)
101 data_file.SetPtrAddress('Data', self.data)
102 data_file.SetPtrAddress('BoardTime', self.board_times)
103
104 # open the calibration file
105 try:
106 calib_file = fits(self.calib_file_name)
107 except IOError:
108 print 'problem accessing calibration file: ', calib_file_name
109 raise
110 #: drs calibration file
111 self.calib_file = calib_file
112
113 baseline_mean = calib_file.GetN('BaselineMean')
114 gain_mean = calib_file.GetN('GainMean')
115 trigger_offset_mean = calib_file.GetN('TriggerOffsetMean')
116
117 self.blm = np.zeros(baseline_mean, np.float32)
118 self.gm = np.zeros(gain_mean, np.float32)
119 self.tom = np.zeros(trigger_offset_mean, np.float32)
120
121 self.Nblm = baseline_mean / self.npix
122 self.Ngm = gain_mean / self.npix
123 self.Ntom = trigger_offset_mean / self.npix
124
125 calib_file.SetPtrAddress('BaselineMean', self.blm)
126 calib_file.SetPtrAddress('GainMean', self.gm)
127 calib_file.SetPtrAddress('TriggerOffsetMean', self.tom)
128 calib_file.GetRow(0)
129
130 self.v_bsl = np.zeros(self.npix) # array of baseline values (all ZERO)
131
132 def __iter__(self):
133 """ iterator """
134 return self
135
136 def __add__(self, jump_over):
137 self.data_file.GetRow(jump_over)
138 return self
139
140 def next(self):
141 """ used by __iter__ """
142
143 if self.data_file.GetNextRow() == False:
144 raise StopIteration
145 else:
146 self.calibrate_drs_amplitude()
147
148 #print 'nevents = ', self.nevents, 'event_id = ', self.event_id.value
149 if self.return_dict:
150 return self.__dict__
151 else:
152 return self.acal_data, self.start_cells, self.trigger_type.value
153
154 def next_event(self):
155 """ load the next event from disk and calibrate it
156
157 """
158
159 self.data_file.GetNextRow()
160 self.calibrate_drs_amplitude()
161
162 def calibrate_drs_amplitude(self):
163 """ perform the drs amplitude calibration of the event data
164
165 """
166
167 to_mV = 2000./4096.
168 #: 2D array with amplitude calibrated dat in mV
169 acal_data = self.data * to_mV # convert ADC counts to mV
170
171 # make 2D arrays: row = pixel, col = drs_slice
172 acal_data = np.reshape(acal_data, (self.npix, self.nroi) )
173 blm = np.reshape(self.blm, (self.npix, self.Nblm) )
174 tom = np.reshape(self.tom, (self.npix, self.Ntom) )
175 gm = np.reshape(self.gm, (self.npix, self.Ngm) )
176
177 for pixel in range( self.npix ):
178 # rotate the pixel baseline mean to the Data startCell
179 blm_pixel = np.roll( blm[pixel,:], -self.start_cells[pixel] )
180 # rotate the pixel gain mean to the Data startCell
181 gm_pixel = np.roll( gm[pixel,:], -self.start_cells[pixel] )
182 # the 'trigger offset mean' does not need to be rolled
183 # on the contrary, it seems there is an offset in the DRS data,
184 # which is related to its distance to the startCell, not to its
185 # distance to the beginning of the physical pipeline in the DRS chip
186 tom_pixel = tom[pixel,:]
187
188 acal_data[pixel,:] -= blm_pixel[0:self.nroi]
189 acal_data[pixel,:] -= tom_pixel[0:self.nroi]
190 acal_data[pixel,:] /= gm_pixel[0:self.nroi]
191
192 self.acal_data = acal_data * 1907.35
193
194 #print 'blm _pyfact', blm[0,0:20]
195 #t = np.roll( blm[0,:], -self.start_cells[0] )
196 #print 'blm _pyfact', t[0:20]
197 #print 'start_pyfact: ', self.start_cells[0]
198 #print 'acal _pyfact: ', self.acal_data[0,0:10]
199 #t = np.roll( gm[0,:], -self.start_cells[0] )
200 #print 'gm _pyfact: ', t[0:10]
201 self.user_action_calib( self.acal_data,
202 np.reshape(self.data, (self.npix, self.nroi) ), blm, tom, gm, self.start_cells, self.nroi)
203
204
205 def baseline_read_values(self, file, bsl_hist='bsl_sum/hplt_mean'):
206 """
207
208 open ROOT file with baseline histogram and read baseline values
209 file name of the root file
210 bsl_hist path to the histogram containing the basline values
211
212 """
213
214 try:
215 f = TFile(file)
216 except:
217 print 'Baseline data file could not be read: ', file
218 return
219
220 h = f.Get(bsl_hist)
221
222 for i in range(self.npix):
223 self.v_bsl[i] = h.GetBinContent(i+1)
224
225 f.Close()
226
227 def baseline_correct(self):
228 """ subtract baseline from the data
229
230 """
231
232 for pixel in range(self.npix):
233 self.acal_data[pixel,:] -= self.v_bsl[pixel]
234
235 def info(self):
236 """ print run information
237
238 """
239
240 print 'data file: ', data_file_name
241 print 'calib file: ', calib_file_name
242 print 'calibration file'
243 print 'N baseline_mean: ', self.Nblm
244 print 'N gain mean: ', self.Ngm
245 print 'N TriggeroffsetMean: ', self.Ntom
246
247# -----------------------------------------------------------------------------
248class fnames( object ):
249 """ organize file names of a FACT data run
250
251 """
252
253 def __init__(self, specifier = ['012', '023', '2011', '11', '24'],
254 rpath = '/scratch_nfs/res/bsl/',
255 zipped = True):
256 """
257 specifier : list of strings defined as:
258 [ 'DRS calibration file', 'Data file', 'YYYY', 'MM', 'DD']
259
260 rpath : directory path for the results; YYYYMMDD will be appended to rpath
261 zipped : use zipped (True) or unzipped (Data)
262
263 """
264
265 self.specifier = specifier
266 self.rpath = rpath
267 self.zipped = zipped
268
269 self.make( self.specifier, self.rpath, self.zipped )
270
271
272 def make( self, specifier, rpath, zipped ):
273 """ create (make) the filenames
274
275 names : dictionary of filenames, tags { 'data', 'drscal', 'results' }
276 data : name of the data file
277 drscal : name of the drs calibration file
278 results : radikal of file name(s) for results (to be completed by suffixes)
279 """
280
281 self.specifier = specifier
282
283 if zipped:
284 dpath = '/data00/fact-construction/raw/'
285 ext = '.fits.gz'
286 else:
287 dpath = '/data03/fact-construction/raw/'
288 ext = '.fits'
289
290 year = specifier[2]
291 month = specifier[3]
292 day = specifier[4]
293
294 yyyymmdd = year + month + day
295 dfile = specifier[1]
296 cfile = specifier[0]
297
298 rpath = rpath + yyyymmdd + '/'
299 self.rpath = rpath
300 self.names = {}
301
302 tmp = dpath + year + '/' + month + '/' + day + '/' + yyyymmdd + '_'
303 self.names['data'] = tmp + dfile + ext
304 self.names['drscal'] = tmp + cfile + '.drs' + ext
305 self.names['results'] = rpath + yyyymmdd + '_' + dfile + '_' + cfile
306
307 self.data = self.names['data']
308 self.drscal = self.names['drscal']
309 self.results = self.names['results']
310
311 def info( self ):
312 """ print complete filenames
313
314 """
315
316 print 'file names:'
317 print 'data: ', self.names['data']
318 print 'drs-cal: ', self.names['drscal']
319 print 'results: ', self.names['results']
320
321# end of class definition: fnames( object )
322
323def _test_iter( nevents ):
324 """ test for function __iter__ """
325
326 data_file_name = '/data00/fact-construction/raw/2011/11/24/20111124_117.fits.gz'
327 calib_file_name = '/data00/fact-construction/raw/2011/11/24/20111124_114.drs.fits.gz'
328# data_file_name = '/home/luster/win7/FACT/data/raw/20120114/20120114_028.fits.gz'
329# calib_file_name = '/home/luster/win7/FACT/data/raw/20120114/20120114_022.drs.fits.gz'
330 run = RawData( data_file_name, calib_file_name )
331
332 for data, scell, tt in run:
333 print 'ev ', run.event_id.value, 'data[0,0] = ', data[0,0], 'start_cell[0] = ', scell[0], 'trigger type = ', tt
334 if run.event_id.value == nevents:
335 break
336
337
338if __name__ == '__main__':
339 """ tests """
340
341 _test_iter(10)
Note: See TracBrowser for help on using the repository browser.