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

Last change on this file since 12343 was 12343, checked in by tbretz, 13 years ago
Moved some common code between MARS and FACT++ to DrsCalib.h as new class DrsCalibration; renamed CalibData to DrsCalibrate.
File size: 6.4 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+3);
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
23 int i=0;
24 while (i<1024*1440*2+3) // Set mean and RMS to 0
25 fStats[i++] = 0;
26 while (i<1024*1440*3+3)
27 fStats[i++] = 2000./4096; // Set mean to 0.5
28 while (i<1024*1440*6+3)
29 fStats[i++] = 0; // Set everything else to 0
30
31 fProcessing = false;
32}
33
34void DataCalib::Update(DimDescribedService &dim)
35{
36 dim.Update(fStats);
37}
38
39bool DataCalib::Open(RUN_HEAD* h)
40{
41 if (h->NPix != 1440)
42 {
43 fMsg.Error("Number of pixels in header not 1440.");
44 return false;
45 }
46
47 if (h->Nroi != 1024)
48 {
49 fMsg.Error("Region of interest not 1024.");
50 return false;
51 }
52
53 if (fProcessing)
54 {
55 fMsg.Warn("Previous DRS calibration run not yet finished!");
56 return false;
57 }
58
59 if (fData.fStep==4)
60 {
61 fMsg.Warn("DRS Calibration already finished... please restart!");
62 return false;
63 }
64
65 fProcessing = true;
66
67 ostringstream name;
68 name << "drs-calib-" << fData.fStep;
69 fFileName = name.str();
70
71 Reset();
72 InitSize(1440, 1024);
73
74 return DataWriteFits::Open(h);
75}
76
77bool DataCalib::WriteEvt(EVENT *e)
78{
79 // FIXME: SET StartPix to 0 if StartPix is -1
80
81 if (fData.fStep==0)
82 {
83 AddRel(e->Adc_Data, e->StartPix);
84 }
85 if (fData.fStep==1)
86 {
87 AddRel(e->Adc_Data, e->StartPix, fData.fOffset.data(), fData.fNumOffset);
88 }
89 if (fData.fStep==2)
90 {
91 AddAbs(e->Adc_Data, e->StartPix, fData.fOffset.data(), fData.fNumOffset);
92 }
93
94 return DataWriteFits::WriteEvt(e);
95}
96
97bool DataCalib::ReadFits(const string &str, MessageImp &msg)
98{
99 if (fProcessing)
100 {
101 msg.Error("Reading "+str+" failed: DRS calibration in process.");
102 return false;
103 }
104
105 try
106 {
107 const string txt = fData.ReadFitsImp(str, fStats);
108 if (txt.empty())
109 return true;
110
111 msg.Error(txt);
112 return false;
113 }
114 catch (const runtime_error &e)
115 {
116 msg.Error("Exception reading "+str+": "+e.what());
117 return false;
118 }
119}
120
121void DataCalib::WriteFits()
122{
123#ifdef HAVE_FITS
124 FitsFile file(fMsg);
125
126 file.AddColumn('I', "RunNumberBaseline");
127 file.AddColumn('I', "RunNumberGain");
128 file.AddColumn('I', "RunNumberTriggerOffset");
129 file.AddColumn('F', "BaselineMean", 1024*1440, "mV");
130 file.AddColumn('F', "BaselineRms", 1024*1440, "mV");
131 file.AddColumn('F', "GainMean", 1024*1440, "mV");
132 file.AddColumn('F', "GainRms", 1024*1440, "mV");
133 file.AddColumn('F', "TriggerOffsetMean", 1024*1440, "mV");
134 file.AddColumn('F', "TriggerOffsetRms", 1024*1440, "mV");
135
136 fFileName = FormFileName("drs.fits");
137
138 if (!file.OpenFile(fFileName))
139 return;
140
141 if (!file.OpenTable("DrsCalibration"))
142 return;
143
144 if (!file.WriteDefaultKeys("fadctrl"))
145 return;
146
147 if (!file.WriteKeyNT("STEP", fData.fStep, "") ||
148 !file.WriteKeyNT("ADCRANGE", 2000, "Dynamic range of the ADC in mV") ||
149 !file.WriteKeyNT("DACRANGE", 2500, "Dynamic range of the DAC in mV") ||
150 !file.WriteKeyNT("ADC", 12, "Resolution of ADC in bits") ||
151 !file.WriteKeyNT("DAC", 16, "Resolution of DAC in bits") ||
152 !file.WriteKeyNT("DACLEVEL", 50000, "Applied DAC level in counts") ||
153 !file.WriteKeyNT("NBOFFSET", fData.fNumOffset, "Number of entries for offset calibration") ||
154 !file.WriteKeyNT("NBGAIN", fData.fNumGain/1953125, "Number of entries for gain calibration") ||
155 !file.WriteKeyNT("NBTRGOFF", fData.fNumTrgOff, "Number of entries for trigger offset calibration") ||
156 !file.WriteKeyNT("NPIX", 1440, "Number of channels in the camera") ||
157 !file.WriteKeyNT("NROI", 1024, "Region of interest")
158 )
159 return;
160
161 vector<char> buf;
162 buf.reserve(fStats.size()*sizeof(float));
163
164 char *src = reinterpret_cast<char*>(fStats.data());
165 char *end = reinterpret_cast<char*>(fStats.data()+1024*1440*6+3);
166 char *dest = buf.data();
167
168 while (src<end)
169 {
170 reverse_copy(src, src+sizeof(float), dest);
171 src += sizeof(float);
172 dest += sizeof(float);
173 }
174
175 if (!file.AddRow())
176 return;
177
178 if (!file.WriteData(buf.data(), 1024*1440*sizeof(float)*6+3))
179 return;
180
181 ostringstream str;
182 str << "Wrote DRS calibration data (step=" << fData.fStep << ") to '" << fFileName << "'";
183 Info(str.str());
184#endif
185}
186
187bool DataCalib::Close(RUN_TAIL *tail)
188{
189 if (fData.fStep==0)
190 {
191 fData.fOffset.assign(fSum.begin(), fSum.end());
192 fData.fNumOffset = fNumEntries;
193
194 for (int i=0; i<1024*1440; i++)
195 fData.fGain[i] = 4096*fNumEntries;
196
197 // Scale ADC data from 12bit to 2000mV
198 GetSampleStats(fStats.data()+3, 2000./4096);
199 reinterpret_cast<uint32_t*>(fStats.data())[0] = GetRunId();;
200 }
201 if (fData.fStep==1)
202 {
203 fData.fGain.assign(fSum.begin(), fSum.end());
204 fData.fNumGain = fNumEntries;
205
206 // DAC: 0..2.5V == 0..65535
207 // V-mV: 1000
208 //fNumGain *= 2500*50000;
209 //for (int i=0; i<1024*1440; i++)
210 // fGain[i] *= 65536;
211 fData.fNumGain *= 1953125;
212 for (int i=0; i<1024*1440; i++)
213 fData.fGain[i] *= 1024;
214
215 // Scale ADC data from 12bit to 2000mV
216 GetSampleStats(fStats.data()+1024*1440*2+3, 2000./4096/fData.fNumOffset);//0.5);
217 reinterpret_cast<uint32_t*>(fStats.data())[1] = GetRunId();;
218 }
219 if (fData.fStep==2)
220 {
221 fData.fTrgOff.assign(fSum.begin(), fSum.end());
222 fData.fNumTrgOff = fNumEntries;
223
224 // Scale ADC data from 12bit to 2000mV
225 GetSampleStats(fStats.data()+1024*1440*4+3, 2000./4096/fData.fNumOffset);//0.5);
226 reinterpret_cast<uint32_t*>(fStats.data())[2] = GetRunId();;
227 }
228
229 if (fData.fStep<=2)
230 WriteFits();
231
232 fDim.Update(fStats);
233
234 fData.fStep++;
235
236 fProcessing = false;
237
238 return DataWriteFits::Close(tail);
239}
Note: See TracBrowser for help on using the repository browser.