source: trunk/Mars/mcore/FITS.h@ 19690

Last change on this file since 19690 was 19284, checked in by tbretz, 6 years ago
Removed processings from BlockHeader, as a variable size array, it created problem with compiling the root dictionary with certain compilers. Now, the memory position is calculated directly in the code (fortunately, this 'trick' was only used in one location).
File size: 5.2 KB
Line 
1/*
2 *
3 * FITS.h
4 *
5 * Global fits header
6 *
7 * Author: lyard
8 *
9 */
10
11#ifndef MARS_FITS
12#define MARS_FITS
13
14#include <stdint.h>
15#include <string.h>
16
17#include <vector>
18#include <string>
19
20#ifndef __CINT__
21#include <unordered_set>
22#endif
23
24namespace FITS
25{
26 static inline bool IsReservedKeyWord(const std::string &key)
27 {
28#ifndef __CINT__
29 static const std::unordered_set<std::string> keys =
30 {
31 "DATASUM", "END", "EXTNAME", "PCOUNT", "NAXIS",
32 "NAXIS1", "NAXIS2", "RAWSUM", "SIMPLE", "TFIELDS",
33 "THEAP", "XTENSION", "ZHEAPPTR", "ZNAXIS1", "ZNAXIS2",
34 "ZPCOUNT", "ZRATIO", "ZSHRINK", "ZTABLE", "ZTILELEN",
35 };
36
37 static const std::unordered_set<std::string> short_keys =
38 {
39 "TFORM", "TUNIT", "TTYPE", "ZCTYP", "ZFORM",
40 };
41
42 if (keys.find(key)!=keys.end())
43 return true;
44
45 const std::string five = key.substr(0, 5);
46 return short_keys.find(five)!=short_keys.end();
47#endif
48 }
49
50 static inline std::string CommentFromType(char type)
51 {
52 std::string comment;
53
54 switch (type)
55 {
56 case 'L': comment = "[1-byte BOOL]"; break;
57 case 'A': comment = "[1-byte CHAR]"; break;
58 case 'B': comment = "[1-byte BOOL]"; break;
59 case 'I': comment = "[2-byte INT]"; break;
60 case 'J': comment = "[4-byte INT]"; break;
61 case 'K': comment = "[8-byte INT]"; break;
62 case 'E': comment = "[4-byte FLOAT]"; break;
63 case 'D': comment = "[8-byte FLOAT]"; break;
64 case 'Q': comment = "[var. Length]"; break;
65 }
66
67 return comment;
68 }
69
70 static inline uint32_t SizeFromType(char type)
71 {
72 size_t size = 0;
73
74 switch (type)
75 {
76 case 'L':
77 case 'A':
78 case 'B': size = 1; break;
79 case 'I': size = 2; break;
80 case 'J':
81 case 'E': size = 4; break;
82 case 'K':
83 case 'D': size = 8; break;
84 case 'Q': size = 16; break;
85 }
86
87 return size;
88 }
89
90 //Identifier of the compression schemes processes
91 enum CompressionProcess_t
92 {
93 kFactRaw = 0x0,
94 kFactSmoothing = 0x1,
95 kFactHuffman16 = 0x2
96 };
97
98 //ordering of the columns / rows
99 enum RowOrdering_t
100 {
101 kOrderByCol = 'C',
102 kOrderByRow = 'R'
103 };
104
105#ifdef __CINT__
106 // CINT doesn't like the packed attribute...
107 // Therefore we give another hint of the size of the structure
108 struct TileHeader { char dummy[16]; };
109 struct BlockHeader { char dummy[10]; };
110#else
111 //Structure helper for tiles headers
112 struct TileHeader
113 {
114 char id[4];
115 uint32_t numRows;
116 uint64_t size;
117
118 TileHeader() {}
119
120 TileHeader(uint32_t nRows,
121 uint64_t s) : id{'T', 'I', 'L', 'E'},
122 numRows(nRows),
123 size(s)
124 { };
125 } __attribute__((__packed__));
126
127 //Structure helper for blocks headers and compresion schemes
128 struct BlockHeader
129 {
130 uint64_t size;
131 char ordering;
132 unsigned char numProcs;
133 // This looks like a nice solution but always created problems
134 // with the root dictionary because the dictionary generator
135 // generates invalid code for some compilers.
136 // As it is used only while reading, and only in one place
137 // I replaced that by a direct cast.
138 // uint16_t processings[];
139
140 BlockHeader(uint64_t s=0,
141 char o=kOrderByRow,
142 unsigned char n=1) : size(s),
143 ordering(o),
144 numProcs(n)
145 {
146 }
147 } __attribute__((__packed__));
148#endif
149
150 //Helper structure to simplify the initialization and handling of compressed blocks headers
151 struct Compression
152 {
153 std::vector<uint16_t> sequence;
154 BlockHeader header;
155
156 Compression(const std::vector<uint16_t> &seq, const RowOrdering_t &order=kOrderByCol)
157 : sequence(seq), header(0, order, seq.size())
158 {
159 }
160
161 Compression(const CompressionProcess_t &compression=kFactRaw, const RowOrdering_t &order=kOrderByCol)
162 : sequence(1), header(0, order, 1)
163 {
164 sequence[0] = compression;
165 }
166
167#ifdef __MARS__ // needed for CINT
168 Compression(const int &compression)
169 : sequence(1), header(0, kOrderByCol, 1)
170 {
171 sequence[0] = compression;
172 }
173#endif
174
175 RowOrdering_t getOrdering() const { return RowOrdering_t(header.ordering); }
176 uint32_t getSizeOnDisk() const { return sizeof(BlockHeader) + sizeof(uint16_t)*header.numProcs; }
177 CompressionProcess_t getProc(uint32_t i) const { return CompressionProcess_t(sequence[i]); }
178 uint16_t getNumProcs() const { return header.numProcs; }
179
180 void SetBlockSize(uint64_t size) { header.size = size; }
181 void Memcpy(char *dest) const
182 {
183 memcpy(dest, &header, sizeof(BlockHeader));
184 memcpy(dest+sizeof(BlockHeader), sequence.data(), header.numProcs*sizeof(uint16_t));
185 }
186 };
187};
188
189#endif //_FITS_H_
190
Note: See TracBrowser for help on using the repository browser.