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

Last change on this file since 11812 was 11810, checked in by tbretz, 13 years ago
Added reading of FITS files.
File size: 7.5 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)
115{
116 try
117 {
118 fits file(str);
119 if (!file)
120 return false;
121
122 if (file.GetStr("TELESCOP")!="FACT")
123 {
124 Error("Reading "+str+" failed: Not a valid FACT file (TELESCOP not FACT in header)");
125 return false;
126 }
127
128 if (!file.HasKey("STEP"))
129 {
130 Error("Reading "+str+" failed: Is not a DRS calib file (STEP not found in header)");
131 return false;
132 }
133
134 if (file.GetNumRows()!=1)
135 {
136 Error("Reading "+str+" failed: Number of rows in table is not 1.");
137 return false;
138 }
139
140 vector<float> data(1440*1024*6+3);
141
142 float *base = data.data();
143
144 file.SetPtrAddress("RunNumberBaseline", base, sizeof(float));
145 file.SetPtrAddress("RunNumberGain", base+1, sizeof(float));
146 file.SetPtrAddress("RunNumberTriggerOffset", base+2, sizeof(float));
147 file.SetPtrAddress("BaselineMean", base+0*1024*1440+3, sizeof(float)*1024*1440);
148 file.SetPtrAddress("BaselineRms", base+1*1024*1440+3, sizeof(float)*1024*1440);
149 file.SetPtrAddress("GainMean", base+2*1024*1440+3, sizeof(float)*1024*1440);
150 file.SetPtrAddress("GainRms", base+3*1024*1440+3, sizeof(float)*1024*1440);
151 file.SetPtrAddress("TriggerOffsetMean", base+4*1024*1440+3, sizeof(float)*1024*1440);
152 file.SetPtrAddress("TriggerOffsetRms", base+5*1024*1440+3, sizeof(float)*1024*1440);
153
154 if (!file.GetNextRow())
155 {
156 Error("Reading data from "+str+" failed.");
157 return false;
158 }
159
160 fStep = file.GetUInt("STEP");
161
162 memcpy(fStats.data(), base, fStats.size()*sizeof(float));
163
164 return true;
165 }
166 catch (const runtime_error &e)
167 {
168 Error("Exception reading "+str+": "+e.what());
169 return false;
170 }
171}
172
173void DataCalib::WriteFits()
174{
175#ifdef HAVE_FITS
176 FitsFile file(fMsg);
177
178 file.AddColumn('I', "RunNumberBaseline");
179 file.AddColumn('I', "RunNumberGain");
180 file.AddColumn('I', "RunNumberTriggerOffset");
181 file.AddColumn('F', "BaselineMean", 1024*1440);
182 file.AddColumn('F', "BaselineRms", 1024*1440);
183 file.AddColumn('F', "GainMean", 1024*1440);
184 file.AddColumn('F', "GainRms", 1024*1440);
185 file.AddColumn('F', "TriggerOffsetMean", 1024*1440);
186 file.AddColumn('F', "TriggerOffsetRms", 1024*1440);
187
188 fFileName = FormFileName(GetRunId(), "drs.fits");
189
190 if (!file.OpenFile(fFileName))
191 return;
192
193 if (!file.OpenTable("DrsCalibration"))
194 return;
195
196 if (!file.WriteDefaultKeys("fadctrl"))
197 return;
198
199 if (!file.WriteKeyNT("STEP", fStep, ""))
200 return;
201
202 vector<char> buf;
203 buf.reserve(fStats.size()*sizeof(float));
204
205 char *src = reinterpret_cast<char*>(fStats.data());
206 char *end = reinterpret_cast<char*>(fStats.data()+1024*1440*6+3);
207 char *dest = buf.data();
208
209 while (src<end)
210 {
211 reverse_copy(src, src+sizeof(float), dest);
212 src += sizeof(float);
213 dest += sizeof(float);
214 }
215
216 if (!file.AddRow())
217 return;
218
219 if (!file.WriteData(buf.data(), 1024*1440*sizeof(float)*6+3))
220 return;
221
222 ostringstream str;
223 str << "Wrote DRS calibration data (step=" << fStep << ") to '" << fFileName << "'";
224 Info(str.str());
225#endif
226}
227
228bool DataCalib::Close(RUN_TAIL *)
229{
230 if (fStep==0)
231 {
232 fOffset.assign(fSum.begin(), fSum.end());
233 fNumOffset = fNumEntries;
234
235 // Scale ADC data from 12bit to 2000mV
236 GetSampleStats(fStats.data()+3, 2000./4096);
237 reinterpret_cast<uint32_t*>(fStats.data())[0] = GetRunId();;
238 }
239 if (fStep==1)
240 {
241 fGain.assign(fSum.begin(), fSum.end());
242 fNumGain = fNumEntries*fNumOffset;
243
244 // DAC: 0..2.5V == 0..65535
245 // V-mV: 1000
246 //fNumGain *= 2500*50000;
247 //for (int i=0; i<1024*1440; i++)
248 // fGain[i] *= 65536;
249 fNumGain *= 1953125;
250 for (int i=0; i<1024*1440; i++)
251 fGain[i] *= 1024;
252
253 // Scale ADC data from 12bit to 2000mV
254 GetSampleStats(fStats.data()+1024*1440*2+3, 2000./4096/fNumOffset);//0.5);
255 reinterpret_cast<uint32_t*>(fStats.data())[1] = GetRunId();;
256 }
257 if (fStep==2)
258 {
259 fTrgOff.assign(fSum.begin(), fSum.end());
260 fNumTrgOff = fNumEntries*fNumOffset;
261
262 // Scale ADC data from 12bit to 2000mV
263 GetSampleStats(fStats.data()+1024*1440*4+3, 2000./4096/fNumOffset);//0.5);
264 reinterpret_cast<uint32_t*>(fStats.data())[2] = GetRunId();;
265 }
266
267 if (fStep>=0 && fStep<=2)
268 WriteFits();
269
270 fProcessing = false;
271
272 fDim.Update(fStats);
273
274 fStep++;
275
276 return true;
277}
278
279void DataCalib::Apply(int16_t *val, const int16_t *start, uint32_t roi)
280{
281 CalibData::Apply(val, start, roi,
282 fOffset.data(), fNumOffset,
283 fGain.data(), fNumGain,
284 fTrgOff.data(), fNumTrgOff);
285}
286
287void DataCalib::Apply(float *vec, int16_t *val, const int16_t *start, uint32_t roi)
288{
289 CalibData::Apply(vec, val, start, roi,
290 fOffset.data(), fNumOffset,
291 fGain.data(), fNumGain,
292 fTrgOff.data(), fNumTrgOff);
293}
294
Note: See TracBrowser for help on using the repository browser.