source: fact/tools/pyscripts/pyfact/pynew.py@ 13254

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