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

Last change on this file since 14021 was 14000, checked in by tbretz, 12 years ago
Exchanged the enum definitions for the cfitsio based fits format and our fits format; replaced the cfitsio based on with the new one in DataCalib.
File size: 10.2 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
11DrsCalibration DataCalib::fData;
12bool DataCalib::fProcessing = false;
13vector<float> DataCalib::fStats(1440*1024*6+160*1024*2+4);
14
15void DataCalib::Restart()
16{
17 fData.Clear();
18
19 reinterpret_cast<uint32_t*>(fStats.data())[0] = 0;
20 reinterpret_cast<uint32_t*>(fStats.data())[1] = 0;
21 reinterpret_cast<uint32_t*>(fStats.data())[2] = 0;
22 reinterpret_cast<uint32_t*>(fStats.data())[3] = 0;
23
24 int i=0;
25 while (i<1024*1440*2+4) // Set mean and RMS to 0
26 fStats[i++] = 0;
27 while (i<1024*1440*3+4)
28 fStats[i++] = 2000./4096; // Set mean to 0.5
29 while (i<1440*1024*6+160*1024*2+4)
30 fStats[i++] = 0; // Set everything else to 0
31
32 fProcessing = false;
33}
34
35bool DataCalib::ResetTrgOff(DimDescribedService &dim, DimDescribedService &runs)
36{
37 if (fData.fStep!=3)
38 return false;
39
40 for (int i=1024*1440*3+4; i<1440*1024*6+160*1024*2+4; i++)
41 fStats[i] = 0;
42
43 reinterpret_cast<uint32_t*>(fStats.data())[0] = 0;
44 reinterpret_cast<uint32_t*>(fStats.data())[3] = 0;
45
46 fData.fStep = 1;
47 Update(dim, runs);
48 fData.fStep = 2;
49
50 return true;
51}
52
53void DataCalib::Update(DimDescribedService &dim, DimDescribedService &runs)
54{
55 const uint16_t roi = fData.fRoi;
56 const uint16_t ntm = fData.fNumTm;
57
58 vector<float> buf(1440*1024*6+160*1024*2+4);
59
60 memcpy(buf.data(), fStats.data(), (4*1024*1440+4)*sizeof(float));
61
62 for (int i=0; i<1440; i++)
63 {
64 memcpy(buf.data()+4+1440*1024*4 + i*1024, fStats.data()+4 + 4*1024*1440 + roi*i, roi*sizeof(float));
65 memcpy(buf.data()+4+1440*1024*5 + i*1024, fStats.data()+4 + 4*1024*1440 + roi*1440 + roi*i, roi*sizeof(float));
66 }
67
68 /*
69 for (int i=0; i<ntm; i++)
70 {
71 memcpy(buf.data()+4+1440*1024*6 + i*1024, fStats.data()+4 + 4*1024*1440 + 2*roi*1440, roi*sizeof(float));
72 memcpy(buf.data()+4+1440*1024*6+160*1024 + i*1024, fStats.data()+4 + 4*1024*1440 + 2*roi*1440+i*roi, roi*sizeof(float));
73 }*/
74
75#warning Time marker channels not sent
76
77 dim.Update(buf);
78
79 runs.setData(buf.data(), 4*sizeof(uint32_t));
80 runs.Update();
81}
82
83bool DataCalib::Open(const RUN_HEAD* h, const FAD::RunDescription &d)
84{
85 if (h->NPix != 1440)
86 {
87 fMsg.Error("Number of pixels in header not 1440.");
88 return false;
89 }
90
91 if (fProcessing)
92 {
93 fMsg.Warn("Previous DRS calibration run not yet finished!");
94 return false;
95 }
96
97 if (fData.fStep==3)
98 {
99 fMsg.Warn("DRS Calibration already finished... please restart!");
100 return false;
101 }
102
103 if (fData.fStep!=2 && h->Nroi != 1024)
104 {
105 ostringstream msg;
106 msg << "Region of interest not 1024, but " << h->Nroi << " in step " << fData.fStep << " ... as it ought to be.";
107 fMsg.Error(msg);
108 return false;
109 }
110
111 vector<uint16_t> dac(8);
112/*
113 // We don't check consistency over several boards because this is done
114 // by the eventCheck routine already
115 for (int i=0; i<h->NBoard; i++)
116 {
117 const PEVNT_HEADER &hh = h->FADhead[i];
118
119 if (hh.start_package_flag==0)
120 continue;
121
122 for (int j=0; j<8; j++)
123 dac[j] = hh.dac[j];
124
125 break;
126 }
127
128 for (int i=1; i<7; i++)
129 {
130 if (i==3 || dac[i]==dac[i+1])
131 continue;
132
133 ostringstream msg;
134 msg << "Values of DAC" << i << " (" << dac[i] << ") and DAC" << i+1 <<" (" << dac[i+1] << ") do not match... cannot take DRS calibration!";
135 fMsg.Error(msg);
136 return false;
137 }
138
139 if (fData.fStep>0)
140 {
141 for (int j=0; j<8; j++)
142 {
143 if (fData.fDAC[j]==dac[j])
144 continue;
145
146 ostringstream msg;
147 msg << "DAC value from previous run (DAC" << j << "=" << fData.fDAC[j] << ") and current run ";
148 msg << "(DAC" << j << "=" << dac[j] << ") inconsistent... cannot take DRS calibration!";
149 fMsg.Error(msg);
150 return false;
151 }
152 }
153
154 memcpy(fData.fDAC, dac.data(), 8*sizeof(uint16_t));
155*/
156 fProcessing = true;
157
158 const bool hastm = h->Nroi<=512 && h->NroiTM>=2*h->Nroi;
159
160 Reset();
161 InitSize(hastm ? 1600 : 1440, h->Nroi);
162
163 fData.fRoi = fNumSamples;
164 fData.fNumTm = hastm ? 160 : 0;
165
166 return DataWriteFits2::Open(h, d);
167}
168
169bool DataCalib::WriteEvt(EVENT *e)
170{
171 // FIXME: SET StartPix to 0 if StartPix is -1
172
173 if (fData.fStep==0)
174 {
175 AddRel(e->Adc_Data, e->StartPix);
176 }
177 if (fData.fStep==1)
178 {
179 AddRel(e->Adc_Data, e->StartPix, fData.fOffset.data(), fData.fNumOffset);
180 }
181 if (fData.fStep==2)
182 {
183 AddAbs(e->Adc_Data, e->StartPix, fData.fOffset.data(), fData.fNumOffset);
184 }
185
186 return DataWriteFits2::WriteEvt(e);
187}
188
189bool DataCalib::ReadFits(const string &str, MessageImp &msg)
190{
191 if (fProcessing)
192 {
193 msg.Error("Reading "+str+" failed: DRS calibration in process.");
194 return false;
195 }
196
197 try
198 {
199 const string txt = fData.ReadFitsImp(str, fStats);
200 if (txt.empty())
201 return true;
202
203 msg.Error(txt);
204 return false;
205 }
206 catch (const runtime_error &e)
207 {
208 msg.Error("Exception reading "+str+": "+e.what());
209 return false;
210 }
211}
212
213void ReverseCopy(const void *src, void *dest)
214{
215 reverse_copy(reinterpret_cast<const char*>(src),
216 reinterpret_cast<const char*>(src)+sizeof(float),
217 reinterpret_cast<char*>(dest));
218}
219
220void DataCalib::WriteFits()
221{
222#ifdef HAVE_FITS
223 FitsFile file(fMsg);
224
225 const uint16_t roi = fData.fRoi;
226 const uint16_t ntm = fData.fNumTm;
227
228 file.AddColumn('I', "RunNumberBaseline");
229 file.AddColumn('I', "RunNumberGain");
230 file.AddColumn('I', "RunNumberTriggerOffset");
231 file.AddColumn('F', "BaselineMean", 1024*1440, "mV");
232 file.AddColumn('F', "BaselineRms", 1024*1440, "mV");
233 file.AddColumn('F', "GainMean", 1024*1440, "mV");
234 file.AddColumn('F', "GainRms", 1024*1440, "mV");
235 file.AddColumn('F', "TriggerOffsetMean", roi*1440, "mV");
236 file.AddColumn('F', "TriggerOffsetRms", roi*1440, "mV");
237 file.AddColumn('F', "TriggerOffsetTMMean", roi*ntm, "mV");
238 file.AddColumn('F', "TriggerOffsetTMRms", roi*ntm, "mV");
239
240 const string filename = FormFileName("drs.fits");
241
242 if (!file.OpenFile(filename))
243 return;
244
245 if (!file.OpenTable("DrsCalibration"))
246 return;
247
248 if (!file.WriteDefaultKeys("fadctrl"))
249 return;
250
251 if (!file.WriteKeyNT("STEP", fData.fStep, "") ||
252 !file.WriteKeyNT("ADCRANGE", 2000, "Dynamic range of the ADC in mV") ||
253 !file.WriteKeyNT("DACRANGE", 2500, "Dynamic range of the DAC in mV") ||
254 !file.WriteKeyNT("ADC", 12, "Resolution of ADC in bits") ||
255 !file.WriteKeyNT("DAC", 16, "Resolution of DAC in bits") ||
256// !file.WriteKeyNT("DAC_A", fData.fDAC[0], "Level of DAC 0 in DAC counts") ||
257// !file.WriteKeyNT("DAC_B", fData.fDAC[1], "Leval of DAC 1-3 in DAC counts") ||
258// !file.WriteKeyNT("DAC_C", fData.fDAC[4], "Leval of DAC 4-7 in DAC counts") ||
259 !file.WriteKeyNT("NBOFFSET", fData.fNumOffset, "Number of entries for offset calibration") ||
260 !file.WriteKeyNT("NBGAIN", fData.fNumGain/1953125, "Number of entries for gain calibration") ||
261 !file.WriteKeyNT("NBTRGOFF", fData.fNumTrgOff, "Number of entries for trigger offset calibration") ||
262 !file.WriteKeyNT("NPIX", 1440, "Number of channels in the camera") ||
263 !file.WriteKeyNT("NTM", ntm, "Number of time marker channels") ||
264 !file.WriteKeyNT("NROI", roi, "Region of interest")
265 )
266 return;
267
268 vector<char> buf(fStats.size()*sizeof(float));
269
270 char *src = reinterpret_cast<char*>(fStats.data());
271 char *end = reinterpret_cast<char*>(fStats.data()+fStats.size());
272 char *dest = buf.data();
273
274 while (src<end)
275 {
276 reverse_copy(src, src+sizeof(float), dest);
277 src += sizeof(float);
278 dest += sizeof(float);
279 }
280
281 if (!file.AddRow())
282 return;
283
284 if (!file.WriteData(buf.data()+sizeof(float), (1440*1024*4 + 1440*roi*2 + ntm*roi*2 + 3)*sizeof(float)))
285 return;
286
287 ostringstream str;
288 str << "Wrote DRS calibration data (step=" << fData.fStep << ", roi=" << roi << ") to '" << filename << "'";
289 Info(str.str());
290#endif
291}
292
293bool DataCalib::Close(RUN_TAIL *tail)
294{
295 if (fData.fStep==0)
296 {
297 fData.fOffset.assign(fSum.begin(), fSum.end());
298 fData.fNumOffset = fNumEntries;
299
300 for (int i=0; i<1024*1440; i++)
301 fData.fGain[i] = 4096*fNumEntries;
302
303 // Scale ADC data from 12bit to 2000mV
304 GetSampleStats(fStats.data()+4, 2000./4096);
305 reinterpret_cast<uint32_t*>(fStats.data())[1] = GetRunId();;
306 }
307 if (fData.fStep==1)
308 {
309 fData.fGain.assign(fSum.begin(), fSum.end());
310 fData.fNumGain = fNumEntries;
311
312 // DAC: 0..2.5V == 0..65535 2500*50000 625*50000 625*3125
313 // V-mV: 1000 ---------- --------- --------
314 //fNumGain *= 2500*50000; 65536 16384 1024
315 //for (int i=0; i<1024*1440; i++)
316 // fGain[i] *= 65536;
317 fData.fNumGain *= 1953125;
318 for (int i=0; i<1024*1440; i++)
319 fData.fGain[i] *= 1024;
320
321 // Scale ADC data from 12bit to 2000mV
322 GetSampleStats(fStats.data()+1024*1440*2+4, 2000./4096/fData.fNumOffset);//0.5);
323 reinterpret_cast<uint32_t*>(fStats.data())[2] = GetRunId();;
324 }
325 if (fData.fStep==2)
326 {
327 fData.fTrgOff.assign(fSum.begin(), fSum.end());
328 fData.fNumTrgOff = fNumEntries;
329
330 // Scale ADC data from 12bit to 2000mV
331 GetSampleStats(fStats.data()+1024*1440*4+4, 2000./4096/fData.fNumOffset);//0.5);
332 reinterpret_cast<uint32_t*>(fStats.data())[0] = fNumSamples;
333 reinterpret_cast<uint32_t*>(fStats.data())[3] = GetRunId();
334 }
335
336 if (fData.fStep<=2)
337 WriteFits();
338
339 Update(fDim, fDimRuns);
340
341 fData.fStep++;
342
343 fProcessing = false;
344
345 return DataWriteFits2::Close(tail);
346}
Note: See TracBrowser for help on using the repository browser.