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

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