source: trunk/Mars/mcore/factfits.h@ 18246

Last change on this file since 18246 was 18119, checked in by tbretz, 10 years ago
Allow to access the calibration coefficients.
File size: 6.1 KB
Line 
1/*
2 * factfits.h
3 *
4 * Created on: May 26, 2013
5 * Author: lyard
6 */
7
8#ifndef MARS_FACTFITS
9#define MARS_FACTFITS
10
11#include "zfits.h"
12
13class factfits : public zfits
14{
15public:
16 // Default constructor
17 factfits(const std::string& fname, const std::string& tableName="", bool force=false) :
18 zfits(fname, tableName, force),
19 fOffsetCalibration(0),
20 fOffsetStartCellData(0),
21 fOffsetData(0),
22 fNumRoi(0)
23 {
24 if (init())
25 readDrsCalib(fname);
26 }
27
28 // Alternative constructor
29 factfits(const std::string& fname, const std::string& fout, const std::string& tableName, bool force=false) :
30 zfits(fname, fout, tableName, force),
31 fOffsetCalibration(0),
32 fOffsetStartCellData(0),
33 fOffsetData(0),
34 fNumRoi(0)
35 {
36 if (init())
37 readDrsCalib(fname);
38 }
39
40 const std::vector<int16_t> &GetOffsetCalibration() const { return fOffsetCalibration; }
41
42private:
43
44 void StageRow(size_t row, char* dest)
45 {
46 zfits::StageRow(row, dest);
47
48 // This file does not contain fact data or no calibration to be applied
49 if (fOffsetCalibration.empty())
50 return;
51
52 //re-get the pointer to the data to access the offsets
53 const uint8_t offset = (row*fTable.bytes_per_row)%4;
54
55 int16_t *startCell = reinterpret_cast<int16_t*>(fBufferRow.data() + offset + fOffsetStartCellData);
56 int16_t *data = reinterpret_cast<int16_t*>(fBufferRow.data() + offset + fOffsetData);
57
58 /*
59 for (uint32_t i=0; i<1440*1024; i+=1024, startCell++)
60 {
61 if (*startCell < 0)
62 {
63 data += fNumRoi;
64 continue;
65 }
66 for (uint32_t j=0; j<fNumRoi; j++, data++)
67 *data += fOffsetCalibration[i + (*startCell+j)%1024];
68 }
69 */
70
71 // This version is faster because the compilers optimization
72 // is not biased by the evaluation of %1024
73 for (int ch=0; ch<1440; ch++)
74 {
75 if (startCell[ch]<0)
76 {
77 data += fNumRoi;
78 continue;
79 }
80
81 const int16_t modStart = startCell[ch] % 1024;
82 const int16_t *off = fOffsetCalibration.data() + ch*1024;
83
84 const int16_t *cal = off+modStart;
85 const int16_t *end_stride = data+fNumRoi;
86
87 if (modStart+fNumRoi>1024)
88 {
89 while (cal<off+1024)
90 *data++ += *cal++;
91
92 cal = off;
93 }
94 while (data<end_stride)
95 *data++ += *cal++;
96 }
97
98 }
99
100 bool init()
101 {
102 if (!HasKey("NPIX") || !HasKey("NROI"))
103 return false;
104
105 if (Get<uint16_t>("NPIX")!=1440)
106 return false;
107
108 fNumRoi = Get<uint16_t>("NROI");
109 if (fNumRoi>1024)
110 return false;
111
112 // check column details for Data
113 const Table::Columns::const_iterator it = fTable.cols.find("Data");
114 if (it==fTable.cols.end() || it->second.num!=1440*fNumRoi || it->second.type!='I')
115 return false;
116
117 // check column details for StartCellData
118 const Table::Columns::const_iterator is = fTable.cols.find("StartCellData");
119 if (is==fTable.cols.end() || is->second.num!=1440 || is->second.type!='I')
120 return false;
121
122 fOffsetStartCellData = is->second.offset;
123 fOffsetData = it->second.offset;
124
125 return true;
126 }
127
128 // Read the Drs calibration data
129 void readDrsCalib(const std::string& fileName)
130 {
131 //should not be mandatory, but improves the perfs a lot when reading not compressed, gzipped files
132 if (!IsCompressedFITS())
133 return;
134
135 zfits calib(fileName, "ZDrsCellOffsets");
136
137 if (calib.bad())
138 {
139 clear(rdstate()|std::ios::badbit);
140 return;
141 }
142
143 if (calib.eof())
144 return;
145
146 // Check correct size and format of table
147 if (calib.GetNumRows() != 1)
148 {
149 clear(rdstate()|std::ios::badbit);
150#ifdef __EXCEPTIONS
151 throw std::runtime_error("Table 'ZDrsCellOffsets' found, but not with one row as expected");
152#else
153 gLog << ___err___ << "ERROR - Table 'ZDrsCellOffsets' found, but not with one row as expected" << std::endl;
154 return;
155#endif
156 }
157 if (calib.GetStr("TTYPE1") != "OffsetCalibration")
158 {
159 clear(rdstate()|std::ios::badbit);
160#ifdef __EXCEPTIONS
161 throw std::runtime_error("Table 'ZDrsCellOffsets' found, but first column is not the one expected");
162#else
163 gLog << ___err___ << "ERROR - Table 'ZDrsCellOffsets' found, but first column is not the one expected" << std::endl;
164 return;
165#endif
166 }
167 bool isColumnPresent = false;
168 if (calib.HasKey("TFORM1") && calib.GetStr("TFORM1") == "1474560I") isColumnPresent = true;
169 if (calib.HasKey("ZFORM1") && calib.GetStr("ZFORM1") == "1474560I") isColumnPresent = true;
170 if (!isColumnPresent) // 1024*1440
171 {
172 clear(rdstate()|std::ios::badbit);
173#ifdef __EXCEPTIONS
174 throw std::runtime_error("Table 'ZDrsCellOffsets' has wrong column format (TFROM1)");
175#else
176 gLog << ___err___ << "ERROR - Table 'ZDrsCellOffsets' has wrong column format (TFORM1)" << std::endl;
177 return;
178#endif
179 }
180
181 fOffsetCalibration.resize(1024*1440);
182
183 calib.SetPtrAddress("OffsetCalibration", fOffsetCalibration.data());
184 if (calib.GetNextRow())
185 return;
186
187 clear(rdstate()|std::ios::badbit);
188
189#ifdef __EXCEPTIONS
190 throw std::runtime_error("Reading column 'OffsetCalibration' failed.");
191#else
192 gLog << ___err___ << "ERROR - Reading column 'OffsetCalibration' failed." << std::endl;
193#endif
194
195 }
196
197 std::vector<int16_t> fOffsetCalibration; ///< integer values of the drs calibration used for compression
198
199 size_t fOffsetStartCellData;
200 size_t fOffsetData;
201
202 uint16_t fNumRoi;
203
204#warning Time marker channels currently unhandled
205
206}; //class factfits
207
208#endif
Note: See TracBrowser for help on using the repository browser.