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

Last change on this file since 14731 was 13535, checked in by neise, 13 years ago
Makefile works
  • Property svn:executable set to *
File size: 6.9 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( vector<float> &destination,
54 int pixel,
55 int LeaveOutLeft,
56 int LeaveOutRight,
57 vector<float> &drs_basemean,
58 vector<float> &drs_gainmean,
59 vector<float> &drs_triggeroffsetmean,
60 unsigned int RegionOfInterest,
61 vector<int16_t> AllPixelDataVector,
62 vector<int16_t> StartCellVector,
63 int verbosityLevel
64){
65 // In order to minimize mem free and alloc actions
66 // the destination vector is only resized, if it is way too big
67 // or too small
68 size_t DestinationLength = RegionOfInterest-LeaveOutRight-LeaveOutLeft;
69 if ( destination.size() < DestinationLength || destination.size() > 2 * DestinationLength ){
70 destination.resize( DestinationLength );
71 }
72
73 // We do not entirely know how the calibration constants, which are saved in a filename.drs.fits file
74 // were calculated, so it is not fully clear how they should be applied to the raw data for calibration.
75 // apparently the calibration constants were transformed to the unit mV, which means we have to do the same to
76 // the raw data prior to apply the calibration
77 //
78 // on the FAD board, there is a 12bit ADC, with a 2.0V range, so the factor between ADC units and mV is
79 // ADC2mV = 2000/4096. = 0.48828125 (numerically exact)
80 //
81 // from the schematic of the FAD we learned, that the voltage at the ADC
82 // should be 1907.35 mV when the calibration DAC is set to 50000.
83 //
84 // One would further assume that the calibration constants are calculated like this:
85
86 // The DRS Offset of each bin in each channel is the mean value in this very bin,
87 // obtained from so called DRS pedestal data
88 // Its value is about -1820 ADC units or -910mV
89
90 // In order to obtain the DRS Gain of each bin of each channel
91 // again data is takes, with the calibration DAC set to 50000
92 // This is called DRS calibration data.
93 // We assume the DRS Offset is already subtracted from the DRS calibration data
94 // so the typical value is assumed to be ~3600 ADC units oder ~1800mV
95 // As mentioned before, the value *should* be 1907.35 mV
96 // 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.
97 // So that the calibration procedure looks like this
98 // TrueValue = (RawValue - Offset) * Gain
99 // The numerical value of Gain would differ slightly from the theoretical value of 2000/4096.
100 // But this is apparently not the case.
101 // The Gain, as it is stored in the DRS calibration file of FACT++ has numerical values
102 // around +1800.
103 // So it seems one should calibrate like this:
104 // TrueValue = (RawValue - Offset) / Gain * 1907.35
105
106 // When these calibrations are done, one ends up with a quite nice calibrated voltage.
107 // But it turns out that, if one returns the first measurement, and calculates the mean voltages
108 // in each bin of the now *logical* DRS pipeline, the mean voltage is not zero, but slightly varies
109 // So one can store these systematical deviations from zero in the logical pipeline as well, and subtract them.
110 // The remaining question is, when to subtract them.
111 // I assume, in the process of measuring this third calibration constant, the first two
112 // calibrations are already applied to the raw data.
113
114 // So the calculation of the calibrated volatage from some raw voltage works like this:
115 // assume the raw voltage is the s'th sample in channel c. While the Trigger made the DRS stopp in its t'th cell.
116 // note, that the DRS pipeline is always 1024 bins long. This is constant of the DRS4 chip.
117
118 // TrueValue[c][s] = ( RawValue[c][s] - Offset[c][ (c+t)%1024 ] ) / Gain[c][ (c+t)%1024 ] * 1907.35 - TriggerOffset[c][s]
119
120 const float dconv = 2000/4096.0;
121 float vraw;
122
123 if ( RegionOfInterest != AllPixelDataVector.size()/1440 ){
124 if (verbosityLevel > 0){
125 cout << "RegionOfInterest != AllPixelDataVector.size()/1440" << endl;
126 cout << "RegionOfInterest: " << RegionOfInterest << endl;
127 cout << "AllPixelDataVector.size(): " << AllPixelDataVector.size() << endl;
128 cout << "aborting" << endl;
129 }
130 return 0;
131 }
132
133 // the vector drs_triggeroffsetmean is not 1440 * 1024 entries long
134 // but has hopefully the length 1440 * RegionOfInterest (or longer)
135 if ( drs_triggeroffsetmean.size() < 1440*RegionOfInterest ){
136 if (verbosityLevel > 0){
137 cout << "Error: drs_triggeroffsetmean.size() < 1440*RegionOfInterest" << endl;
138 cout << "drs_triggeroffsetmean.size():" << drs_triggeroffsetmean.size() << endl;
139 cout << "RegionOfInterest" << RegionOfInterest << endl;
140 cout << "aborting" << endl;
141 }
142 return 0;
143 }
144
145 int DataPos, OffsetPos, TriggerOffsetPos;
146
147 for ( unsigned int sl = LeaveOutLeft; sl < RegionOfInterest-LeaveOutRight ; sl++){
148
149 DataPos = pixel * RegionOfInterest + sl;
150 // Offset and Gain vector *should look the same
151 OffsetPos = pixel * drs_basemean.size()/1440 + (sl + StartCellVector[pixel])%(drs_basemean.size()/1440);
152
153 TriggerOffsetPos = pixel * drs_triggeroffsetmean.size()/1440 + sl;
154
155 vraw = AllPixelDataVector[ DataPos ] * dconv;
156 vraw -= drs_basemean[ OffsetPos ];
157 vraw -= drs_triggeroffsetmean[ TriggerOffsetPos ];
158 vraw /= drs_gainmean[ OffsetPos ];
159 vraw *= 1907.35;
160
161// slice_pt = pixel_pt + sl;
162// drs_cal_offset = ( sl + StartCellVector[ pixel ] ) % RegionOfInterest;
163// cal_pt = pixel_pt + drs_cal_offset;
164// vraw = AllPixelDataVector[ slice_pt ] * dconv;
165// vcal = ( vraw - drs_basemean[ cal_pt ] - drs_triggeroffsetmean[ slice_pt ] ) / drs_gainmean[ cal_pt ]*1907.35;
166// destination.push_back(vcal);
167
168 destination[sl-LeaveOutLeft] = vraw;
169 }
170
171 return destination.size();
172}
Note: See TracBrowser for help on using the repository browser.