source: trunk/FACT++/src/simpleFitsDumper.cc@ 10789

Last change on this file since 10789 was 10763, checked in by lyard, 13 years ago
created a simple example about how to read fits
File size: 9.4 KB
Line 
1#include <map>
2#include <vector>
3#include <iostream>
4#include <fstream>
5
6#include <CCfits/CCfits>
7
8using namespace std;
9
10void writeValuesFromFits(vector<int>& offsets,ofstream& targetFile, unsigned char* fitsBuffer, vector<string> dumpList, map<string, CCfits::Column*>& colMap)
11{
12 targetFile.precision(20);
13 map<string, CCfits::Column*>::iterator it;
14 for (it=colMap.begin(); it != colMap.end(); it++)
15 {
16 bool found = false;
17 for (vector<string>::iterator jt=dumpList.begin(); jt != dumpList.end(); jt++)
18 {
19 if (it->first == *jt)
20 {
21 found = true;
22 break;
23 }
24 }
25 if (!found)
26 continue;
27 int offset = offsets[it->second->index()-1];
28 const char* charSrc = reinterpret_cast<char*>(&fitsBuffer[offset]);
29 unsigned char copyBuffer[30];//max size of a single variable
30 for (int width = 0; width<it->second->width(); width++)
31 {
32 switch (it->second->type())
33 {
34 case CCfits::Tbyte:
35 targetFile << *charSrc;
36 charSrc += sizeof(char);
37 break;
38 case CCfits::Tushort:
39 targetFile << *reinterpret_cast<const unsigned short*>(charSrc);
40 charSrc += sizeof(char);
41 break;
42 case CCfits::Tshort:
43 targetFile << *reinterpret_cast<const short*>(charSrc);
44 charSrc += sizeof(char);
45 break;
46 case CCfits::Tuint:
47 reverse_copy(charSrc, charSrc+sizeof(unsigned int), copyBuffer);
48 //warning suppressed in gcc4.0.2
49 targetFile << *reinterpret_cast<unsigned int*>(copyBuffer);
50 charSrc += sizeof(int);
51 break;
52 case CCfits::Tint:
53 reverse_copy(charSrc, charSrc+sizeof(int), copyBuffer);
54 targetFile << *reinterpret_cast<int*>(copyBuffer);
55 charSrc += sizeof(int);
56 break;
57 case CCfits::Tulong:
58 reverse_copy(charSrc, charSrc+sizeof(unsigned long), copyBuffer);
59 targetFile << *reinterpret_cast<unsigned long*>(copyBuffer);
60 charSrc += sizeof(int);
61 break;
62 case CCfits::Tlong:
63 reverse_copy(charSrc, charSrc+sizeof(long), copyBuffer);
64 targetFile << *reinterpret_cast<long*>(copyBuffer);
65 charSrc += sizeof(int);
66 break;
67 case CCfits::Tlonglong:
68 reverse_copy(charSrc, charSrc+sizeof(long long), copyBuffer);
69 targetFile << *reinterpret_cast<long long*>(copyBuffer);
70 charSrc += sizeof(long long);
71 break;
72 case CCfits::Tfloat:
73 reverse_copy(charSrc, charSrc+sizeof(float), copyBuffer);
74 targetFile << *reinterpret_cast<float*>(copyBuffer);
75 charSrc += sizeof(float);
76 break;
77 case CCfits::Tdouble:
78 reverse_copy(charSrc, charSrc+sizeof(double), copyBuffer);
79 targetFile << *reinterpret_cast<double*>(copyBuffer);
80 charSrc += sizeof(double);
81 break;
82 case CCfits::Tnull:
83 case CCfits::Tbit:
84 case CCfits::Tlogical:
85 case CCfits::Tstring:
86 case CCfits::Tcomplex:
87 case CCfits::Tdblcomplex:
88 case CCfits::VTbit:
89 case CCfits::VTbyte:
90 case CCfits::VTlogical:
91 case CCfits::VTushort:
92 case CCfits::VTshort:
93 case CCfits::VTuint:
94 case CCfits::VTint:
95 case CCfits::VTulong:
96 case CCfits::VTlong:
97 case CCfits::VTlonglong:
98 case CCfits::VTfloat:
99 case CCfits::VTdouble:
100 case CCfits::VTcomplex:
101 case CCfits::VTdblcomplex:
102 cout << "Data type not implemented yet." << endl;
103 return;
104 break;
105 default:
106 cout << "THIS SHOULD NEVER BE REACHED" << endl;
107 return;
108 }//switch
109 targetFile << " ";
110 }//width loop
111 }//iterator over the columns
112 targetFile << endl;
113}
114
115// --------------------------------------------------------------------------
116//
117//! Calculates the required buffer size for reading one row of the current table.
118//! Also calculates the offsets to all the columns
119//
120vector<int> CalculateBufferSize(map<string, CCfits::Column*>& colMap)
121{
122 vector<int> result;
123 map<int,int> sizes;
124 int size = 0;
125
126 for (map<string, CCfits::Column*>::iterator it=colMap.begin(); it != colMap.end(); it++)
127 {
128 int width = it->second->width();
129 switch (it->second->type())
130 {
131 case CCfits::Tbyte:
132 case CCfits::Tushort:
133 case CCfits::Tshort:
134 sizes[it->second->index()] = sizeof(char)*width;
135 break;
136 case CCfits::Tuint:
137 case CCfits::Tint:
138 sizes[it->second->index()] = sizeof(int)*width;
139 break;
140 case CCfits::Tulong:
141 case CCfits::Tlong:
142 sizes[it->second->index()] = sizeof(int)*width;
143 break;
144 case CCfits::Tlonglong:
145 sizes[it->second->index()] = sizeof(long long)*width;
146 break;
147 case CCfits::Tfloat:
148 sizes[it->second->index()] = sizeof(float)*width;
149 break;
150 case CCfits::Tdouble:
151 sizes[it->second->index()] = sizeof(double)*width;
152 break;
153 case CCfits::Tnull:
154 case CCfits::Tbit:
155 case CCfits::Tlogical:
156 case CCfits::Tstring:
157 case CCfits::Tcomplex:
158 case CCfits::Tdblcomplex:
159 case CCfits::VTbit:
160 case CCfits::VTbyte:
161 case CCfits::VTlogical:
162 case CCfits::VTushort:
163 case CCfits::VTshort:
164 case CCfits::VTuint:
165 case CCfits::VTint:
166 case CCfits::VTulong:
167 case CCfits::VTlong:
168 case CCfits::VTlonglong:
169 case CCfits::VTfloat:
170 case CCfits::VTdouble:
171 case CCfits::VTcomplex:
172 case CCfits::VTdblcomplex:
173 cout << "Data type not implemented yet." << endl;
174 return vector<int>();
175 break;
176 default:
177 cout << "THIS SHOULD NEVER BE REACHED" << endl;
178 return vector<int>();
179 }
180 }
181 //calculate the offsets in the vector.
182 int checkIndex = 1;
183 for (map<int,int>::iterator it=sizes.begin(); it != sizes.end(); it++)
184 {
185 result.push_back(size);
186 size += it->second;
187 if (it->first != checkIndex)
188 {
189 cout << "Expected index " << checkIndex << " found " << it->first << endl;
190 }
191 checkIndex++;
192 }
193 result.push_back(size);
194 return result;
195}
196
197int main(int argc, const char** argv)
198{
199 //set the names of the file and table to be loaded
200 string fileNameToLoad = "test.fits";
201 string tableNameToLoad = "FACT-TIME_ETIENNE";
202 //set the vector of columns to be dumped
203 vector<string> columnsToDump;
204 columnsToDump.push_back("Data0");
205 columnsToDump.push_back("Data1");
206 //set the name of the output text file
207 string outputFile = "output.txt";
208
209 //load the fits file
210 CCfits::FITS* file = NULL;
211 try
212 {
213 file = new CCfits::FITS(fileNameToLoad);
214 }
215 catch (CCfits::FitsException e)
216 {
217 cout << "Could not open FITS file " << fileNameToLoad << " reason: " << e.message() << endl;
218 return -1;
219 }
220 //check if the selected table indeed exists in the loaded file. If so, load it. Otherwise display the existing tables
221 CCfits::Table* table;
222 const multimap< string, CCfits::ExtHDU * > extMap = file->extension();
223 if (extMap.find(tableNameToLoad) == extMap.end())
224 {
225 cout << "Could not open table " << tableNameToLoad << ". Tables in file are: " << endl;
226 for (std::multimap<string, CCfits::ExtHDU*>::const_iterator it=extMap.begin(); it != extMap.end(); it++)
227 cout << it->first << " ";
228 cout << endl;
229 delete file;
230 return -1;
231 }
232 else
233 table = dynamic_cast<CCfits::Table*>(extMap.find(tableNameToLoad)->second);
234 int numRows = table->rows();
235 //check that the given column names are indeed part of that table
236 map<string, CCfits::Column*> colMap = table->column();
237 if (columnsToDump.size() != 0)
238 {
239 for (vector<string>::iterator it=columnsToDump.begin(); it!= columnsToDump.end(); it++)
240 {
241 if (colMap.find(*it) == colMap.end())
242 {
243 cout << "Config-given dump list contains invalid entry " << *it << endl;
244 delete file;
245 return -1;
246 }
247 }
248 }
249 //dump the requested columns
250 table->makeThisCurrent();
251 vector<int> offsets = CalculateBufferSize(colMap);
252 int size = offsets[offsets.size()-1];
253 offsets.pop_back();
254 unsigned char* fitsBuffer = new unsigned char[size];
255
256 ofstream targetFile(outputFile.c_str());
257 int status = 0;
258
259 for (int i=1;i<=table->rows(); i++)
260 {
261 fits_read_tblbytes(file->fitsPointer(), i, 1, size, fitsBuffer, &status);
262 if (status)
263 {
264 cout << "An error occurred while reading fits row #" << i << " error code: " << status << endl;
265 for (unsigned int j=0;j<offsets.size(); j++)
266 cout << offsets[j] << " ";
267 cout << endl;
268 }
269 writeValuesFromFits(offsets, targetFile, fitsBuffer, columnsToDump, colMap);
270 }
271 delete file;
272 return 0;
273}
Note: See TracBrowser for help on using the repository browser.