source: Sophya/trunk/AddOn/TAcq/minifits.cc@ 4086

Last change on this file since 4086 was 4016, checked in by ansari, 14 years ago

Ajout de commentaires d'autodocumentation Doxygen, Reza 12/08/2011

File size: 9.8 KB
Line 
1#include <stdlib.h>
2#include <string.h>
3#include "minifits.h"
4
5// #include <iostream>
6
7//////////////////////////////////////////////////////////////////////
8// Classe MiniFITSException
9//////////////////////////////////////////////////////////////////////
10/*!
11 \class MiniFITSException
12 \ingroup TAcq
13
14 \brief Exception class for FITS I/O services provided by the MiniFITSFile class.
15*/
16
17
18/* --Methode-- */
19MiniFITSException::MiniFITSException(const char * m) throw()
20{
21 if (m!=NULL) {
22 strncpy(msg_, m, MFEX_MAXMSGLEN-1);
23 msg_[MFEX_MAXMSGLEN-1] = '\0';
24 }
25 else msg_[0] = '\0';
26}
27
28/* --Methode-- */
29MiniFITSException::MiniFITSException(const string& m) throw()
30{
31 strncpy(msg_, m.c_str(), MFEX_MAXMSGLEN-1);
32 msg_[MFEX_MAXMSGLEN-1] = '\0';
33}
34
35/* --Methode-- */
36MiniFITSException::~MiniFITSException() throw()
37{
38}
39
40/* --Methode-- */
41const char* MiniFITSException::what() const throw()
42{
43 return msg_;
44}
45
46/* --Methode-- */
47string const MiniFITSException::Msg() const
48{
49 return (string(msg_));
50}
51
52//////////////////////////////////////////////////////////////////////
53// Classe MiniFITSFile
54//////////////////////////////////////////////////////////////////////
55/*!
56 \class MiniFITSFile
57 \ingroup TAcq
58
59 \brief This class provides a subset of I/O services in FITS format (IMAGE_HDU only).
60*/
61
62#define MFITSHLEN 2880
63
64/* --Methode-- */
65MiniFITSFile::MiniFITSFile()
66{
67 Init();
68}
69
70/* --Methode-- */
71MiniFITSFile::MiniFITSFile(string const & nom, MiniFITS_Mode rwm)
72{
73 Init();
74 Open(nom, rwm);
75}
76
77/* --Methode-- */
78MiniFITSFile::MiniFITSFile(const char* nom, MiniFITS_Mode rwm)
79{
80 Init();
81 Open(nom, rwm);
82}
83
84
85/* --Methode-- */
86MiniFITSFile::~MiniFITSFile()
87{
88 Close();
89 delete[] header;
90}
91
92/* --Methode-- */
93void MiniFITSFile::Init()
94{
95 fip = NULL;
96 rwmode = MF_Read;
97 dtype = MF_Byte;
98 nax1 = 1;
99 nax2 = 1;
100 nax3 = 1;
101 fgnax3 = false;
102 totwsz = 0;
103 header = new char[MFITSHLEN];
104 for(int i=0; i<MFITSHLEN; i++) header[i]=' ';
105 nkeya_ = 0;
106}
107
108/* --Methode-- */
109void MiniFITSFile::Open(const char* nom, MiniFITS_Mode rwm)
110{
111 if (fip != NULL) throw MiniFITSException("MiniFITSFile::Open() - fip != NULL");
112 if (rwm == MF_Write) {
113 for(int i=0; i<MFITSHLEN; i++) header[i]=' ';
114 nkeya_ = 0;
115 FillHeader();
116 fip = fopen(nom, "w");
117 if (fip == NULL)
118 throw MiniFITSException("MiniFITSFile::Open()/ failed fopen() for write");
119 fwrite(header, 1, MFITSHLEN, fip);
120 rwmode = MF_Write;
121 }
122 else {
123 fip = fopen(nom, "r");
124 if (fip == NULL)
125 throw MiniFITSException("MiniFITSFile::Open()/ failed fopen() for read");
126 fread(header, 1, MFITSHLEN, fip);
127 DecodeHeader();
128 rwmode = MF_Read;
129 }
130 return;
131}
132
133/* --Methode-- */
134void MiniFITSFile::Close()
135{
136 if (fip) {
137 if (rwmode == MF_Write) {
138 // on remplit avec des zeros pour avoir une longueur multiple de 2880
139 size_t padsz = MFITSHLEN-(totwsz%MFITSHLEN);
140 char zeros[160];
141 for(size_t k=0; k<160; k++) zeros[k]=0;
142 while(padsz>160) {
143 fwrite(zeros, 1, 160, fip);
144 padsz-=160;
145 }
146 if (padsz>0) fwrite(zeros, 1, padsz, fip);
147 // On reecrit l'entete
148 FillHeader();
149 fseek(fip, 0, SEEK_SET);
150 fwrite(header, 1, MFITSHLEN, fip);
151 }
152 fclose(fip);
153 }
154 fip = NULL;
155 return;
156}
157
158/* --Methode-- */
159void MiniFITSFile::setDTypeNaxis(MiniFITS_DT dt, size_t na1, size_t na2)
160{
161 // Interdit si fichier ouvert en lecture ...
162 if ((fip!=NULL)&&(rwmode == MF_Read))
163 throw MiniFITSException("MiniFITSFile::setDTypeNaxis()/Error ReadOnly file");
164
165 dtype = dt;
166 nax1 = na1;
167 nax2 = na2;
168 nax3 = 1;
169 fgnax3 = false;
170}
171
172/* --Methode-- */
173void MiniFITSFile::setDTypeNaxis(MiniFITS_DT dt, size_t na1, size_t na2, size_t na3)
174{
175 // Interdit si fichier ouvert en lecture ...
176 if ((fip!=NULL)&&(rwmode == MF_Read))
177 throw MiniFITSException("MiniFITSFile::setDTypeNaxis()/Error ReadOnly file");
178
179 dtype = dt;
180 nax1 = na1;
181 nax2 = na2;
182 nax3 = na3;
183 fgnax3 = true;
184}
185
186
187/* --Methode-- */
188string MiniFITSFile::DataTypeToString()
189{
190 if (dtype == MF_Byte) return "MF_Byte";
191 else if (dtype == MF_Int16) return "MF_Int16";
192 else if (dtype == MF_Float32) return "MF_Float32";
193 else return "Unknown??";
194}
195
196/* --Methode-- */
197int MiniFITSFile::Write(void* data, size_t sz)
198{
199 fwrite(data, 1, sz, fip);
200 totwsz += sz;
201 return 0;
202}
203
204/* --Methode-- */
205int MiniFITSFile::Read(void* data, size_t sz, size_t offset)
206{
207 fseek(fip, offset+MFITSHLEN, SEEK_SET);
208 fread(data, 1, sz, fip);
209 return 0;
210}
211
212/* --Methode-- */
213void MiniFITSFile::FillHeader()
214{
215 strcpy(header, "SIMPLE = T / file does conform to FITS standard");
216 header[strlen(header)] = ' ';
217 int bpix = 8;
218 if (dtype == MF_Byte) bpix = 8;
219 else if (dtype == MF_Int16) bpix = 16;
220 else if (dtype == MF_Float32) bpix = -32;
221 char * buff = header+80;
222 sprintf(buff, "BITPIX = %20d / number of bits per data pixel", bpix);
223 buff[strlen(buff)] = ' ';
224 buff = header+160;
225 if (fgnax3)
226 strcpy(buff, "NAXIS = 3 / number of data axes");
227 else
228 strcpy(buff, "NAXIS = 2 / number of data axes");
229 buff[strlen(buff)] = ' ';
230 buff = header+240;
231 sprintf(buff, "NAXIS1 = %20ld / nb of pixels along X = PaquetSize", (long)nax1);
232 buff[strlen(buff)] = ' ';
233 buff = header+320;
234 if (fgnax3)
235 sprintf(buff, "NAXIS2 = %20ld / Number of fibers ", (long)nax2);
236 else
237 sprintf(buff, "NAXIS2 = %20ld / NumberOfPaquets", (long)nax2);
238 buff[strlen(buff)] = ' ';
239 buff = header+400;
240 if (fgnax3)
241 sprintf(buff, "NAXIS3 = %20ld / Number of paquets ", (long)nax3);
242 else
243 strcpy(buff,"COMMENT BAO-Radio / MiniFITSFile ");
244 buff[strlen(buff)] = ' ';
245
246 buff = header+480+nkeya_*80;
247 strcpy(buff,"COMMENT BAO-Radio / MiniFITSFile ");
248 buff[strlen(buff)] = ' ';
249 buff = header+560+nkeya_*80;
250 strcpy(buff,"END");
251 buff[strlen(buff)] = ' ';
252
253 return;
254}
255
256/* --Methode-- */
257int MiniFITSFile::AddKeyI(const char* key, long val, const char* comm)
258{
259 if (nkeya_ >= 28) return 0;
260 char cle[10];
261 strncpy(cle,key,8);
262 cle[8]='=';
263 for(int i=0;i<8;i++)
264 if (cle[i]=='\0') cle[i]=' ';
265 cle[9]='\0';
266 char* buff=header+480+nkeya_*80;
267 if (comm!=NULL) {
268 char tcom[50];
269 strncpy(tcom,comm,48);
270 tcom[48]='\0';
271 sprintf(buff,"%s %20ld / %s", cle, val, tcom);
272 }
273 else sprintf(buff,"%s %20ld / ", cle, val);
274 buff[strlen(buff)]=' ';
275 nkeya_++;
276 return nkeya_;
277}
278
279/* --Methode-- */
280int MiniFITSFile::AddKeyD(const char* key, double val, const char* comm)
281{
282 if (nkeya_ >= 28) return 0;
283 char cle[10];
284 strncpy(cle,key,8);
285 cle[8]='=';
286 for(int i=0;i<8;i++)
287 if (cle[i]=='\0') cle[i]=' ';
288 cle[9]='\0';
289 char* buff=header+480+nkeya_*80;
290 if (comm!=NULL) {
291 char tcom[50];
292 strncpy(tcom,comm,48);
293 tcom[48]='\0';
294 sprintf(buff,"%s %20lg / %s", cle, val, tcom);
295 }
296 else sprintf(buff,"%s %20lg / ", cle, val);
297 buff[strlen(buff)] = ' ';
298 nkeya_++;
299 return nkeya_;
300}
301
302/* --Methode-- */
303int MiniFITSFile::AddKeyS(const char* key, const char* val, const char* comm)
304{
305 if (nkeya_ >= 28) return 0;
306 char cle[10];
307 strncpy(cle,key,8);
308 cle[8]='=';
309 for(int i=0;i<8;i++)
310 if (cle[i]=='\0') cle[i]=' ';
311 cle[9]='\0';
312 char tcom[72];
313 tcom[0]='\'';
314 strncpy(tcom+1,val,65);
315 int l=strlen(tcom);
316 strcpy(tcom+l,"' / ");
317 l+=4;
318 if ((l<70)&&(comm!=NULL)) strncpy(tcom+l,comm,70-l);
319 tcom[70]='\0';
320 char* buff=header+480+nkeya_*80;
321 sprintf(buff,"%s %s", cle, tcom);
322 buff[strlen(buff)] = ' ';
323 nkeya_++;
324 return nkeya_;
325}
326
327/* --Methode-- */
328string MiniFITSFile::GetKey(const char* key)
329{
330 char rs[80];
331 rs[0]='\0';
332 char cle[10];
333 strncpy(cle,key,8);
334 cle[8]='=';
335 for(int i=0;i<8;i++)
336 if (cle[i]=='\0') cle[i]=' ';
337 cle[9]='\0';
338 for(int kh=80; kh<2800; kh+=80) {
339 char * buff = header+kh;
340 if (strncmp(buff, cle, 9) == 0) {
341 strncpy(rs, buff, 79);
342 rs[79]='\0';
343 break;
344 }
345 }
346 return rs;
347}
348
349/* --Methode-- */
350string MiniFITSFile::GetKeyValue(const char* key)
351{
352 string line = GetKey(key);
353 if(line.size()==0) return "";
354 char rs[84], sep = '?';
355 bool foundeq = false;
356 unsigned int ip = 0;
357 for(unsigned int i=0;i<line.size();i++) {
358 if(!foundeq) {if(line[i] == '=') foundeq = true; continue;}
359 if(sep=='?') { // recherche du separateur de debut
360 if(line[i]==' ') continue;
361 if(line[i]=='\'' || line[i]=='\"') {sep = line[i]; continue;}
362 else sep = ' ';
363 }
364 if(line[i]==sep) break;
365 rs[ip] = line[i];
366 ip++;
367 }
368 rs[ip] = '\0';
369 return rs;
370}
371
372/* --Methode-- */
373void MiniFITSFile::DecodeHeader()
374{
375 // AMELIORER le decodage de l'entete, remplissage dtype, nax1, nax2
376 char * buff = header;
377 if (strncmp(buff, "SIMPLE =", 9) != 0)
378 throw MiniFITSException("MiniFITSFile::DecodeHeader()/Error - NO SIMPLE keyword");
379 bool fgokt=false;
380 bool fgok1=false;
381 bool fgok2=false;
382 bool fgok3=false;
383 for(int kh=80; kh<2800; kh+=80) {
384 buff = header+kh;
385 if (strncmp(buff, "NAXIS1 =", 9) == 0) {
386 nax1 = atol(buff+10);
387 fgok1 = true;
388 // cout << " FOUND : NAXIS1= " << nax1 << endl;
389 }
390 else if (strncmp(buff, "NAXIS2 =", 9) == 0) {
391 nax2 = atol(buff+10);
392 fgok2 = true;
393 // cout << " FOUND : NAXIS2= " << nax2 << endl;
394 }
395 else if (strncmp(buff, "NAXIS3 =", 9) == 0) {
396 nax3 = atol(buff+10);
397 fgok3 = true;
398 // cout << " FOUND : NAXIS2= " << nax2 << endl;
399 }
400 else if (strncmp(buff, "BITPIX =", 9) == 0) {
401 int bpix = atoi(buff+10);
402 fgokt = true;
403 if (bpix == 8) dtype = MF_Byte;
404 else if (bpix == 16) dtype = MF_Int16;
405 else if (bpix == -32) dtype = MF_Float32;
406 else fgokt = false;
407 // cout << " FOUND : bpix= " << bpix << endl;
408 }
409 }
410 if (!(fgok1&&fgok2&&fgokt))
411 throw MiniFITSException("MiniFITSFile::DecodeHeader()/Error- Missing/wrong NAXIS1/2,BITPIX");
412 if (fgok3) fgnax3=true;
413 return;
414}
415
Note: See TracBrowser for help on using the repository browser.