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

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