source: trunk/FACT++/src/DataCalib.cc@ 11838

Last change on this file since 11838 was 11833, checked in by tbretz, 14 years ago
Fixed a few typos.
File size: 9.3 KB
Line 
1#include "DataCalib.h"
2
3#include "FAD.h"
4#include "FitsFile.h"
5#include "DimDescriptionService.h"
6
7#include "externals/fits.h"
8
9using namespace std;
10
11int DataCalib::fStep = 0;
12bool DataCalib::fProcessing = false;
13
14vector<int32_t> DataCalib::fOffset(1440*1024, 0);
15vector<int64_t> DataCalib::fGain (1440*1024, 4096);
16vector<int64_t> DataCalib::fTrgOff(1440*1024, 0);
17vector<float> DataCalib::fStats (1440*1024*6+3);
18
19uint64_t DataCalib::fNumOffset = 1;
20uint64_t DataCalib::fNumGain = 2000;
21uint64_t DataCalib::fNumTrgOff = 1;
22
23void DataCalib::Restart()
24{
25 // Default gain:
26 // 0.575*[45590]*2.5V / 2^16 = 0.99999 V
27 fOffset.assign(1440*1024, 0);
28 fGain.assign (1440*1024, 4096);
29 fTrgOff.assign(1440*1024, 0);
30
31 fNumOffset = 1;
32 fNumGain = 2000;
33 fNumTrgOff = 1;
34
35 reinterpret_cast<uint32_t*>(fStats.data())[0] = 0;
36 reinterpret_cast<uint32_t*>(fStats.data())[1] = 0;
37 reinterpret_cast<uint32_t*>(fStats.data())[2] = 0;
38
39 int i=0;
40 while (i<1024*1440*2+3) // Set mean and RMS to 0
41 fStats[i++] = 0;
42 while (i<1024*1440*3+3)
43 fStats[i++] = 2000./4096; // Set mean to 0.5
44 while (i<1024*1440*6+3)
45 fStats[i++] = 0; // Set everything else to 0
46
47 fStep = 0;
48 fProcessing = false;
49}
50
51void DataCalib::Update(DimDescribedService &dim)
52{
53 dim.Update(fStats);
54}
55
56bool DataCalib::Open(RUN_HEAD* h)
57{
58 if (h->NPix != 1440)
59 {
60 fMsg.Error("Number of pixels in header not 1440.");
61 return false;
62 }
63
64 if (h->Nroi != 1024)
65 {
66 fMsg.Error("Region of interest not 1024.");
67 return false;
68 }
69
70 if (fProcessing)
71 {
72 fMsg.Warn("Previous run not yet finished!");
73 return false;
74 }
75
76 if (fStep==4)
77 {
78 fMsg.Warn("DRS Calibration already finished... please restart!");
79 return false;
80 }
81
82 fProcessing = true;
83
84 ostringstream name;
85 name << "drs-calib-" << fStep;
86 fFileName = name.str();
87
88 Reset();
89 InitSize(1440, 1024);
90
91 return true;
92}
93
94bool DataCalib::WriteEvt(EVENT *e)
95{
96 // FIXME: SET StartPix to 0 if StartPix is -1
97
98 if (fStep==0)
99 {
100 AddRel(e->Adc_Data, e->StartPix);
101 }
102 if (fStep==1)
103 {
104 AddRel(e->Adc_Data, e->StartPix, fOffset.data(), fNumOffset);
105 }
106 if (fStep==2)
107 {
108 AddAbs(e->Adc_Data, e->StartPix, fOffset.data(), fNumOffset);
109 }
110
111 return true;
112}
113
114bool DataCalib::ReadFits(const string &str, MessageImp &msg)
115{
116 if (fProcessing)
117 {
118 msg.Error("Reading "+str+" failed: DRS calibration in process.");
119 return false;
120 }
121
122 try
123 {
124 fits file(str);
125 if (!file)
126 return false;
127
128 if (file.GetStr("TELESCOP")!="FACT")
129 {
130 msg.Error("Reading "+str+" failed: Not a valid FACT file (TELESCOP not FACT in header)");
131 return false;
132 }
133
134 if (!file.HasKey("STEP"))
135 {
136 msg.Error("Reading "+str+" failed: Is not a DRS calib file (STEP not found in header)");
137 return false;
138 }
139
140 if (file.GetNumRows()!=1)
141 {
142 msg.Error("Reading "+str+" failed: Number of rows in table is not 1.");
143 return false;
144 }
145
146 vector<float> data(1440*1024*6+3);
147
148 float *base = data.data();
149
150 file.SetPtrAddress("RunNumberBaseline", base, sizeof(float));
151 file.SetPtrAddress("RunNumberGain", base+1, sizeof(float));
152 file.SetPtrAddress("RunNumberTriggerOffset", base+2, sizeof(float));
153 file.SetPtrAddress("BaselineMean", base+0*1024*1440+3, sizeof(float)*1024*1440);
154 file.SetPtrAddress("BaselineRms", base+1*1024*1440+3, sizeof(float)*1024*1440);
155 file.SetPtrAddress("GainMean", base+2*1024*1440+3, sizeof(float)*1024*1440);
156 file.SetPtrAddress("GainRms", base+3*1024*1440+3, sizeof(float)*1024*1440);
157 file.SetPtrAddress("TriggerOffsetMean", base+4*1024*1440+3, sizeof(float)*1024*1440);
158 file.SetPtrAddress("TriggerOffsetRms", base+5*1024*1440+3, sizeof(float)*1024*1440);
159
160 if (!file.GetNextRow())
161 {
162 msg.Error("Reading data from "+str+" failed.");
163 return false;
164 }
165
166 fStep = file.GetUInt("STEP");
167 fNumOffset = file.GetUInt("NBOFFSET");
168 fNumGain = file.GetUInt("NBGAIN");
169 fNumTrgOff = file.GetUInt("NBTRGOFF");
170
171 memcpy(fStats.data(), base, fStats.size()*sizeof(float));
172
173 // Convert back to ADC counts: 256/125 = 4096/2000
174 // Convert back to sum (mean * num_entries)
175 for (int i=0; i<1024*1440; i++)
176 {
177
178 fOffset[i] = fNumOffset *256*fStats[i+1024*1440*0+3]/125;
179 fGain[i] = fNumOffset*fNumGain *256*fStats[i+1024*1440*2+3]/125;
180 fTrgOff[i] = fNumOffset*fNumTrgOff*256*fStats[i+1024*1440*4+3]/125;
181 }
182
183 // DAC: 0..2.5V == 0..65535
184 // V-mV: 1000
185 //fNumGain *= 2500*50000;
186 //for (int i=0; i<1024*1440; i++)
187 // fGain[i] *= 65536;
188 fNumGain *= 1953125;
189 for (int i=0; i<1024*1440; i++)
190 fGain[i] *= 1024;
191
192 return true;
193 }
194 catch (const runtime_error &e)
195 {
196 msg.Error("Exception reading "+str+": "+e.what());
197 return false;
198 }
199}
200
201void DataCalib::WriteFits()
202{
203#ifdef HAVE_FITS
204 FitsFile file(fMsg);
205
206 file.AddColumn('I', "RunNumberBaseline");
207 file.AddColumn('I', "RunNumberGain");
208 file.AddColumn('I', "RunNumberTriggerOffset");
209 file.AddColumn('F', "BaselineMean", 1024*1440, "V");
210 file.AddColumn('F', "BaselineRms", 1024*1440, "V");
211 file.AddColumn('F', "GainMean", 1024*1440, "V");
212 file.AddColumn('F', "GainRms", 1024*1440, "V");
213 file.AddColumn('F', "TriggerOffsetMean", 1024*1440, "V");
214 file.AddColumn('F', "TriggerOffsetRms", 1024*1440, "V");
215
216 fFileName = FormFileName(GetRunId(), "drs.fits");
217
218 if (!file.OpenFile(fFileName))
219 return;
220
221 if (!file.OpenTable("DrsCalibration"))
222 return;
223
224 if (!file.WriteDefaultKeys("fadctrl"))
225 return;
226
227 if (!file.WriteKeyNT("STEP", fStep, "") ||
228 !file.WriteKeyNT("ADCRANGE", 2000, "Dynamic range of the ADC in mV") ||
229 !file.WriteKeyNT("DACRANGE", 2500, "Dynamic range of the DAC in mV") ||
230 !file.WriteKeyNT("ADC", 12, "Resolution of ADC in bits") ||
231 !file.WriteKeyNT("DAC", 16, "Resolution of DAC in bits") ||
232 !file.WriteKeyNT("DACLEVEL", 50000, "Applied DAC level in counts") ||
233 !file.WriteKeyNT("NBOFFSET", fNumOffset, "Number of entries for offset calibration") ||
234 !file.WriteKeyNT("NBGAIN", fNumGain/1953125, "Number of entries for gain calibration") ||
235 !file.WriteKeyNT("NBTRGOFF", fNumTrgOff, "Number of entries for trigger offset calibration")
236 )
237 return;
238
239 vector<char> buf;
240 buf.reserve(fStats.size()*sizeof(float));
241
242 char *src = reinterpret_cast<char*>(fStats.data());
243 char *end = reinterpret_cast<char*>(fStats.data()+1024*1440*6+3);
244 char *dest = buf.data();
245
246 while (src<end)
247 {
248 reverse_copy(src, src+sizeof(float), dest);
249 src += sizeof(float);
250 dest += sizeof(float);
251 }
252
253 if (!file.AddRow())
254 return;
255
256 if (!file.WriteData(buf.data(), 1024*1440*sizeof(float)*6+3))
257 return;
258
259 ostringstream str;
260 str << "Wrote DRS calibration data (step=" << fStep << ") to '" << fFileName << "'";
261 Info(str.str());
262#endif
263}
264
265bool DataCalib::Close(RUN_TAIL *)
266{
267 if (fStep==0)
268 {
269 fOffset.assign(fSum.begin(), fSum.end());
270 fNumOffset = fNumEntries;
271
272 // Scale ADC data from 12bit to 2000mV
273 GetSampleStats(fStats.data()+3, 2000./4096);
274 reinterpret_cast<uint32_t*>(fStats.data())[0] = GetRunId();;
275 }
276 if (fStep==1)
277 {
278 fGain.assign(fSum.begin(), fSum.end());
279 fNumGain = fNumEntries;
280
281 // DAC: 0..2.5V == 0..65535
282 // V-mV: 1000
283 //fNumGain *= 2500*50000;
284 //for (int i=0; i<1024*1440; i++)
285 // fGain[i] *= 65536;
286 fNumGain *= 1953125;
287 for (int i=0; i<1024*1440; i++)
288 fGain[i] *= 1024;
289
290 // Scale ADC data from 12bit to 2000mV
291 GetSampleStats(fStats.data()+1024*1440*2+3, 2000./4096/fNumOffset);//0.5);
292 reinterpret_cast<uint32_t*>(fStats.data())[1] = GetRunId();;
293 }
294 if (fStep==2)
295 {
296 fTrgOff.assign(fSum.begin(), fSum.end());
297 fNumTrgOff = fNumEntries;
298
299 // Scale ADC data from 12bit to 2000mV
300 GetSampleStats(fStats.data()+1024*1440*4+3, 2000./4096/fNumOffset);//0.5);
301 reinterpret_cast<uint32_t*>(fStats.data())[2] = GetRunId();;
302 }
303
304 if (fStep>=0 && fStep<=2)
305 WriteFits();
306
307 fDim.Update(fStats);
308
309 fStep++;
310
311 fProcessing = false;
312
313 return true;
314}
315
316void DataCalib::Apply(int16_t *val, const int16_t *start, uint32_t roi)
317{
318 CalibData::Apply(val, start, roi,
319 fOffset.data(), fNumOffset,
320 fGain.data(), fNumGain,
321 fTrgOff.data(), fNumTrgOff);
322}
323
324void DataCalib::Apply(float *vec, int16_t *val, const int16_t *start, uint32_t roi)
325{
326 CalibData::Apply(vec, val, start, roi,
327 fOffset.data(), fNumOffset,
328 fGain.data(), fNumGain,
329 fTrgOff.data(), fNumTrgOff);
330}
331
Note: See TracBrowser for help on using the repository browser.