FACT++  1.0
factofits.h
Go to the documentation of this file.
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 #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
12 
13 #include "zofits.h"
14 #include "DrsCalib.h"
15 
16 class factofits : public zofits
17 {
18  public:
19 
21  factofits(uint32_t numTiles=DefaultMaxNumTiles(), uint32_t rowPerTile=DefaultNumRowsPerTile(),
22  uint32_t maxMem=DefaultMaxMemory())
23  : zofits(numTiles, rowPerTile, maxMem)
24  {
25  fStartCellsOffset = -1;
26  fDataOffset = -1;
27  }
28 
29  factofits(const char *fname, uint32_t numTiles=DefaultMaxNumTiles(),
30  uint32_t rowPerTile=DefaultNumRowsPerTile(), uint32_t maxMem=DefaultMaxMemory())
31  : zofits(fname, numTiles, rowPerTile, maxMem)
32  {
33  fStartCellsOffset = -1;
34  fDataOffset = -1;
35  }
36 
37  virtual ~factofits()
38  {
39  }
40 
42  virtual bool IsOffsetCalibration()
43  {
44  return (fOffsetCalibration.size() != 0);
45  }
46 
48  void SetDrsCalibration(const std::vector<float> &calib)
49  {
50  VerifyCalibrationSize(calib.size());
51 
52  if (!IsOffsetCalibration())
53  fOffsetCalibration.resize(1440*1024);
54 
55  for (uint32_t i=0; i<1440*1024; i++)
56  fOffsetCalibration[i] = (int16_t)(calib[i]*4096/2000);
57  }
58 
60  void SetDrsCalibration(const std::vector<int16_t>& vec)
61  {
62  VerifyCalibrationSize(vec.size());
63 
64  if (!IsOffsetCalibration())
65  fOffsetCalibration.resize(1440*1024);
66 
67  for (uint32_t i=0; i<1440*1024; i++)
68  fOffsetCalibration[i] = vec[i];
69  }
70 
73  {
74  if (drs.fNumOffset==0)
75  return;
76 
77  VerifyCalibrationSize(drs.fOffset.size());
78 
79  if (!IsOffsetCalibration())
80  fOffsetCalibration.resize(1440*1024);
81 
82  for (uint32_t i=0; i<1024*1440; i++)
84  }
85 
87  bool WriteTableHeader(const char* name="DATA")
88  {
89  if (!zofits::WriteTableHeader(name))
90  return false;
91 
92  if (!IsOffsetCalibration())
93  return true;
94 
95  //retrieve the column storing the start cell offsets, if required.
96  for (auto it=fRealColumns.cbegin(); it!=fRealColumns.cend(); it++)
97  {
98  if (it->col.name == "StartCellData")
99  fStartCellsOffset = it->col.offset;
100 
101  if (it->col.name == "Data")
102  {
103  fNumSlices = it->col.num;
104  fDataOffset = it->col.offset;
105  if (fNumSlices % 1440 != 0)
106  {
107 #ifdef __EXCEPTIONS
108  throw std::runtime_error("Number of data samples not a multiple of 1440.");
109 #else
110  gLog << ___warn___ << "WARNING - Number of data samples not a multiple of 1440. Doing it uncalibrated." << std::endl;
111 #endif
112  fOffsetCalibration.resize(0);
113  }
114  fNumSlices /= 1440;
115  }
116  }
117 
118  if (fStartCellsOffset < 0)
119  {
120 #ifdef __EXCEPTIONS
121  throw std::runtime_error("FACT Calibration requested, but \"StartCellData\" column not found.");
122 #else
123  gLog << ___warn___ << "WARNING - FACT Calibration requested, but \"StartCellData\" column not found. Doing it uncalibrated." << std::endl;
124 #endif
125  //throw away the calibration data
126  fOffsetCalibration.resize(0);
127  }
128 
129  if (fDataOffset < 0)
130  {
131 #ifdef __EXCEPTIONS
132  throw std::runtime_error("FACT Calibration requested, but \"Data\" column not found.");
133 #else
134  gLog << ___warn___ << "WARNING - FACT Calibration requested, but \"Data\" column not found. Doing it uncalibrated." << std::endl;
135 #endif
136  //throw away the calibration data
137  fOffsetCalibration.resize(0);
138  }
139 
140  return true;
141  }
142 
144  /* virtual bool WriteDrsOffsetsTable()
145  {
146  if (!IsOffsetCalibration())
147  return false;
148 
149  ofits c;
150  c.SetStr("XTENSION", "BINTABLE" , "binary table extension");
151  c.SetInt("BITPIX" , 8 , "8-bit bytes");
152  c.SetInt("NAXIS" , 2 , "2-dimensional binary table");
153  c.SetInt("NAXIS1" , 1024*1440*2 , "width of table in bytes");
154  c.SetInt("NAXIS2" , 1 , "number of rows in table");
155  c.SetInt("PCOUNT" , 0 , "size of special data area");
156  c.SetInt("GCOUNT" , 1 , "one data group (required keyword)");
157  c.SetInt("TFIELDS" , 1 , "number of fields in each row");
158  c.SetStr("CHECKSUM", "0000000000000000" , "Checksum for the whole HDU");
159  c.SetStr("DATASUM" , " 0" , "Checksum for the data block");
160  c.SetStr("EXTNAME" , "ZDrsCellOffsets" , "name of this binary table extension");
161  c.SetStr("TTYPE1" , "OffsetCalibration" , "label for field 1");
162  c.SetStr("TFORM1" , "1474560I" , "data format of field: 2-byte INTEGER");
163  c.End();
164 
165  vector<char> swappedOffsets;
166  swappedOffsets.resize(1024*1440*sizeof(int16_t));
167  revcpy<sizeof(int16_t)>(swappedOffsets.data(), (char*)(fOffsetCalibration.data()), 1024*1440);
168 
169  Checksum datasum;
170  datasum.add(swappedOffsets.data(), sizeof(int16_t)*1024*1440);
171 
172  std::ostringstream dataSumStr;
173  dataSumStr << datasum.val();
174  c.SetStr("DATASUM", dataSumStr.str());
175 
176  datasum += c.WriteHeader(*this);
177 
178  const off_t here_I_am = tellp();
179 
180  c.SetStr("CHECKSUM", datasum.str());
181  c.WriteHeader(*this);
182 
183  seekp(here_I_am);
184 
185  write(swappedOffsets.data(), swappedOffsets.size());
186 
187  AlignTo2880Bytes();
188 
189  return good();
190  }*/
191 
193  virtual bool WriteDrsOffsetsTable()
194  {
195  if (!IsOffsetCalibration())
196  return false;
197 
198  const uint32_t catalog_size = sizeof(int64_t)*2;
199 
200  ofits c;
201  c.SetStr("XTENSION", "BINTABLE" , "binary table extension");
202  c.SetInt("BITPIX" , 8 , "8-bit bytes");
203  c.SetInt("NAXIS" , 2 , "2-dimensional binary table");
204  c.SetInt("NAXIS1" , catalog_size , "width of table in bytes");
205  c.SetInt("NAXIS2" , 1 , "number of rows in table");
206  c.SetInt("PCOUNT" , 0 , "size of special data area");
207  c.SetInt("GCOUNT" , 1 , "one data group (required keyword)");
208  c.SetInt("TFIELDS" , 1 , "number of fields in each row");
209  c.SetStr("CHECKSUM", "0000000000000000" , "Checksum for the whole HDU");
210  c.SetStr("DATASUM" , " 0" , "Checksum for the data block");
211  c.SetStr("EXTNAME" , "ZDrsCellOffsets" , "name of this binary table extension");
212  c.SetStr("TTYPE1" , "OffsetCalibration" , "label for field 1");
213  c.SetStr("ZFORM1" , "1474560I" , "data format of field: 2-byte INTEGER");
214  c.SetStr("TFORM1" , "1QB" , "data format of variable length bytes");
215  c.SetStr("ZCTYP1" , "FACT" , "Compression type FACT");
216 
217  c.SetBool( "ZTABLE", true, "Table is compressed");
218  c.SetInt( "ZNAXIS1", 1024*1440*2, "Width of uncompressed rows");
219  c.SetInt( "ZNAXIS2", 1, "Number of uncompressed rows");
220  c.SetInt( "ZPCOUNT", 0, "");
221  c.SetInt( "ZHEAPPTR", catalog_size, "");
222  c.SetInt( "ZTILELEN", 1, "Number of rows per tile");
223  c.SetInt( "THEAP", catalog_size, "");
224  c.SetStr( "RAWSUM", " 0", "Checksum of raw little endian data");
225  c.SetFloat("ZRATIO", 0, "Compression ratio");
226 
227  c.SetInt( "ZSHRINK", 1, "Catalog shrink factor");
228  c.End();
229 
230  c.WriteHeader(*this);
231 
232  const off_t here_I_am = tellp();
233 
234  //go after the catalog to compress and write the table data
235  seekp(here_I_am + catalog_size);
236 
237  //calculate RAWSUM
238  Checksum rawsum;
239  rawsum.add((char*)(fOffsetCalibration.data()), 1024*1440*sizeof(int16_t));
240 #if GCC_VERSION < 40603
241  c.SetStr("RAWSUM", std::to_string((long long unsigned int)(rawsum.val())));
242 #else
243  c.SetStr("RAWSUM", std::to_string(rawsum.val()));
244 #endif
245 
246  //compress data and calculate final, compressed size
247  const uint32_t compressed_header_size = sizeof(FITS::TileHeader) + sizeof(FITS::BlockHeader) + 1*sizeof(uint16_t);
248  std::vector<char> compressed_calib(1024*1440*2 + compressed_header_size + 8); //+8 for checksum;
249  char* data_start = compressed_calib.data() + compressed_header_size;
250  uint32_t compressed_size = compressHUFFMAN16(data_start, (char*)(fOffsetCalibration.data()), 1024*1440, 2, 1);;
251  compressed_size += compressed_header_size;
252 
253  //Write tile header
254  FITS::TileHeader th(0, 0);
255  std::vector<uint16_t> seq(1, FITS::kFactHuffman16);
257  th.numRows = 1;
258  th.size = compressed_size;
259  bh.SetBlockSize(compressed_size-sizeof(FITS::TileHeader));
260  memcpy(compressed_calib.data(), &(th), sizeof(FITS::TileHeader));
261  bh.Memcpy(compressed_calib.data()+sizeof(FITS::TileHeader));
262 
263  //calculate resulting compressed datasum
264  Checksum datasum;
265  memset(compressed_calib.data()+compressed_size, 0, 8-compressed_size%8);
266  datasum.add(compressed_calib.data(), compressed_size + 8-compressed_size%8);
267 
268  //write the catalog !
269  seekp(here_I_am);
270 
271  std::vector<uint64_t> catalog(2,0);
272  catalog[0] = compressed_size-sizeof(FITS::TileHeader);
273  catalog[1] = sizeof(FITS::TileHeader);
274 
275  std::vector<char> swappedCatalog(catalog_size);
276  revcpy<sizeof(int64_t)>(swappedCatalog.data(), (char*)(catalog.data()), 2);//catalog_size);
277  datasum.add(swappedCatalog.data(), catalog_size);
278 
279  write(swappedCatalog.data(), catalog_size);
280 
281  //update relevant keywords
282  c.SetFloat("ZRATIO", (float)(1024*1440*2)/(float)(compressed_size));
283  c.SetInt("PCOUNT", compressed_size);// + catalog_size);
284 
285 
286 //cout << "DEBUG: compressed_size=" << compressed_size << " " << compressed_size%2880 << " " << catalog_size << endl;
287 
288 
289 #if GCC_VERSION < 40603
290  c.SetStr("DATASUM", std::to_string((long long unsigned int)(datasum.val())));
291 #else
292  c.SetStr("DATASUM", std::to_string(datasum.val()));
293 #endif
294 
295  datasum += c.WriteHeader(*this);
296 
297  c.SetStr("CHECKSUM", datasum.str());
298 
299  c.WriteHeader(*this);
300 
301  //write the compressed data
302  seekp(here_I_am + catalog_size);
303  write(compressed_calib.data(), compressed_size);
304 
306 
307  return good();
308  }
309 
311  virtual void DrsOffsetCalibrate(char* target_location)
312  {
313  if (!IsOffsetCalibration())
314  return;
315 
316  const int16_t* startCell = reinterpret_cast<int16_t*>(target_location + fStartCellsOffset);
317  int16_t* data = reinterpret_cast<int16_t*>(target_location + fDataOffset);
318 
319  for (uint32_t ch=0; ch<1440; ch++)
320  {
321  if (startCell[ch] < 0)
322  {
323  data += fNumSlices;
324  continue;
325  }
326 
327  const int16_t modStart = startCell[ch]%1024;
328  const int16_t *off = fOffsetCalibration.data() + ch*1024;
329 
330  const int16_t* cal = off+modStart;
331  const int16_t* end_stride = data+fNumSlices;
332 
333  if (modStart+fNumSlices > 1024)
334  {
335  while (cal < off+1024)
336  *data++ -= *cal++;
337  cal = off;
338  }
339 
340  while (data<end_stride)
341  *data++ -= *cal++;
342  }
343  }
344 
345 private:
348  {
349  if (size == 1440*1024)
350  return true;
351 
352  std::ostringstream str;
353  str << "Cannot load calibration with anything else than 1440 pixels and 1024 samples per pixel. Got a total size of " << size;
354 #ifdef __EXCEPTIONS
355  throw std::runtime_error(str.str());
356 #else
357  gLog << ___err___ << "ERROR - " << str.str() << std::endl;
358  return false;
359 #endif
360  }
361 
362  //Offsets calibration stuff.
363  std::vector<int16_t> fOffsetCalibration;
365  int32_t fDataOffset;
366  int32_t fNumSlices;
367 
368 }; //class factofits
369 
370 #endif /* FACTOFITS_H_ */
bool SetInt(const std::string &key, int64_t i, const std::string &comment="")
Definition: ofits.h:535
std::vector< int32_t > fOffset
Definition: DrsCalib.h:1309
void AlignTo2880Bytes()
Definition: ofits.h:961
int32_t fNumSlices
Number of samples per pixel per event.
Definition: factofits.h:366
virtual bool WriteDrsOffsetsTable()
Uncompressed version of the DrsCalibration table.
Definition: factofits.h:193
int i
Definition: db_dim_client.c:21
char str[80]
Definition: test_client.c:7
uint32_t compressHUFFMAN16(char *dest, const char *src, uint32_t numRows, uint32_t sizeOfElems, uint32_t numRowElems)
Definition: zofits.h:900
bool VerifyCalibrationSize(uint32_t size)
Checks if the size of the input calibration is ok.
Definition: factofits.h:347
uint32_t numRows
Definition: FITS.h:115
static uint32_t DefaultMaxMemory(const uint32_t &_n=0)
Definition: zofits.h:93
virtual ~factofits()
Definition: factofits.h:37
bool SetBool(const std::string &key, bool b, const std::string &comment="")
Definition: ofits.h:516
uint32_t val() const
Definition: checksum.h:20
#define gLog
Definition: fits.h:36
int32_t fDataOffset
Offset in bytes for the data.
Definition: factofits.h:365
static uint32_t DefaultMaxNumTiles(const uint32_t &_n=0)
Definition: zofits.h:94
void Memcpy(char *dest) const
Definition: FITS.h:176
int32_t fStartCellsOffset
Offset in bytes for the startcell data.
Definition: factofits.h:364
#define ___err___
Definition: fits.h:37
void SetDrsCalibration(const std::vector< int16_t > &vec)
assign a given drs offset calibration
Definition: factofits.h:60
virtual bool WriteTableHeader(const char *name="DATA")
Definition: zofits.h:165
void SetDrsCalibration(const std::vector< float > &calib)
assign a given drs offset calibration
Definition: factofits.h:48
Definition: ofits.h:29
void SetDrsCalibration(const DrsCalibration &drs)
assign a given drs offset calibration
Definition: factofits.h:72
bool SetStr(const std::string &key, std::string s, const std::string &comment="")
Definition: ofits.h:526
std::string str(bool complm=true) const
Definition: checksum.h:148
#define ___warn___
Definition: fits.h:38
int size
Definition: db_dim_server.c:17
float data[4 *1440]
std::vector< int16_t > fOffsetCalibration
The calibration itself.
Definition: factofits.h:363
bool SetFloat(const std::string &key, double f, int p, const std::string &comment="")
Definition: ofits.h:543
std::vector< CompressedColumn > fRealColumns
Vector hosting the columns of the file.
Definition: zofits.h:1005
static uint32_t DefaultNumRowsPerTile(const uint32_t &_n=0)
Definition: zofits.h:95
void End()
Definition: ofits.h:588
factofits(const char *fname, uint32_t numTiles=DefaultMaxNumTiles(), uint32_t rowPerTile=DefaultNumRowsPerTile(), uint32_t maxMem=DefaultMaxMemory())
Definition: factofits.h:29
virtual void DrsOffsetCalibrate(char *target_location)
Apply the drs offset calibration (overload of super-method)
Definition: factofits.h:311
factofits(uint32_t numTiles=DefaultMaxNumTiles(), uint32_t rowPerTile=DefaultNumRowsPerTile(), uint32_t maxMem=DefaultMaxMemory())
constructors
Definition: factofits.h:21
virtual bool IsOffsetCalibration()
whether or not a calibration was given to the file writer
Definition: factofits.h:42
bool add(const char *buf, size_t len, bool big_endian=true)
Definition: checksum.h:49
Checksum WriteHeader(std::ostream &fout)
Definition: ofits.h:782
Definition: zofits.h:28
uint64_t size
Definition: FITS.h:116
TileHeader()
Definition: FITS.h:75
void SetBlockSize(uint64_t size)
Definition: FITS.h:175
int64_t fNumOffset
Definition: DrsCalib.h:1313
bool WriteTableHeader(const char *name="DATA")
Overload of the super function.
Definition: factofits.h:87