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

Last change on this file since 3686 was 3684, checked in by ansari, 16 years ago

Ajout de la possibilite creation/lecture fichiers fits 3D (type cube) - Reza 27/11/2009

File size: 8.4 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
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
50#define MFITSHLEN 2880
51
52/* --Methode-- */
53MiniFITSFile::MiniFITSFile()
54{
55 Init();
56}
57
58/* --Methode-- */
59MiniFITSFile::MiniFITSFile(string const & nom, MiniFITS_Mode rwm)
60{
61 Init();
62 Open(nom, rwm);
63}
64
65/* --Methode-- */
66MiniFITSFile::MiniFITSFile(const char* nom, MiniFITS_Mode rwm)
67{
68 Init();
69 Open(nom, rwm);
70}
71
72
73/* --Methode-- */
74MiniFITSFile::~MiniFITSFile()
75{
76 Close();
77 delete[] header;
78}
79
80/* --Methode-- */
81void MiniFITSFile::Init()
82{
83 fip = NULL;
84 rwmode = MF_Read;
85 dtype = MF_Byte;
86 nax1 = 1;
87 nax2 = 1;
88 nax3 = 1;
89 fgnax3 = false;
90 totwsz = 0;
91 header = new char[MFITSHLEN];
92 for(int i=0; i<MFITSHLEN; i++) header[i]=' ';
93 nkeya_ = 0;
94}
95
96/* --Methode-- */
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) {
101 for(int i=0; i<MFITSHLEN; i++) header[i]=' ';
102 nkeya_ = 0;
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
121/* --Methode-- */
122void MiniFITSFile::Close()
123{
124 if (fip) {
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);
141 }
142 fip = NULL;
143 return;
144}
145
146/* --Methode-- */
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;
156 nax3 = 1;
157 fgnax3 = false;
158}
159
160/* --Methode-- */
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-- */
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
184/* --Methode-- */
185int MiniFITSFile::Write(void* data, size_t sz)
186{
187 fwrite(data, 1, sz, fip);
188 totwsz += sz;
189 return 0;
190}
191
192/* --Methode-- */
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
200/* --Methode-- */
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;
210 sprintf(buff, "BITPIX = %20d / number of bits per data pixel", bpix);
211 buff[strlen(buff)] = ' ';
212 buff = header+160;
213 if (fgnax3)
214 strcpy(buff, "NAXIS = 2 / number of data axes");
215 else
216 strcpy(buff, "NAXIS = 3 / number of data axes");
217 buff[strlen(buff)] = ' ';
218 buff = header+240;
219 sprintf(buff, "NAXIS1 = %20ld / nb of pixels along X = PaquetSize", (long)nax1);
220 buff[strlen(buff)] = ' ';
221 buff = header+320;
222 sprintf(buff, "NAXIS2 = %20ld / nb of rows = NumberOfPaquets", (long)nax2);
223 buff[strlen(buff)] = ' ';
224 buff = header+400;
225 if (fgnax3)
226 sprintf(buff, "NAXIS3 = %20ld / nb of rows = NumberOfFibers", (long)nax3);
227 else
228 strcpy(buff,"COMMENT BAO-Radio / MiniFITSFile ");
229 buff[strlen(buff)] = ' ';
230
231 buff = header+480+nkeya_*80;
232 strcpy(buff,"COMMENT BAO-Radio / MiniFITSFile ");
233 buff[strlen(buff)] = ' ';
234 buff = header+560+nkeya_*80;
235 strcpy(buff,"END");
236 buff[strlen(buff)] = ' ';
237
238 return;
239}
240
241/* --Methode-- */
242int MiniFITSFile::AddKeyI(const char* key, long val, const char* comm)
243{
244 if (nkeya_ >= 28) return 0;
245 char cle[10];
246 strncpy(cle,key,8);
247 cle[8]='=';
248 for(int i=0;i<8;i++)
249 if (cle[i]=='\0') cle[i]=' ';
250 cle[9]='\0';
251 char* buff=header+480+nkeya_*80;
252 if (comm!=NULL) {
253 char tcom[50];
254 strncpy(tcom,comm,48);
255 tcom[48]='\0';
256 sprintf(buff,"%s %20ld / %s", cle, val, tcom);
257 }
258 else sprintf(buff,"%s %20ld / ", cle, val);
259 buff[strlen(buff)]=' ';
260 nkeya_++;
261 return nkeya_;
262}
263
264/* --Methode-- */
265int MiniFITSFile::AddKeyD(const char* key, double val, const char* comm)
266{
267 if (nkeya_ >= 28) return 0;
268 char cle[10];
269 strncpy(cle,key,8);
270 cle[8]='=';
271 for(int i=0;i<8;i++)
272 if (cle[i]=='\0') cle[i]=' ';
273 cle[9]='\0';
274 char* buff=header+480+nkeya_*80;
275 if (comm!=NULL) {
276 char tcom[50];
277 strncpy(tcom,comm,48);
278 tcom[48]='\0';
279 sprintf(buff,"%s %20lg / %s", cle, val, tcom);
280 }
281 else sprintf(buff,"%s %20lg / ", cle, val);
282 buff[strlen(buff)] = ' ';
283 nkeya_++;
284 return nkeya_;
285}
286
287/* --Methode-- */
288int MiniFITSFile::AddKeyS(const char* key, const char* val, const char* comm)
289{
290 if (nkeya_ >= 28) return 0;
291 char cle[10];
292 strncpy(cle,key,8);
293 cle[8]='=';
294 for(int i=0;i<8;i++)
295 if (cle[i]=='\0') cle[i]=' ';
296 cle[9]='\0';
297 char tcom[72];
298 tcom[0]='\'';
299 strncpy(tcom+1,val,65);
300 int l=strlen(tcom);
301 strcpy(tcom+l,"' / ");
302 l+=4;
303 if ((l<70)&&(comm!=NULL)) strncpy(tcom+l,comm,70-l);
304 tcom[70]='\0';
305 char* buff=header+480+nkeya_*80;
306 sprintf(buff,"%s %s", cle, tcom);
307 buff[strlen(buff)] = ' ';
308 nkeya_++;
309 return nkeya_;
310}
311
312/* --Methode-- */
313void MiniFITSFile::DecodeHeader()
314{
315 // AMELIORER le decodage de l'entete, remplissage dtype, nax1, nax2
316 char * buff = header;
317 if (strncmp(buff, "SIMPLE =", 9) != 0)
318 throw MiniFITSException("MiniFITSFile::DecodeHeader()/Error - NO SIMPLE keyword");
319 bool fgokt=false;
320 bool fgok1=false;
321 bool fgok2=false;
322 bool fgok3=false;
323 for(int kh=80; kh<2800; kh+=80) {
324 buff = header+kh;
325 if (strncmp(buff, "NAXIS1 =", 9) == 0) {
326 nax1 = atol(buff+10);
327 fgok1 = true;
328// cout << " FOUND : NAXIS1= " << nax1 << endl;
329 }
330 else if (strncmp(buff, "NAXIS2 =", 9) == 0) {
331 nax2 = atol(buff+10);
332 fgok2 = true;
333// cout << " FOUND : NAXIS2= " << nax2 << endl;
334 }
335 else if (strncmp(buff, "NAXIS3 =", 9) == 0) {
336 nax3 = atol(buff+10);
337 fgok3 = true;
338// cout << " FOUND : NAXIS2= " << nax2 << endl;
339 }
340 else if (strncmp(buff, "BITPIX =", 9) == 0) {
341 int bpix = atoi(buff+10);
342 fgokt = true;
343 if (bpix == 8) dtype = MF_Byte;
344 else if (bpix == 16) dtype = MF_Int16;
345 else if (bpix == -32) dtype = MF_Float32;
346 else fgokt = false;
347// cout << " FOUND : bpix= " << bpix << endl;
348 }
349 }
350 if (!(fgok1&&fgok2&&fgokt))
351 throw MiniFITSException("MiniFITSFile::DecodeHeader()/Error- Missing/wrong NAXIS1/2,BITPIX");
352 if (fgok3) fgnax3=true;
353 return;
354}
355
Note: See TracBrowser for help on using the repository browser.