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

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