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

Last change on this file since 3714 was 3693, checked in by cmv, 16 years ago

add GetKeyValue pour lire le contenu des clefs FITS, cmv 30/11/2009

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