source: trunk/Mars/mcore/factofits.h@ 17226

Last change on this file since 17226 was 17226, checked in by tbretz, 11 years ago
SerDrsCalibration changed to vector... pointers are always a security risk; added SetDrsCalibration(DrsCalibration&)
File size: 8.2 KB
Line 
1/*
2 * factofits.h
3 *
4 * Created on: Oct 16, 2013
5 * Author: lyard
6 */
7
8#ifndef FACTOFITS_H_
9#define FACTOFITS_H_
10
11#include "zofits.h"
12
13#ifndef __MARS__
14namespace std
15{
16#else
17using namespace std;
18#endif
19
20class factofits : public zofits
21{
22
23 public:
24
25 factofits(uint32_t numTiles=1000,
26 uint32_t rowPerTile=100,
27 uint64_t maxUsableMem=0) : zofits(numTiles, rowPerTile, maxUsableMem)
28 {
29 fStartCellsOffset = -1;
30 fDataOffset = -1;
31 }
32 factofits(const char* fname,
33 uint32_t numTiles=1000,
34 uint32_t rowPerTile=100,
35 uint64_t maxUsableMem=0) : zofits(fname, numTiles, rowPerTile, maxUsableMem)
36 {
37 fStartCellsOffset = -1;
38 fDataOffset = -1;
39 }
40 virtual ~factofits()
41 {
42 }
43
44 //whether or not a calibration was given to the file writer
45 virtual bool IsOffsetCalibration()
46 {
47 return (fOffsetCalibration.size() != 0);
48 }
49
50 //assign a given drs offset calibration
51 void SetDrsCalibration(const vector<float> &calib)
52 {
53 if (!IsOffsetCalibration())
54 fOffsetCalibration.resize(1440*1024);
55
56 for (uint32_t i=0; i<1440*1024; i++)
57 fOffsetCalibration[i] = (int16_t)(calib[i]*4096/2000);
58 }
59
60 void SetDrsCalibration(const vector<float>& calib)
61 {
62 if (calib.size() != 1440*1024)
63 #ifdef __EXCEPTIONS
64 throw runtime_error("Cannot load calibration with anything else than 1024 samples per pixel");
65 #else
66 gLog << ___err___ << "ERROR - Cannot load calibration with anything else than 1024 samples per pixel");
67 #endif
68 SetDrsCalibration(calib.data());
69 }
70
71 void SetDrsCalibration(const vector<int16_t>& vec)
72 {
73 if (!IsOffsetCalibration())
74 fOffsetCalibration.resize(1440*1024);
75
76 for (uint32_t i=0; i<1440*1024; i++)
77 fOffsetCalibration[i] = vec[i];
78 }
79
80 void SetDrsCalibration(const DrsCalibration& drs)
81 {
82 if (drs.fNumOffset==0)
83 return;
84
85 if (!IsOffsetCalibration())
86 fOffsetCalibration.resize(1440*1024);
87
88 for (uint32_t i=0; i<1024*1440; i++)
89 fOffsetCalibration[i] = drs.fOffset[i]/drs.fNumOffset;
90 }
91
92 bool WriteTableHeader(const char* name="DATA")
93 {
94 if (!zofits::WriteTableHeader(name))
95 return false;
96
97 if (IsOffsetCalibration())
98 {//retrieve the column storing the start cell offsets, if required.
99
100 for (auto it=fRealColumns.begin(); it!=fRealColumns.end(); it++)//Table.cols.begin(); it!= fTable.cols.end(); it++)
101 {
102 if (it->col.name == "StartCellData")
103 fStartCellsOffset = it->col.offset;
104 if (it->col.name == "Data")
105 {
106 fNumSlices = it->col.num;
107 fDataOffset = it->col.offset;
108 if (fNumSlices % 1440 != 0)
109 {
110#ifdef __EXCEPTIONS
111 throw runtime_error("Number of data samples not a multiple of 1440.");
112#else
113 gLog << ___err___ << "ERROR - Number of data samples not a multiple of 1440. Doing it uncalibrated." << endl;
114#endif
115 fOffsetCalibration.resize(0);
116 }
117 fNumSlices /= 1440;
118 }
119 }
120 if (fStartCellsOffset < 0)
121 {
122#ifdef __EXCEPTIONS
123 throw runtime_error("FACT Calibration requested, but \"StartCellData\" column not found.");
124#else
125 gLog << ___err___ << "ERROR - FACT Calibration requested, but \"StartCellData\" column not found. Doing it uncalibrated." << endl;
126#endif
127 //throw away the calibration data
128 fOffsetCalibration.resize(0);
129 }
130 if (fDataOffset < 0)
131 {
132#ifdef __EXCEPTIONS
133 throw runtime_error("FACT Calibration requested, but \"Data\" column not found.");
134#else
135 gLog << ___err___ << "ERROR - FACT Calibration requested, but \"Data\" column not found. Doing it uncalibrated." << endl;
136#endif
137 //throw away the calibration data
138 fOffsetCalibration.resize(0);
139 }
140 }
141
142 return true;
143 }
144
145 virtual bool WriteDrsOffsetsTable()
146 {
147 if (!IsOffsetCalibration())
148 return false;
149
150 ofits c;
151 c.SetStr("XTENSION", "BINTABLE" , "binary table extension");
152 c.SetInt("BITPIX" , 8 , "8-bit bytes");
153 c.SetInt("NAXIS" , 2 , "2-dimensional binary table");
154 c.SetInt("NAXIS1" , 1024*1440*2 , "width of table in bytes");
155 c.SetInt("NAXIS2" , 1 , "number of rows in table");
156 c.SetInt("PCOUNT" , 0 , "size of special data area");
157 c.SetInt("GCOUNT" , 1 , "one data group (required keyword)");
158 c.SetInt("TFIELDS" , 1 , "number of fields in each row");
159 c.SetStr("CHECKSUM", "0000000000000000" , "Checksum for the whole HDU");
160 c.SetStr("DATASUM" , " 0" , "Checksum for the data block");
161 c.SetStr("EXTNAME" , "ZDrsCellOffsets" , "name of this binary table extension");
162 c.SetStr("TTYPE1" , "OffsetCalibration" , "label for field 1");
163 c.SetStr("TFORM1" , "1474560I" , "data format of field: 2-byte INTEGER");
164 c.End();
165
166 vector<char> swappedOffsets;
167 swappedOffsets.resize(1024*1440*sizeof(int16_t));
168 revcpy<sizeof(int16_t)>(swappedOffsets.data(), (char*)(fOffsetCalibration.data()), 1024*1440);
169
170 Checksum datasum;
171 datasum.add(swappedOffsets.data(), sizeof(int16_t)*1024*1440);
172
173 ostringstream dataSumStr;
174 dataSumStr << datasum.val();
175 c.SetStr("DATASUM", dataSumStr.str());
176
177 datasum += c.WriteHeader(*this);
178
179 const off_t here_I_am = tellp();
180
181 c.SetStr("CHECKSUM", datasum.str());
182 c.WriteHeader(*this);
183
184 seekp(here_I_am);
185
186 write(swappedOffsets.data(), swappedOffsets.size());
187
188 AlignTo2880Bytes();
189
190 return good();
191 }
192
193 virtual void DrsOffsetCalibrate(char* target_location)
194 {
195 if (IsOffsetCalibration())
196 {
197 int16_t* startCell = reinterpret_cast<int16_t*>(target_location + fStartCellsOffset);
198 int16_t* data = reinterpret_cast<int16_t*>(target_location + fDataOffset);
199
200 for (uint32_t ch=0; ch<1440; ch++)
201 {
202 if (startCell[ch] < 0)
203 {
204 data += fNumSlices;
205 continue;
206 }
207
208 const int16_t modStart = startCell[ch]%1024;
209 const int16_t *off = fOffsetCalibration.data() + ch*1024;
210
211 const int16_t* cal = off+modStart;
212 const int16_t* end_stride = data+fNumSlices;
213
214 if (modStart+fNumSlices > 1024)
215 {
216 while (cal < off+1024)
217 *data++ -= *cal++;
218 cal = off;
219 }
220
221 while (data<end_stride)
222 *data++ -= *cal++;
223 }
224 }
225 }
226
227private:
228 //Offsets calibration stuff.
229 vector<int16_t> fOffsetCalibration; ///< The calibration itself
230 int32_t fStartCellsOffset; ///< Offset in bytes for the startcell data
231 int32_t fDataOffset; ///< Offset in bytes for the data
232 int32_t fNumSlices; ///< Number of samples per pixel per event
233
234}; //class factofits
235
236#ifndef __MARS
237}; //namespace std
238#endif
239
240#endif /* FACTOFITS_H_ */
Note: See TracBrowser for help on using the repository browser.