source: fact/tools/rootmacros/DrsCalibration.C@ 12519

Last change on this file since 12519 was 12519, checked in by neise, 13 years ago
this way of subtracting TriggerOffset minimizes the mean and rms
  • Property svn:executable set to *
File size: 6.8 KB
Line 
1
2
3float getValue( int slice, int pixel,
4 vector<float> &drs_basemean,
5 vector<float> &drs_gainmean,
6 vector<float> &drs_triggeroffsetmean,
7 UInt_t RegionOfInterest,
8 vector<int16_t> AllPixelDataVector,
9 vector<int16_t> StartCellVector
10){
11 const float dconv = 2000/4096.0;
12
13 float vraw, vcal;
14
15 unsigned int pixel_pt;
16 unsigned int slice_pt;
17 unsigned int cal_pt;
18 unsigned int drs_cal_offset;
19
20 // printf("pixel = %d, slice = %d\n", slice, pixel);
21
22 pixel_pt = pixel * RegionOfInterest;
23 slice_pt = pixel_pt + slice;
24 drs_cal_offset = ( slice + StartCellVector[ pixel ] )%RegionOfInterest;
25 cal_pt = pixel_pt + drs_cal_offset;
26
27 vraw = AllPixelDataVector[ slice_pt ] * dconv;
28 vcal = ( vraw - drs_basemean[ cal_pt ] - drs_triggeroffsetmean[ slice_pt ] ) / drs_gainmean[ cal_pt ]*1907.35;
29
30 return( vcal );
31}
32
33
34
35// FACT raw data is stored in fits files in large vector<int16_t>. these
36// containt the data of the full camera for a single event.
37// in order to work with this data, one needs to extract the part, which
38// belongs to the current pixel and apply a DRS calibration, based on a dedicated
39// DRS calibration file.
40//
41// TODO: The calibration Data as well as the Data and StartCell vectors are a bit
42// massive to give this function as parameters.
43// better to have these vectors somehow bundled in classes like:
44// RawData - class and
45// DrsCalibration - class
46// those classes would be the result of
47// openDataFits() and
48// openCalibFits()
49//
50size_t applyDrsCalibration( vector<float> &destination,
51 int pixel,
52 int LeaveOutLeft,
53 int LeaveOutRight,
54 vector<float> &drs_basemean,
55 vector<float> &drs_gainmean,
56 vector<float> &drs_triggeroffsetmean,
57 UInt_t RegionOfInterest,
58 vector<int16_t> AllPixelDataVector,
59 vector<int16_t> StartCellVector,
60 int verbosityLevel
61){
62 // In order to minimize mem free and alloc actions
63 // the destination vector is only resized, if it is way too big
64 // or too small
65 size_t DestinationLength = RegionOfInterest-LeaveOutRight-LeaveOutLeft;
66 if ( destination.size() < DestinationLength || destination.size() > 2 * DestinationLength ){
67 destination.resize( DestinationLength );
68 }
69
70 // We do not entirely know how the calibration constants, which are saved in a filename.drs.fits file
71 // were calculated, so it is not fully clear how they should be applied to the raw data for calibration.
72 // apparently the calibration constants were transformed to the unit mV, which means we have to do the same to
73 // the raw data prior to apply the calibration
74 //
75 // on the FAD board, there is a 12bit ADC, with a 2.0V range, so the factor between ADC units and mV is
76 // ADC2mV = 2000/4096. = 0.48828125 (numerically exact)
77 //
78 // from the schematic of the FAD we learned, that the voltage at the ADC
79 // should be 1907.35 mV when the calibration DAC is set to 50000.
80 //
81 // One would further assume that the calibration constants are calculated like this:
82
83 // The DRS Offset of each bin in each channel is the mean value in this very bin,
84 // obtained from so called DRS pedestal data
85 // Its value is about -1820 ADC units or -910mV
86
87 // In order to obtain the DRS Gain of each bin of each channel
88 // again data is takes, with the calibration DAC set to 50000
89 // This is called DRS calibration data.
90 // We assume the DRS Offset is already subtracted from the DRS calibration data
91 // so the typical value is assumed to be ~3600 ADC units oder ~1800mV
92 // As mentioned before, the value *should* be 1907.35 mV
93 // So one might assume that the Gain is a number, which actually converts ~3600 ADC units into 1907.35mV for each bin of each channel.
94 // So that the calibration procedure looks like this
95 // TrueValue = (RawValue - Offset) * Gain
96 // The numerical value of Gain would differ slightly from the theoretical value of 2000/4096.
97 // But this is apparently not the case.
98 // The Gain, as it is stored in the DRS calibration file of FACT++ has numerical values
99 // around +1800.
100 // So it seems one should calibrate like this:
101 // TrueValue = (RawValue - Offset) / Gain * 1907.35
102
103 // When these calibrations are done, one ends up with a quite nice calibrated voltage.
104 // But it turns out that, if one returns the first measurement, and calculates the mean voltages
105 // in each bin of the now *logical* DRS pipeline, the mean voltage is not zero, but slightly varies
106 // So one can store these systematical deviations from zero in the logical pipeline as well, and subtract them.
107 // The remaining question is, when to subtract them.
108 // I assume, in the process of measuring this third calibration constant, the first two
109 // calibrations are already applied to the raw data.
110
111 // So the calculation of the calibrated volatage from some raw voltage works like this:
112 // assume the raw voltage is the s'th sample in channel c. While the Trigger made the DRS stopp in its t'th cell.
113 // note, that the DRS pipeline is always 1024 bins long. This is constant of the DRS4 chip.
114
115 // TrueValue[c][s] = ( RawValue[c][s] - Offset[c][ (c+t)%1024 ] ) / Gain[c][ (c+t)%1024 ] * 1907.35 - TriggerOffset[c][s]
116
117 const float dconv = 2000/4096.0;
118 float vraw;
119
120 if ( RegionOfInterest != AllPixelDataVector.size()/1440 ){
121 if (verbosityLevel > 0){
122 cout << "RegionOfInterest != AllPixelDataVector.size()/1440" << endl;
123 cout << "RegionOfInterest: " << RegionOfInterest << endl;
124 cout << "AllPixelDataVector.size(): " << AllPixelDataVector.size() << endl;
125 cout << "aborting" << endl;
126 }
127 return 0;
128 }
129
130 // the vector drs_triggeroffsetmean is not 1440 * 1024 entries long
131 // but has hopefully the length 1440 * RegionOfInterest (or longer)
132 if ( drs_triggeroffsetmean.size() < 1440*RegionOfInterest ){
133 if (verbosityLevel > 0){
134 cout << "Error: drs_triggeroffsetmean.size() < 1440*RegionOfInterest" << endl;
135 cout << "drs_triggeroffsetmean.size():" << drs_triggeroffsetmean.size() << endl;
136 cout << "RegionOfInterest" << RegionOfInterest << endl;
137 cout << "aborting" << endl;
138 }
139 return 0;
140 }
141
142 int DataPos, OffsetPos, TriggerOffsetPos;
143
144 for ( unsigned int sl = LeaveOutLeft; sl < RegionOfInterest-LeaveOutRight ; sl++){
145
146 DataPos = pixel * RegionOfInterest + sl;
147 // Offset and Gain vector *should look the same
148 OffsetPos = pixel * drs_basemean.size()/1440 + (sl + StartCellVector[pixel])%(drs_basemean.size()/1440);
149
150 TriggerOffsetPos = pixel * drs_triggeroffsetmean.size()/1440 + sl;
151
152 vraw = AllPixelDataVector[ DataPos ] * dconv;
153 vraw -= drs_basemean[ OffsetPos ];
154 vraw -= drs_triggeroffsetmean[ TriggerOffsetPos ];
155 vraw /= drs_gainmean[ OffsetPos ];
156 vraw *= 1907.35;
157
158// slice_pt = pixel_pt + sl;
159// drs_cal_offset = ( sl + StartCellVector[ pixel ] ) % RegionOfInterest;
160// cal_pt = pixel_pt + drs_cal_offset;
161// vraw = AllPixelDataVector[ slice_pt ] * dconv;
162// vcal = ( vraw - drs_basemean[ cal_pt ] - drs_triggeroffsetmean[ slice_pt ] ) / drs_gainmean[ cal_pt ]*1907.35;
163// destination.push_back(vcal);
164
165 destination[sl-LeaveOutLeft] = vraw;
166 }
167
168 return destination.size();
169}
Note: See TracBrowser for help on using the repository browser.