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

Last change on this file since 12472 was 12469, checked in by tbretz, 14 years ago
Added the time marker channels to the DRS calibration; added the roi for the secondary baseline calculation; added the roi to the dim service; adapted the fStats handling accordingly.
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(RUN_HEAD* h)
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);
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(), (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())[0] = 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())[1] = 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())[2] = GetRunId();
310 reinterpret_cast<uint32_t*>(fStats.data())[3] = fNumSamples;
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.