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

Last change on this file since 13141 was 13141, checked in by neise, 13 years ago
moved newer pyfact_rename.py to pyfact.py ... keeping its history hopefully
  • Property svn:executable set to *
File size: 10.4 KB
Line 
1#!/usr/bin/python
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
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 """ initialize object
33
34 open data file and calibration data file
35 get basic information about the data in data_file_name
36 allocate buffers for data access
37
38 data_file_name : fits or fits.gz file of the data including the path
39 calib_file_name : fits or fits.gz file containing DRS calibration data
40 baseline_file_name : npy file containing the baseline values
41
42 """
43
44 self.data_file_name = data_file_name
45 self.calib_file_name = calib_file_name
46 self.baseline_file_name = baseline_file_name
47
48 self.user_action_calib = user_action_calib
49
50 # baseline correction: True / False
51 if len(baseline_file_name) == 0:
52 self.correct_baseline = False
53 else:
54 self.correct_baseline = True
55
56 # access data file
57 try:
58 data_file = fits(self.data_file_name)
59 except IOError:
60 print 'problem accessing data file: ', data_file_name
61 raise # stop ! no data
62 #: data file (fits object)
63 self.data_file = data_file
64
65 # get basic information about the data file
66 #: region of interest (number of DRS slices read)
67 self.nroi = data_file.GetUInt('NROI')
68 #: number of pixels (should be 1440)
69 self.npix = data_file.GetUInt('NPIX')
70 #: number of events in the data run
71 self.nevents = data_file.GetNumRows()
72
73 # allocate the data memories
74 self.event_id = c_ulong()
75 self.trigger_type = c_ushort()
76 #: 1D array with raw data
77 self.data = np.zeros( self.npix * self.nroi, np.int16 )
78 #: slice where drs readout started
79 self.start_cells = np.zeros( self.npix, np.int16 )
80 #: time when the FAD was triggered, in some strange units...
81 self.board_times = np.zeros( 40, np.int32 )
82
83 # set the pointers to the data++
84 data_file.SetPtrAddress('EventNum', self.event_id)
85 data_file.SetPtrAddress('TriggerType', self.trigger_type)
86 data_file.SetPtrAddress('StartCellData', self.start_cells)
87 data_file.SetPtrAddress('Data', self.data)
88 data_file.SetPtrAddress('BoardTime', self.board_times)
89
90 # open the calibration file
91 try:
92 calib_file = fits(self.calib_file_name)
93 except IOError:
94 print 'problem accessing calibration file: ', calib_file_name
95 raise
96 #: drs calibration file
97 self.calib_file = calib_file
98
99 baseline_mean = calib_file.GetN('BaselineMean')
100 gain_mean = calib_file.GetN('GainMean')
101 trigger_offset_mean = calib_file.GetN('TriggerOffsetMean')
102
103 self.blm = np.zeros(baseline_mean, np.float32)
104 self.gm = np.zeros(gain_mean, np.float32)
105 self.tom = np.zeros(trigger_offset_mean, np.float32)
106
107 self.Nblm = baseline_mean / self.npix
108 self.Ngm = gain_mean / self.npix
109 self.Ntom = trigger_offset_mean / self.npix
110
111 calib_file.SetPtrAddress('BaselineMean', self.blm)
112 calib_file.SetPtrAddress('GainMean', self.gm)
113 calib_file.SetPtrAddress('TriggerOffsetMean', self.tom)
114 calib_file.GetRow(0)
115
116 self.v_bsl = np.zeros(self.npix) # array of baseline values (all ZERO)
117 self.data_saverage_out = None
118 self.pulse_time_of_maximum = None
119 self.pulse_amplitude = None
120
121 def __iter__(self):
122 """ iterator """
123 return self
124
125 def __add__(self, jump_over):
126 self.data_file.GetRow(jump_over)
127 return self
128
129 def next(self):
130 """ used by __iter__ """
131
132 if self.data_file.GetNextRow() == False:
133 raise StopIteration
134 else:
135 self.calibrate_drs_amplitude()
136
137 #print 'nevents = ', self.nevents, 'event_id = ', self.event_id.value
138
139 return self.acal_data, self.start_cells, self.trigger_type.value
140
141 def next_event(self):
142 """ load the next event from disk and calibrate it
143
144 """
145
146 self.data_file.GetNextRow()
147 self.calibrate_drs_amplitude()
148
149 def calibrate_drs_amplitude(self):
150 """ perform the drs amplitude calibration of the event data
151
152 """
153
154 to_mV = 2000./4096.
155 #: 2D array with amplitude calibrated dat in mV
156 acal_data = self.data * to_mV # convert ADC counts to mV
157
158 # make 2D arrays: row = pixel, col = drs_slice
159 acal_data = np.reshape(acal_data, (self.npix, self.nroi) )
160 blm = np.reshape(self.blm, (self.npix, self.Nblm) )
161 tom = np.reshape(self.tom, (self.npix, self.Ntom) )
162 gm = np.reshape(self.gm, (self.npix, self.Ngm) )
163
164 for pixel in range( self.npix ):
165 # rotate the pixel baseline mean to the Data startCell
166 blm_pixel = np.roll( blm[pixel,:], -self.start_cells[pixel] )
167 tom_pixel = np.roll( tom[pixel,:], -self.start_cells[pixel] )
168 gm_pixel = np.roll( gm[pixel,:], -self.start_cells[pixel] )
169 acal_data[pixel,:] -= blm_pixel[0:self.nroi]
170 acal_data[pixel,:] -= tom_pixel[0:self.nroi]
171 acal_data[pixel,:] /= gm_pixel[0:self.nroi]
172
173 self.acal_data = acal_data * 1907.35
174
175 #print 'blm _pyfact', blm[0,0:20]
176 #t = np.roll( blm[0,:], -self.start_cells[0] )
177 #print 'blm _pyfact', t[0:20]
178 #print 'start_pyfact: ', self.start_cells[0]
179 #print 'acal _pyfact: ', self.acal_data[0,0:10]
180 #t = np.roll( gm[0,:], -self.start_cells[0] )
181 #print 'gm _pyfact: ', t[0:10]
182 self.user_action_calib( self.acal_data,
183 np.reshape(self.data, (self.npix, self.nroi) ), blm, tom, gm, self.start_cells, self.nroi)
184
185
186 def baseline_read_values(self, file, bsl_hist='bsl_sum/hplt_mean'):
187 """
188
189 open ROOT file with baseline histogram and read baseline values
190 file name of the root file
191 bsl_hist path to the histogram containing the basline values
192
193 """
194
195 try:
196 f = TFile(file)
197 except:
198 print 'Baseline data file could not be read: ', file
199 return
200
201 h = f.Get(bsl_hist)
202
203 for i in range(self.npix):
204 self.v_bsl[i] = h.GetBinContent(i+1)
205
206 f.Close()
207
208 def baseline_correct(self):
209 """ subtract baseline from the data
210
211 """
212
213 for pixel in range(self.npix):
214 self.acal_data[pixel,:] -= self.v_bsl[pixel]
215
216 def info(self):
217 """ print run information
218
219 """
220
221 print 'data file: ', data_file_name
222 print 'calib file: ', calib_file_name
223 print 'calibration file'
224 print 'N baseline_mean: ', self.Nblm
225 print 'N gain mean: ', self.Ngm
226 print 'N TriggeroffsetMean: ', self.Ntom
227
228# -----------------------------------------------------------------------------
229class fnames( object ):
230 """ organize file names of a FACT data run
231
232 """
233
234 def __init__(self, specifier = ['012', '023', '2011', '11', '24'],
235 rpath = '/scratch_nfs/res/bsl/',
236 zipped = True):
237 """
238 specifier : list of strings defined as:
239 [ 'DRS calibration file', 'Data file', 'YYYY', 'MM', 'DD']
240
241 rpath : directory path for the results; YYYYMMDD will be appended to rpath
242 zipped : use zipped (True) or unzipped (Data)
243
244 """
245
246 self.specifier = specifier
247 self.rpath = rpath
248 self.zipped = zipped
249
250 self.make( self.specifier, self.rpath, self.zipped )
251
252
253 def make( self, specifier, rpath, zipped ):
254 """ create (make) the filenames
255
256 names : dictionary of filenames, tags { 'data', 'drscal', 'results' }
257 data : name of the data file
258 drscal : name of the drs calibration file
259 results : radikal of file name(s) for results (to be completed by suffixes)
260 """
261
262 self.specifier = specifier
263
264 if zipped:
265 dpath = '/data00/fact-construction/raw/'
266 ext = '.fits.gz'
267 else:
268 dpath = '/data03/fact-construction/raw/'
269 ext = '.fits'
270
271 year = specifier[2]
272 month = specifier[3]
273 day = specifier[4]
274
275 yyyymmdd = year + month + day
276 dfile = specifier[1]
277 cfile = specifier[0]
278
279 rpath = rpath + yyyymmdd + '/'
280 self.rpath = rpath
281 self.names = {}
282
283 tmp = dpath + year + '/' + month + '/' + day + '/' + yyyymmdd + '_'
284 self.names['data'] = tmp + dfile + ext
285 self.names['drscal'] = tmp + cfile + '.drs' + ext
286 self.names['results'] = rpath + yyyymmdd + '_' + dfile + '_' + cfile
287
288 self.data = self.names['data']
289 self.drscal = self.names['drscal']
290 self.results = self.names['results']
291
292 def info( self ):
293 """ print complete filenames
294
295 """
296
297 print 'file names:'
298 print 'data: ', self.names['data']
299 print 'drs-cal: ', self.names['drscal']
300 print 'results: ', self.names['results']
301
302# end of class definition: fnames( object )
303
304def _test_iter():
305 """ test for function __iter__ """
306
307# data_file_name = '/data00/fact-construction/raw/2011/11/24/20111124_111.fits.gz'
308# calib_file_name = data_file_name =
309 data_file_name = '/home/luster/win7/FACT/data/raw/20120114/20120114_028.fits.gz'
310 calib_file_name = '/home/luster/win7/FACT/data/raw/20120114/20120114_022.drs.fits.gz'
311 run = RawData( data_file_name, calib_file_name )
312
313 for data, scell, tt in run:
314 print 'data[0,0] = ', data[0,0], "start_cell[0] =", scell[0], "trigger type = ", tt
315
316
317if __name__ == '__main__':
318 """ tests """
319
320 _test_iter()
Note: See TracBrowser for help on using the repository browser.