source: Sophya/trunk/SophyaExt/FitsIOServer/fabtcolread.cc@ 4025

Last change on this file since 4025 was 4025, checked in by cmv, 14 years ago

read/write string, complex, bufferisation enlevee pour FitsABTColRd1F, cmv 03/10/2011

File size: 63.2 KB
Line 
1/* Lecteur de colonne de table Fits (binaire ou ASCII) avec buffer */
2#include "sopnamsp.h"
3#include "machdefs.h"
4#include <stdlib.h>
5#include <stdio.h>
6#include "pexceptions.h"
7#include "fabtcolread.h"
8
9///////////////////////////////////////////////////////////////////
10///////////////////////////////////////////////////////////////////
11///////////////////////////////////////////////////////////////////
12///////////////////////////////////////////////////////////////////
13
14//! Class for opening a FITS file for reading
15
16/*!
17 \class SOPHYA::FitsOpenFile
18 \ingroup FitsIOServer
19 Class for opening a FITS file for reading
20*/
21
22/*!
23 Constructor.
24 \param fname : FITS file name to be opened for reading
25*/
26FitsOpenFile::FitsOpenFile(string fname)
27{
28 Init(fname.c_str());
29}
30
31/*!
32 Constructor.
33 \param cfname : FITS file name to be opened for reading
34*/
35FitsOpenFile::FitsOpenFile(const char *cfname)
36{
37 Init(cfname);
38}
39
40/*!
41 Constructor by default.
42*/
43FitsOpenFile::FitsOpenFile()
44{
45 FitsFN = "";
46 NHdu = IHdu = HduType = 0;
47 HasBeenPos = false;
48 FitsPtr = NULL;
49}
50
51/*!
52 Constructor by copy.
53*/
54FitsOpenFile::FitsOpenFile(FitsOpenFile& fof)
55{
56 Init(fof.FileName().c_str());
57}
58
59/*!
60 Destructor.
61*/
62FitsOpenFile::~FitsOpenFile()
63{
64 Delete();
65 FitsFN = "";
66 NHdu = IHdu = HduType = 0;
67 HasBeenPos = false;
68}
69
70/*!
71 Delete routine called by the destructor.
72*/
73void FitsOpenFile::Delete(void)
74{
75 if(FitsPtr != NULL) {
76 int sta = 0;
77 if(fits_close_file(FitsPtr,&sta)) printerror(sta);
78 FitsPtr = NULL;
79 }
80}
81
82/*! Init routine called by the constructor */
83void FitsOpenFile::Init(const char* fname)
84{
85 // Parametres Generaux
86 FitsFN = fname;
87 NHdu = IHdu = HduType = 0;
88 HasBeenPos = false;
89 FitsPtr = NULL;
90
91 // Ouverture du fichier
92 if(FitsFN.size() <= 0 )
93 throw ParmError("FitsOpenFile::Init: Fits file name error\n");
94
95 int sta = 0;
96 if(fits_open_file(&FitsPtr,FitsFN.c_str(),READONLY,&sta)) {
97 printerror(sta);
98 FitsPtr = NULL;
99 throw NullPtrError("FitsOpenFile::Init: Error opening Fits file\n");
100 }
101
102 // Get number of hdu
103 if(fits_get_num_hdus(FitsPtr,&NHdu,&sta)) {
104 printerror(sta);
105 NHdu = 0;
106 Delete();
107 throw NotAvailableOperation("FitsOpenFile::Init: Error getting NHdu\n");
108 }
109 if(NHdu<=0) {
110 Delete();
111 throw SzMismatchError("FitsOpenFile::Init: Bad NHdu\n");
112 }
113
114 MoveToHDU(1);
115}
116
117/*! Move to an HDU
118\param ihdu: hdu number to move
119\warning ihdu = [1,nhdu]
120\return 0 if positionning failed, ihdu if success
121*/
122int FitsOpenFile::MoveToHDU(int ihdu)
123{
124 if(FitsPtr==NULL)
125 throw NullPtrError("FitsOpenFile::MoveToHDU: no fits file open FitsPtr==NULL\n");
126 int ihdusave = IHdu;
127 if(ihdu<=0) ihdu=1; if(ihdu>NHdu) ihdu=NHdu;
128 int sta=0;
129 if(fits_movabs_hdu(FitsPtr,ihdu,&HduType,&sta)) {
130 printerror(sta);
131 // On se repositionne ou on etait
132 fits_movabs_hdu(FitsPtr,ihdusave,&HduType,&sta);
133 IHdu = ihdusave;
134 } else IHdu = ihdu;
135 return IHdu;
136}
137
138/*! Move to the first HDU of a certain type
139\param hdutype: type of the hdu
140\param hdudeb: start at that hdu
141\return the type of HDU the file is positionned
142*/
143int FitsOpenFile::MoveToFirst(int hdutype,int ihdudeb)
144{
145 if(ihdudeb<=0) ihdudeb=1; if(ihdudeb>NHdu) ihdudeb=NHdu;
146 int ihdusave = IHdu;
147 for(int ihdu=ihdudeb;ihdu<=NHdu;ihdu++) {
148 MoveToHDU(ihdu);
149 if(HduType==hdutype) break;
150 }
151 // Si echec, on se repositionne ou on etait
152 if(HduType!=hdutype) MoveToHDU(ihdusave);
153 return HduType;
154}
155
156/*! Move to the last HDU of a certain type
157\param hdutype: type of the hdu
158\param hdudeb: stop at that hdu
159\return the type of HDU the file is positionned
160*/
161int FitsOpenFile::MoveToLast(int hdutype,int ihdudeb)
162{
163 if(ihdudeb<=0) ihdudeb=1; if(ihdudeb>NHdu) ihdudeb=NHdu;
164 int ihdusave = IHdu;
165 for(int ihdu=NHdu;ihdu>=ihdudeb;ihdu--) {
166 MoveToHDU(ihdu);
167 if(HduType==hdutype) break;
168 }
169 // Si echec, on se repositionne ou on etait
170 if(HduType!=hdutype) MoveToHDU(ihdusave);
171 return HduType;
172}
173
174/*! Print */
175void FitsOpenFile::Print(void)
176{
177 cout<<"FitsOpenFile::Print: "<<FitsFN
178 <<" hdu="<<IHdu<<"/"<<NHdu<<" type="<<HduType
179 <<" hasbeenpos="<<HasBeenPos<<endl;
180}
181
182//////////////////////////////////////////////////////////////
183//// Methodes statiques
184//////////////////////////////////////////////////////////////
185/*!
186 Read a fitsheader key into double
187 \param fitsptr : cfitio pointer to Fits file
188 \param keyname : name of the key
189 \return value into double
190*/
191double FitsOpenFile::ReadKey(fitsfile *fitsptr,const char *keyname)
192{
193 if(keyname==NULL || fitsptr==NULL) return 0.;
194 int sta=0; double val=0.;
195 if(fits_read_key(fitsptr,TDOUBLE,keyname,&val,NULL,&sta))
196 printerror(sta);
197 return val;
198}
199
200/*!
201 Read a fitsheader key into long
202 \param fitsptr : cfitio pointer to Fits file
203 \param keyname : name of the key
204 \return value into long
205*/
206long FitsOpenFile::ReadKeyL(fitsfile *fitsptr,const char *keyname)
207{
208 if(keyname==NULL || fitsptr==NULL) return 0;
209 int sta=0; long val=0;
210 if(fits_read_key(fitsptr,TLONG,keyname,&val,NULL,&sta))
211 printerror(sta);
212 return val;
213}
214
215/*!
216 Read a fitsheader key into long
217 \param fitsptr : cfitio pointer to Fits file
218 \param keyname : name of the key
219 \return value into long long
220*/
221LONGLONG FitsOpenFile::ReadKeyLL(fitsfile *fitsptr,const char *keyname)
222{
223 if(keyname==NULL || fitsptr==NULL) return 0;
224 int sta=0; LONGLONG val=0;
225 if(fits_read_key(fitsptr,TLONGLONG,keyname,&val,NULL,&sta))
226 printerror(sta);
227 return val;
228}
229
230/*!
231 Read a fitsheader key into string
232 \param fitsptr : cfitio pointer to Fits file
233 \param keyname : name of the key
234 \return value into string
235*/
236string FitsOpenFile::ReadKeyS(fitsfile *fitsptr,const char *keyname)
237{
238 if(keyname==NULL || fitsptr==NULL) return (string)"";
239 int sta=0; char val[FLEN_VALUE];
240 if(fits_read_key(fitsptr,TSTRING,keyname,val,NULL,&sta))
241 printerror(sta);
242 string sval = val;
243 return sval;
244}
245
246/*!
247 CFitsIO error printing routine
248 \param sta : cfitio error return code
249*/
250 void FitsOpenFile::printerror(int sta)
251 {
252 int stat = sta;
253 fits_report_error(stdout,stat);
254 fflush(stdout);
255 return;
256 }
257
258///////////////////////////////////////////////////////////////////
259///////////////////////////////////////////////////////////////////
260///////////////////////////////////////////////////////////////////
261///////////////////////////////////////////////////////////////////
262
263///////////////////////////////////////////////////////////////////
264//! Class for reading a column in a FITS ASCII or BINARY table
265
266/*!
267 \class SOPHYA::FitsABTColRd
268 \ingroup FitsIOServer
269 Class for reading a column in a FITS ASCII or BINARY table.
270 You can read many columns of the same FITS table by instanciating
271 many FitsABTColRd on the same FitsOpenFile. So, the FITS file is
272 opened only once. Of course the various FitsABTColRd must read
273 the same FITS file HDU.
274 \verbatim
275 -- Exemple:
276 // Open the fits file with FitsOpenFile
277 FitsOpenFile fof = new FitsOpenFile("myfits.fits");
278 // Select the column to be read
279 FitsABTColRd fbt(fof,"BoloMuv_28",0,1000,1,3);
280 FitsABTColRd fbt2(fof,"BoloMuv_29",0,1000,1,3);
281 fbt.SetDebug(3);
282 fbt.Print(3);
283 // Read element by element
284 for(LONGLONG i=0;i<fbt.GetNbLine();i++) {
285 double x = fbt.Read(i);
286 double y = fbt2.Read(i);
287 if(i%lpmod==0) cout<<i<<": "<<x<<", "<<y<<endl;
288 }
289 // Read into a vector
290 TVector<double> data;
291 LONGLONG n = fbt.Read(32,50,data);
292 cout<<"Number of values read: "<<n<<endl;
293 data.ReSize(100);
294 n = fbt.Read(10,-1,data);
295 cout<<"Number of values read: "<<n<<endl;
296 TVector<double> data2;
297 fbt2.Read(32,50,data);
298 // Close the fits file
299 delete fof;
300 \endverbatim
301*/
302
303//////////////////////////////////////////////////////////////
304/*!
305 Constructor.
306 \param fof : Pointer to the Class for opening the FITS file
307 \param collabel : label of the column to be read
308 \param ihdu : number of the HDU where the column is.
309 \param blen : read buffer length
310 \param bsens : buffer reading direction
311 \param lp : debug level
312 \verbatim
313 - if ihdu<=0 first BINARY or ASCII table is taken
314 - if ihdu>nhdu ihdu is set to nhdu
315 - bsens>0 read forward
316 bsens<0 read backward
317 bsens==0 read centered
318 \endverbatim
319 \warning ihdu = [1,nhdu]
320*/
321FitsABTColRd::FitsABTColRd(FitsOpenFile* fof,string collabel
322 ,int ihdu,long blen,long bsens,int lp)
323{
324 Init(fof,collabel.c_str(),-1,ihdu,blen,bsens,lp);
325}
326
327/*!
328 Constructor.
329 Same as before but the column is identified by its column number
330 \param colnum : number of the column to be read
331 \warning col = [0,ncol[
332*/
333FitsABTColRd::FitsABTColRd(FitsOpenFile* fof,int colnum
334 ,int ihdu,long blen,long bsens,int lp)
335{
336 Init(fof,"",colnum,ihdu,blen,bsens,lp);
337}
338
339/*! Constructor by copy */
340FitsABTColRd::FitsABTColRd(FitsABTColRd& fbt)
341{
342 Init(fbt.GetFitsOpenFile(),fbt.GetColLabel().c_str()
343 ,fbt.GetColNum(),fbt.HDU()
344 ,fbt.GetBLen(),fbt.GetBSens(),fbt.DbgLevel);
345}
346
347/*! Constructor by default */
348FitsABTColRd::FitsABTColRd()
349{
350 ColLabel = ""; ColTUnit = ""; ColTForm = "";
351 ColNum = -1; ColTypeCode = 0; ColRepeat=0; ColDispWidth=0;
352 StrBuff = NULL;
353 NBcol = 0; NBline = 0;
354 SetNulVal(); SetDebug(0);
355 NFitsRead = 0;
356 FitsOF = NULL;
357 LineDeb = LineFin = -1;
358 Buffer = NULL;
359}
360
361/*! Init routine called by the constructor */
362void FitsABTColRd::Init(FitsOpenFile* fof,const char* collabel,int colnum
363 ,int ihdu,long blen,long bsens,int lp)
364{
365 // Initialisation des Parametres Generaux
366 ColLabel=collabel; ColTUnit=""; ColTForm="";
367 ColNum=colnum; ColTypeCode=0; ColRepeat=0; ColDispWidth=0;
368 StrBuff = NULL;
369 NBcol = 0; NBline = 0;
370 SetNulVal(); SetDebug(lp);
371 NFitsRead = 0;
372 FitsOF = NULL;
373 LineDeb = LineFin = -1;
374 Buffer = NULL;
375
376 // Caracteristiques du FitsOpenFile
377 FitsOF = fof;
378 if(FitsOF==NULL)
379 throw NullPtrError("FitsABTColRd::Init: FitsOpenFile pointer is NULL\n");
380
381 if(GetFitsPtr()==NULL)
382 throw NullPtrError("FitsABTColRd::Init: FitsPtr pointer is NULL\n");
383
384 int sta = 0;
385 if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU();
386
387 // Get HDU for bin/ascii table
388 // ATTENTION: le fichier est ouvert mais non positionne sur un HDU,
389 // une classe utilisant ce fichier doit le positionner sur un HDU.
390 // Par contre, si une autre classe utilise ce meme FitsOpenFile,
391 // elle ne peut le positionner que sur ce meme HDU !
392 if(FitsOF->GetPosStatus()==false) {
393 if(ihdu==0) { // find the first BINARY then the first ASCII
394 int rc = FitsOF->MoveToFirst(BINARY_TBL);
395 if(rc!=BINARY_TBL) FitsOF->MoveToFirst(ASCII_TBL);
396 } else {
397 int rc = FitsOF->MoveToHDU(ihdu);
398 if(rc!=ihdu)
399 throw RangeCheckError("FitsABTColRd::Init: Error moving to requested HDU\n");
400 }
401 } else { // Fits file has already been positionned
402 if(ihdu>0 && ihdu!=HDU())
403 throw RangeCheckError("FitsABTColRd::Init: file already posit. at another HDU\n");
404 }
405
406 // Check HDUType and set position status to TRUE
407 if(HDUType()!=BINARY_TBL && HDUType()!=ASCII_TBL)
408 throw TypeMismatchExc("FitsABTColRd::Init: HDU not ASCII/BINARY table\n");
409 if(DbgLevel>1) cout<<"...Init ihdu="<<ihdu<<" HduType="<<HDUType()<<endl;
410 FitsOF->SetPosStatus(true);
411
412 // Get number of columns
413 if(fits_get_num_cols(GetFitsPtr(),&NBcol,&sta)) {
414 FitsOpenFile::printerror(sta);
415 throw NotAvailableOperation("FitsABTColRd::Init: Error getting number of columns\n");
416 }
417 if(DbgLevel>1) cout<<"...Init NBcol="<<NBcol<<endl;
418 if(NBcol<1)
419 throw RangeCheckError("FitsABTColRd::Init: Bad number of colums\n");
420
421 // Get number of rows
422 if(fits_get_num_rowsll(GetFitsPtr(),&NBline,&sta)) {
423 FitsOpenFile::printerror(sta);
424 throw NotAvailableOperation("FitsABTColRd::Init: Error getting number of rows\n");
425 }
426 if(DbgLevel>1) cout<<"...Init NBline="<<NBline<<endl;
427 if(NBline<1)
428 throw RangeCheckError("FitsABTColRd::Init: Bad number of rows\n");
429
430 // Get column number
431 char labelcol[128];
432 if(ColLabel.size() > 0) {
433 strcpy(labelcol,ColLabel.c_str());
434 if(fits_get_colnum(GetFitsPtr(),CASESEN,labelcol,&ColNum,&sta)) {
435 FitsOpenFile::printerror(sta);
436 throw NotAvailableOperation("FitsABTColRd::Init: Error getting column number\n");
437 }
438 ColNum--; // Convention [0,ncol[
439 }
440 if(DbgLevel>1) cout<<"...Init ColNum="<<ColNum<<endl;
441 if(ColNum<0 || ColNum>=NBcol)
442 throw RangeCheckError("FitsABTColRd::Init: Bad column number\n");
443
444 // Get column type
445 if(fits_get_coltypell(GetFitsPtr(),ColNum+1,&ColTypeCode,NULL,NULL,&sta)) {
446 FitsOpenFile::printerror(sta);
447 throw ParmError("FitsABTColRd::Init: Error getting column type\n");
448 }
449 if(DbgLevel>1) cout<<"...Init ColTypeCode="<<ColTypeCode<<endl;
450 if(ColTypeCode<0 )
451 throw ParmError("FitsABTColRd::Init: Selected column type decoding not implemented\n");
452
453 // Get column name back, tunit, tform
454 char tunit[64], tform[64], tdisp[64];
455 LONGLONG repeat=0; double tscale=1., tzero=0.;
456 int rc=0;
457 if(HDUType()==BINARY_TBL) {
458 rc = fits_get_bcolparmsll(GetFitsPtr(),ColNum+1,labelcol,tunit,tform
459 ,&repeat,&tscale,&tzero,NULL,tdisp,&sta);
460 } else {
461 long repeatlng;
462 rc = fits_get_acolparms(GetFitsPtr(),ColNum+1,labelcol,&repeatlng,tunit,tform
463 ,&tscale,&tzero,NULL,tdisp,&sta);
464 repeat = repeatlng;
465 }
466 if(rc) {
467 FitsOpenFile::printerror(sta);
468 throw RangeCheckError("FitsABTColRd::Init: Error getting the column caracteristics\n");
469 }
470 ColLabel = labelcol;
471 ColTUnit = tunit;
472 ColTForm = tform;
473 ColRepeat = repeat;
474
475 fits_get_col_display_width(GetFitsPtr(),ColNum+1,&ColDispWidth,&sta);
476
477 // Set the buffer for reading
478 ChangeBuffer(blen,bsens);
479
480 if(DbgLevel)
481 cout<<"FitsABTColRd::Init Num="<<ColNum<<" Label="<<ColLabel
482 <<" TypeCode="<<ColTypeCode<<" TUnit="<<ColTUnit<<" TForm="<<ColTForm
483 <<" Repeat="<<ColRepeat<<" DispWidth="<<ColDispWidth<<endl;
484 if(DbgLevel>1)
485 cout<<" (tscale="<<tscale<<",tzero="<<tzero<<",tdisp="<<tdisp<<")"<<endl;
486
487}
488
489/*! Destructor. */
490FitsABTColRd::~FitsABTColRd()
491{
492 Delete();
493}
494
495/*! Delete called by the destructor */
496void FitsABTColRd::Delete(void)
497{
498 if(StrBuff!=NULL) {delete [] StrBuff; StrBuff=NULL;}
499 if(Buffer!=NULL) {delete [] Buffer; Buffer=NULL;}
500 LineDeb = LineFin = -1;
501 //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
502}
503
504//////////////////////////////////////////////////////////////
505/*! Change the buffer caracteristiques (see creator) */
506void FitsABTColRd::ChangeBuffer(long blen,long bsens)
507{
508 long oldnbuffer = NBuffer;
509
510 // Compute buffer caracteristics
511 BuffLen = (blen<=0 || ColRepeat!=1)? 1: blen;
512 BuffSens = bsens;
513 NBuffer = BuffLen;
514 if(bsens==0 && NBuffer%2==0) NBuffer++;
515
516 // De-allocate if necessary
517 if(Buffer!=NULL) {
518 // On des-alloue si pas assez de place
519 // ou si l'ancienne place est beaucoup trop grande (>25%)
520 if(oldnbuffer<NBuffer || (oldnbuffer>NBuffer+long(0.25*NBuffer)) )
521 {delete [] Buffer; Buffer=NULL;}
522 }
523
524 // Re-allocate
525 if(Buffer==NULL) Buffer = new double[NBuffer];
526
527 // Tell program that nothing is into buffer
528 LineDeb = LineFin = -1;
529}
530
531//////////////////////////////////////////////////////////////
532/*!
533 Read a fitsheader key into double
534 \param keyname : name of the key
535 \return value into double
536*/
537double FitsABTColRd::ReadKey(const char *keyname)
538{
539 return FitsOpenFile::ReadKey(GetFitsPtr(),keyname);
540}
541
542/*!
543 Read a fitsheader key into long
544 \param keyname : name of the key
545 \return value into long
546*/
547long FitsABTColRd::ReadKeyL(const char *keyname)
548{
549 return FitsOpenFile::ReadKeyL(GetFitsPtr(),keyname);
550}
551
552/*!
553 Read a fitsheader key into long long
554 \param keyname : name of the key
555 \return value into long long
556*/
557LONGLONG FitsABTColRd::ReadKeyLL(const char *keyname)
558{
559 return FitsOpenFile::ReadKeyLL(GetFitsPtr(),keyname);
560}
561
562/*!
563 Read a fitsheader key into string
564 \param keyname : name of the key
565 \return value into string
566*/
567string FitsABTColRd::ReadKeyS(const char *keyname)
568{
569 return FitsOpenFile::ReadKeyS(GetFitsPtr(),keyname);
570}
571
572/////////////////////////////////////////////////
573/*!
574 Read row "n" element "nfirstel" and return the value into a double
575 \warning be carefull for the range: row = [0,NRows[
576 \return value in double
577 \param n : number of the row to be read.
578 \verbatim
579 usebuffer == true : use read optimisation with bufferisation
580 == false : no optimisation with bufferisation
581 just read one value
582 \endverbatim
583*/
584double FitsABTColRd::Read(LONGLONG n,long nfirstel,bool usebuffer)
585// Attention: n=nline [0,NBline[, cfistio veut [1,NBline]
586// Attention: colnum [0,NBcol[ , cfistio veut [1,NBcol]
587// Attention: nfirstel [0,ColRepeat[ , cfistio veut [1,ColRepeat]
588{
589 int sta=0;
590 if(n<0 || n>=NBline)
591 throw RangeCheckError("FitsABTColRd::Read try to read outside line range\n");
592 if(nfirstel<0 || nfirstel>=ColRepeat)
593 throw RangeCheckError("FitsABTColRd::Read try to read outside element range: nfirstel>repeat\n");
594
595 // Pas de bufferisation (ou repeat=1), on lit betement
596 if(NBuffer==1 || !usebuffer || ColRepeat!=1) {
597 NFitsRead++;
598 double val;
599 fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,n+1,nfirstel+1,1,NULL,&val,NULL,&sta);
600 if(sta) {
601 FitsOpenFile::printerror(sta);
602 throw NotAvailableOperation("FitsABTColRd::Read: Error Reading Fits file\n");
603 }
604 // On ne remplit Buffer[0] que si on a choisit
605 // un mode de lecture non bufferise (n==1) DES LE DEBUT.
606 // Si on a initialement choisit un mode bufferise (avec n>1),
607 // Buffer contient les valeurs chargees auparavent.
608 // Il ne faut pas faire {Buffer[0]=val; LineDeb=LineFin=n;}
609 // car on perd l'info de ces valeurs.
610 if(NBuffer==1) {Buffer[0]=val; LineDeb=LineFin=n;}
611 return val;
612 }
613
614 // Gestion avec bufferisation (uniquement dans le cas repeat=1)
615 if(!Buffer)
616 throw RangeCheckError("FitsABTColRd::Read: Buffer not allocated\n");
617 if(n<LineDeb || n>LineFin) {
618 NFitsRead++;
619 LONGLONG row1,row2,nrow;
620 if(BuffSens>0) { // Cas remplissage forward
621 row1 = n+1;
622 row2 = row1+NBuffer-1; if(row2>NBline) row2 = NBline;
623 } else if(BuffSens<0) { // Cas remplissage backward
624 row2 = n+1;
625 row1 = row2-NBuffer+1; if(row1<1) row1 = 1;
626 } else { // Cas remplissage centre
627 row1 = n+1 - NBuffer/2; if(row1<1) row1 = 1;
628 row2 = n+1 + NBuffer/2; if(row2>NBline) row2 = NBline;
629 }
630 nrow = row2 - row1 + 1;
631 LineDeb = row1-1; LineFin = row2-1;
632 //cout<<"DBG-FitsRead: row1="<<row1<<" row2="<<row2<<" nrow="<<nrow
633 // <<" LineDeb,Fin="<<LineDeb<<","<<LineFin<<endl;
634 fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,row1,1,nrow,NULL,Buffer,NULL,&sta);
635 if(sta) {
636 FitsOpenFile::printerror(sta);
637 LineDeb = LineFin = -1;
638 throw NotAvailableOperation("FitsABTColRd::Read: Error Reading Fits file\n");
639 }
640 }
641
642 long ibuf = n-LineDeb;
643 return Buffer[ibuf];
644}
645
646/*!
647 Read row "n" element "nfirstel" and return a complex value
648*/
649complex<r_8> FitsABTColRd::ReadComplex(LONGLONG n,long nfirstel)
650{
651 int sta=0;
652 if(n<0 || n>=NBline)
653 throw RangeCheckError("FitsABTColRd::ReadComplex try to read outside line range\n");
654 if(nfirstel<0 || nfirstel>=ColRepeat)
655 throw RangeCheckError("FitsABTColRd::ReadComplex try to read outside element range: nfirstel>repeat\n");
656
657 r_8 val[2];
658 fits_read_col(GetFitsPtr(),TDBLCOMPLEX,ColNum+1,n+1,nfirstel+1,1,NULL,val,NULL,&sta);
659 if(sta) {
660 FitsOpenFile::printerror(sta);
661 throw NotAvailableOperation("FitsABTColRd::ReadComplex: Error Reading Fits file\n");
662 }
663 return complex<r_8>(val[0],val[1]);
664}
665
666/*!
667 Read row "n" element "nfirstel" and return in string (internal pointer)
668*/
669char* FitsABTColRd::ReadInStr(LONGLONG n,long nfirstel)
670{
671 int sta=0;
672 if(n<0 || n>=NBline)
673 throw RangeCheckError("FitsABTColRd::ReadInStr try to read outside line range\n");
674 if(nfirstel<0 || nfirstel>=ColRepeat)
675 throw RangeCheckError("FitsABTColRd::ReadInStr try to read outside element range: nfirstel>repeat\n");
676
677 if(StrBuff==NULL) StrBuff= new char[ColDispWidth+5];
678 char nullstr[]="";
679
680 NFitsRead++;
681 fits_read_col(GetFitsPtr(),TSTRING,ColNum+1,n+1,nfirstel+1,1,nullstr,&StrBuff,NULL,&sta);
682 if(sta) {
683 FitsOpenFile::printerror(sta);
684 throw NotAvailableOperation("FitsABTColRd::ReadInStr: Error Reading Fits file\n");
685 }
686
687 return StrBuff;
688}
689
690/*!
691 Read rows from "n1" to "n2" and return the values into TVector of double
692 \return NREAD the number of values read (n2-n1+1).
693 \warning row = [0,NRows[, the routine read [n1,n2]
694 \verbatim
695 - if n2<0 then read [n1,n2] where "n2=min(n1+vector_size-1,nrows-1)"
696 - Last row read is ALWAYS: "n2 = n1 + NREAD -1"
697 - The TVector is never resized if not necessary
698 -------------------------------------------------------------------------
699 - ex: suppose the column table contains 10 elements: nrows=10, rows=[0,9]
700
701 TVector<double> V(5);
702 bt.Read(3,5,V) -> read rows=3,4,5 -> V.Size()==5 -> return 3
703 bt.Read(3,-1,V) -> read rows=3,4,5,6,7 -> V.Size()==5 -> return 5
704 bt.Read(7,-1,V) -> read rows=7,8,9 -> V.Size()==5 -> return 3
705 bt.Read(2,-1,V) -> read rows=2,3,4,5,6 -> V.Size()==5 -> return 5
706 bt.Read(-1,5,V) -> throw exception
707
708 TVector<double> V(5);
709 bt.Read(3,99,V) -> read rows=3,4,5,6,7,8,9 -> V.Size()==7 -> return 7
710
711 TVector<double> V(5);
712 bt.Read(2,8,V) -> read rows=2,3,4,5,6,7,8 -> V.Size()==7 -> return 7
713
714 TVector<double> V;
715 bt.Read(3,5,V) -> read rows=3,4,5 -> V.Size()==3 -> return 3
716
717 TVector<double> V;
718 bt.Read(3,-1,V) -> throw exception
719 -------------------------------------------------------------------------
720 \endverbatim
721*/
722LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<double>& data)
723{
724 if(ColRepeat>1)
725 throw RangeCheckError("FitsABTColRd::Read TVector not-implemented for repeat>1 \n");
726 if(n1<0 || n1>=NBline)
727 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
728 if(data.Size()<=0 && n2<n1)
729 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
730 if(n2<0) n2 = n1 + data.Size()-1;
731 if(n2>=NBline) n2 = NBline-1;
732
733 LONGLONG nread = n2-n1+1;
734 if(data.Size()<nread) data.SetSize(nread);
735
736 //for(LONGLONG i=n1;i<=n2;i++) data(i-n1) = Read(i);
737 int sta=0;
738 fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
739 if(sta) {
740 FitsOpenFile::printerror(sta);
741 throw NotAvailableOperation("FitsABTColRd::Read_TVector<double>: Error Reading Fits file\n");
742 }
743
744 return nread;
745}
746
747/*! idem before but for TVector of float */
748LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<float>& data)
749{
750 if(ColRepeat>1)
751 throw RangeCheckError("FitsABTColRd::Read TVector not-implemented for repeat>1 \n");
752 if(n1<0 || n1>=NBline)
753 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
754 if(data.Size()<=0 && n2<n1)
755 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
756 if(n2<0) n2 = n1 + data.Size()-1;
757 if(n2>=NBline) n2 = NBline-1;
758
759 LONGLONG nread = n2-n1+1;
760 if(data.Size()<nread) data.SetSize(nread);
761
762 //for(LONGLONG i=n1;i<=n2;i++) data(i-n1) = Read(i);
763 int sta=0;
764 fits_read_col(GetFitsPtr(),TFLOAT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
765 if(sta) {
766 FitsOpenFile::printerror(sta);
767 throw NotAvailableOperation("FitsABTColRd::Read_TVector<float>: Error Reading Fits file\n");
768 }
769
770 return nread;
771}
772
773/*! idem before but for TVector of unsigned short */
774LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<uint_2>& data)
775{
776 if(ColRepeat>1)
777 throw RangeCheckError("FitsABTColRd::Read TVector not-implemented for repeat>1 \n");
778 if(n1<0 || n1>=NBline)
779 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
780 if(data.Size()<=0 && n2<n1)
781 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
782 if(n2<0) n2 = n1 + data.Size()-1;
783 if(n2>=NBline) n2 = NBline-1;
784
785 LONGLONG nread = n2-n1+1;
786 if(data.Size()<nread) data.SetSize(nread);
787
788 int sta=0;
789 fits_read_col(GetFitsPtr(),TUSHORT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
790 if(sta) {
791 FitsOpenFile::printerror(sta);
792 throw NotAvailableOperation("FitsABTColRd::Read_TVector<uint_2>: Error Reading Fits file\n");
793 }
794
795 return nread;
796}
797
798/*! idem before but for TVector of int_4 */
799LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<int_4>& data)
800{
801 if(ColRepeat>1)
802 throw RangeCheckError("FitsABTColRd::Read TVector not-implemented for repeat>1 \n");
803 if(n1<0 || n1>=NBline)
804 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
805 if(data.Size()<=0 && n2<n1)
806 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
807 if(n2<0) n2 = n1 + data.Size()-1;
808 if(n2>=NBline) n2 = NBline-1;
809
810 LONGLONG nread = n2-n1+1;
811 if(data.Size()<nread) data.SetSize(nread);
812
813 //for(LONGLONG i=n1;i<=n2;i++) data(i-n1) = Read(i);
814 int sta=0;
815 int T = (sizeof(long)==4) ? TLONG: TINT;
816 fits_read_col(GetFitsPtr(),T,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
817 if(sta) {
818 FitsOpenFile::printerror(sta);
819 throw NotAvailableOperation("FitsABTColRd::Read_TVector<int_4>: Error Reading Fits file\n");
820 }
821
822 return nread;
823}
824
825/*! idem before but for TVector of int_8 */
826LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<int_8>& data)
827{
828#ifdef TLONGLONG
829 if(ColRepeat>1)
830 throw RangeCheckError("FitsABTColRd::Read TVector not-implemented for repeat>1 \n");
831 if(n1<0 || n1>=NBline)
832 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
833 if(data.Size()<=0 && n2<n1)
834 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
835 if(n2<0) n2 = n1 + data.Size()-1;
836 if(n2>=NBline) n2 = NBline-1;
837
838 LONGLONG nread = n2-n1+1;
839 if(data.Size()<nread) data.SetSize(nread);
840
841 int sta=0;
842 fits_read_col(GetFitsPtr(),TLONGLONG,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
843 if(sta) {
844 FitsOpenFile::printerror(sta);
845 throw NotAvailableOperation("FitsABTColRd::Read_TVector<int_8>: Error Reading Fits file\n");
846 }
847
848 return nread;
849#else
850 throw PException("FitsABTColRd::Read(..,TVector<int_8>&) Not in that cfitsio version");
851#endif
852}
853
854/////////////////////////////////////////////////
855/*!
856 Return the number of the first row where "val1"<=val<="val2" starting at row "rowstart"
857 for element "nfirstel"
858 \verbatim
859 - The search is performed from "rowstart" to the end
860 in ascending order (from "rowstart" to nrows).
861 - Warning: "rowstart<0" means "rowstart==0" (search all the table column)
862 That is the default
863 \endverbatim
864 \return <0 means not found
865*/
866LONGLONG FitsABTColRd::FirstRow(long nfirstel,double val1,double val2,LONGLONG rowstart)
867{
868 if(nfirstel<0 || nfirstel>=ColRepeat)
869 throw RangeCheckError("FitsABTColRd::FirstRow try to read outside element range: nfirstel>repeat\n");
870 LONGLONG row = -1;
871 if(NBline==0) return row;
872 // Change buffer for efficiency
873 long bsens=BuffSens; bool bchange=false;
874 if(bsens<=0) {ChangeBuffer(BuffLen,1); bchange=true;}
875 if(rowstart<0) rowstart = 0;
876 if(rowstart>=NBline) rowstart = NBline-1;
877 for(LONGLONG i=rowstart;i<NBline;i++) {
878 double val = Read(i,nfirstel);
879 if(val<val1 || val>val2) continue;
880 row = i;
881 break;
882 }
883 if(bchange) ChangeBuffer(BuffLen,bsens);
884 return row;
885}
886
887/*!
888 Return the number of the last row where val1<=val<=val2 starting at row rowstart
889 for element "nfirstel"
890 \return <0 means not found
891 \verbatim
892 - The search is performed from "rowstart" to the beginning
893 in descending order (from "rowstart" to 0).
894 - Warning: "rowstart<0" means "rowstart==nrows-1" (search all the table column)
895 That is the default
896 \endverbatim
897*/
898LONGLONG FitsABTColRd::LastRow(long nfirstel,double val1,double val2,LONGLONG rowstart)
899{
900 if(nfirstel<0 || nfirstel>=ColRepeat)
901 throw RangeCheckError("FitsABTColRd::FirstRow try to read outside element range: nfirstel>repeat\n");
902 LONGLONG row = -1;
903 if(NBline==0) return row;
904 // Change buffer for efficiency
905 long bsens=BuffSens; bool bchange=false;
906 if(bsens>=0) {ChangeBuffer(BuffLen,-1); bchange=true;}
907 if(rowstart<0 || rowstart>=NBline) rowstart = NBline-1;
908 for(LONGLONG i=rowstart;i>=0;i--) {
909 double val = Read(i,nfirstel);
910 if(val<val1 || val>val2) continue;
911 row = i;
912 break;
913 }
914 if(bchange) ChangeBuffer(BuffLen,bsens);
915 return row;
916}
917
918/*! Print on stream os */
919void FitsABTColRd::Print(ostream& os,int lp) const
920{
921 os<<"FitsABTColRd:Print ("<<BuffLen<<","<<BuffSens<<","<<NulVal<<")"
922 <<" ncols="<<NBcol<<" nrows="<<NBline;
923 if(lp>0) os<<" NRead="<<NFitsRead;
924 os<<"\n... "<<FileName()<<"["<<HDU()<<"/"<<NHDU()<<" type="<<HDUType()<<"]"
925 <<"\n... Label["<<ColNum<<"]="<<ColLabel<<" TypeCode="<<ColTypeCode
926 <<" TUnit="<<ColTUnit<<" TForm="<<ColTForm<<" Repeat="<<ColRepeat
927 <<" DispWidth="<<ColDispWidth
928 <<endl;
929}
930
931///////////////////////////////////////////////////////////////////
932///////////////////////////////////////////////////////////////////
933///////////////////////////////////////////////////////////////////
934///////////////////////////////////////////////////////////////////
935
936//! Class for reading a column in a FITS ASCII or BINARY table with fits file opening
937
938/*!
939 \class SOPHYA::FitsABTColRead
940 \ingroup FitsIOServer
941 Class for reading a column in a FITS ASCII or BINARY table with fits file opening.
942 The FITS file is opened each time you instanciate a FitsABTColRead.
943 So reading "n" columns of the same FITS table by instanciating "n"
944 FitsABTColRead, will open "n" times te FITS file.
945 Use FitsABTColRd if you want to open the FITS file only once.
946 \verbatim
947 -- Exemple:
948 FitsABTColRead fbt("myfits.fits","BoloMuv_28",0,1000,1,3);
949 fbt.SetDebug(3);
950 fbt.Print(3);
951 // Read element by element
952 for(LONGLONG i=0;i<fbt.GetNbLine();i++) {
953 double x = fbt.Read(i);
954 if(i%lpmod==0) cout<<i<<": "<<x<<endl;
955 }
956 // Read into a vector
957 TVector<double> data;
958 LONGLONG n = fbt.Read(32,50,data);
959 cout<<"Number of values read: "<<n<<endl;
960 data.ReSize(100);
961 n = fbt.Read(10,-1,data);
962 cout<<"Number of values read: "<<n<<endl;
963 \endverbatim
964*/
965
966
967//////////////////////////////////////////////////////////////
968/*!
969 Constructor.
970 \param fname : FITS file name to be read
971 \param collabel : label of the column to be read
972 \param ihdu : number of the HDU where the column is.
973 \param blen : read buffer length
974 \param bsens : buffer reading direction
975 \param lp : debug level
976 \verbatim
977 - if ihdu<=0 first BINARY or ASCII table is taken
978 - if ihdu>nhdu ihdu is set to nhdu
979 - bsens>0 read forward
980 bsens<0 read backward
981 bsens==0 read centered
982 \endverbatim
983 \warning ihdu = [1,nhdu]
984*/
985FitsABTColRead::FitsABTColRead(string fname,string collabel
986 ,int ihdu,long blen,long bsens,int lp)
987: FitsABTColRd(new FitsOpenFile(fname),collabel,ihdu,blen,bsens,lp)
988{
989}
990
991/*!
992 Constructor.
993 Same as before but the column is identified by its column number
994 \param colnum : number of the column to be read
995 \warning col = [0,ncol[
996*/
997FitsABTColRead::FitsABTColRead(string fname,int colnum
998 ,int ihdu,long blen,long bsens,int lp)
999: FitsABTColRd(new FitsOpenFile(fname),colnum,ihdu,blen,bsens,lp)
1000{
1001}
1002
1003/*! Constructor. see below */
1004FitsABTColRead::FitsABTColRead(const char * cfname,const char* collabel
1005 ,int ihdu,long blen,long bsens,int lp)
1006: FitsABTColRd(new FitsOpenFile(cfname),collabel,ihdu,blen,bsens,lp)
1007{
1008}
1009
1010/*! Constructor. see below */
1011FitsABTColRead::FitsABTColRead(const char * cfname,int colnum
1012 ,int ihdu,long blen,long bsens,int lp)
1013: FitsABTColRd(new FitsOpenFile(cfname),colnum,ihdu,blen,bsens,lp)
1014{
1015}
1016/*! Constructor by default */
1017FitsABTColRead::FitsABTColRead()
1018: FitsABTColRd()
1019{
1020}
1021
1022/*! Constructor by copy */
1023FitsABTColRead::FitsABTColRead(FitsABTColRead& fbt)
1024{
1025 // --- ATTENTION ---
1026 // FitsABTColRead ferme le fichier FITS: il faut dupliquer le FitsOpenFile
1027 FitsOpenFile* fof = new FitsOpenFile(*fbt.GetFitsOpenFile());
1028 Init(fof,fbt.GetColLabel().c_str()
1029 ,fbt.GetColNum(),fbt.HDU()
1030 ,fbt.GetBLen(),fbt.GetBSens(),fbt.DbgLevel);
1031}
1032
1033/*! Destructor. */
1034FitsABTColRead::~FitsABTColRead()
1035{
1036 Delete(); // ?? inutile ??
1037 // On detruit le FitsOpenFile, cad qu'on ferme (fits_file_close) le fichier FITS
1038 if(FitsOF!=NULL) delete FitsOF;
1039}
1040
1041///////////////////////////////////////////////////////////////////
1042///////////////////////////////////////////////////////////////////
1043///////////////////////////////////////////////////////////////////
1044///////////////////////////////////////////////////////////////////
1045
1046FitsABTColRd1F::FitsABTColRd1F(FitsOpenFile* fof,int ihdu,int lp)
1047{
1048 Init(fof,ihdu,lp);
1049}
1050
1051/*! Init routine called by the constructor */
1052void FitsABTColRd1F::Init(FitsOpenFile* fof,int ihdu,int lp)
1053{
1054 // Initialisation des Parametres Generaux
1055 ColLabel.resize(0); ColTUnit.resize(0); ColTForm.resize(0);
1056 ColTypeCode.resize(0); ColRepeat.resize(0); ColDispWidth.resize(0);
1057 StrBuff.resize(0);
1058 NBcol = 0; NBline = 0;
1059 SetNulVal(); SetDebug(lp);
1060 FitsOF = NULL;
1061
1062 // Caracteristiques du FitsOpenFile
1063 FitsOF = fof;
1064 if(FitsOF==NULL)
1065 throw NullPtrError("FitsABTColRd1F::Init: FitsOpenFile pointer is NULL\n");
1066
1067 if(GetFitsPtr()==NULL)
1068 throw NullPtrError("FitsABTColRd1F::Init: FitsPtr pointer is NULL\n");
1069
1070 int sta = 0;
1071 if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU();
1072
1073 // Get HDU for bin/ascii table
1074 // ATTENTION: le fichier est ouvert mais non positionne sur un HDU,
1075 // une classe utilisant ce fichier doit le positionner sur un HDU.
1076 // Par contre, si une autre classe utilise ce meme FitsOpenFile,
1077 // elle ne peut le positionner que sur ce meme HDU !
1078 if(FitsOF->GetPosStatus()==false) {
1079 if(ihdu==0) { // find the first BINARY then the first ASCII
1080 int rc = FitsOF->MoveToFirst(BINARY_TBL);
1081 if(rc!=BINARY_TBL) FitsOF->MoveToFirst(ASCII_TBL);
1082 } else {
1083 int rc = FitsOF->MoveToHDU(ihdu);
1084 if(rc!=ihdu)
1085 throw RangeCheckError("FitsABTColRd1F::Init: Error moving to requested HDU\n");
1086 }
1087 } else { // Fits file has already been positionned
1088 if(ihdu>0 && ihdu!=HDU())
1089 throw RangeCheckError("FitsABTColRd1F::Init: file already posit. at another HDU\n");
1090 }
1091
1092 // Check HDUType and set position status to TRUE
1093 if(HDUType()!=BINARY_TBL && HDUType()!=ASCII_TBL)
1094 throw TypeMismatchExc("FitsABTColRd1F::Init: HDU not ASCII/BINARY table\n");
1095 if(DbgLevel>1) cout<<"...Init ihdu="<<ihdu<<" HduType="<<HDUType()<<endl;
1096 FitsOF->SetPosStatus(true);
1097
1098 // Get number of columns
1099 if(fits_get_num_cols(GetFitsPtr(),&NBcol,&sta)) {
1100 FitsOpenFile::printerror(sta);
1101 throw NotAvailableOperation("FitsABTColRd1F::Init: Error getting number of columns\n");
1102 }
1103 if(DbgLevel>1) cout<<"...Init NBcol="<<NBcol<<endl;
1104 if(NBcol<1)
1105 throw RangeCheckError("FitsABTColRd1F::Init: Bad number of colums\n");
1106
1107 // Get number of rows
1108 if(fits_get_num_rowsll(GetFitsPtr(),&NBline,&sta)) {
1109 FitsOpenFile::printerror(sta);
1110 throw NotAvailableOperation("FitsABTColRd1F::Init: Error getting number of rows\n");
1111 }
1112 if(DbgLevel>1) cout<<"...Init NBline="<<NBline<<endl;
1113 if(NBline<1)
1114 throw RangeCheckError("FitsABTColRd1F::Init: Bad number of rows\n");
1115
1116 // --- Boucle sur les colonnes
1117 for(int ColNum=0;ColNum<NBcol;ColNum++) { // ***** ColNum
1118 // Get column type
1119 ColTypeCode.push_back(-999);
1120 if(fits_get_coltypell(GetFitsPtr(),ColNum+1,&ColTypeCode[ColNum],NULL,NULL,&sta)) {
1121 FitsOpenFile::printerror(sta);
1122 throw ParmError("FitsABTColRd1F::Init: Error getting column type\n");
1123 }
1124 if(DbgLevel>1) cout<<"...Init ColTypeCode="<<ColTypeCode[ColNum]<<endl;
1125 if(ColTypeCode[ColNum]<0 )
1126 throw ParmError("FitsABTColRd1F::Init: Selected column type decoding not implemented\n");
1127 // Get column name, tunit, tform
1128 char labelcol[128];
1129 char tunit[64], tform[64], tdisp[64];
1130 LONGLONG repeat=0; double tscale=1., tzero=0.;
1131 int rc=0;
1132 if(HDUType()==BINARY_TBL) {
1133 rc = fits_get_bcolparmsll(GetFitsPtr(),ColNum+1,labelcol,tunit,tform
1134 ,&repeat,&tscale,&tzero,NULL,tdisp,&sta);
1135 } else {
1136 long repeatlng;
1137 rc = fits_get_acolparms(GetFitsPtr(),ColNum+1,labelcol,&repeatlng,tunit,tform
1138 ,&tscale,&tzero,NULL,tdisp,&sta);
1139 repeat = repeatlng;
1140 }
1141 if(rc) {
1142 FitsOpenFile::printerror(sta);
1143 throw RangeCheckError("FitsABTColRd1F::Init: Error getting the column caracteristics\n");
1144 }
1145 ColLabel.push_back(labelcol);
1146 ColTUnit.push_back(tunit);
1147 ColTForm.push_back(tform);
1148 ColRepeat.push_back(repeat);
1149
1150 int cdispw = 0;
1151 fits_get_col_display_width(GetFitsPtr(),ColNum+1,&cdispw,&sta);
1152 ColDispWidth.push_back(cdispw);
1153 StrBuff.push_back(NULL);
1154
1155 // some debug print if requested
1156 if(DbgLevel)
1157 cout<<"FitsABTColRd1F::Init Num="<<ColNum<<" Label="<<ColLabel[ColNum]
1158 <<" TypeCode="<<ColTypeCode[ColNum]<<" TUnit="<<ColTUnit[ColNum]<<" TForm="<<ColTForm[ColNum]
1159 <<" Repeat="<<ColRepeat[ColNum]<<" ColDispWidth="<<ColDispWidth[ColNum]<<endl;
1160 if(DbgLevel>1)
1161 cout<<" (tscale="<<tscale<<",tzero="<<tzero<<",tdisp="<<tdisp<<")"<<endl;
1162 } // ***** ColNum
1163
1164}
1165
1166/*! Destructor. */
1167FitsABTColRd1F::~FitsABTColRd1F()
1168{
1169 Delete();
1170}
1171
1172/*! Delete called by the destructor */
1173void FitsABTColRd1F::Delete(void)
1174{
1175 if(NBcol>0) for(int ColNum=0; ColNum<NBcol; ColNum++) {
1176 if(StrBuff[ColNum]==NULL) continue;
1177 delete [] StrBuff[ColNum];
1178 StrBuff[ColNum] = NULL;
1179 }
1180 //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
1181}
1182
1183//////////////////////////////////////////////////////////////
1184/*!
1185 Read a fitsheader key into double
1186 \param keyname : name of the key
1187 \return value into double
1188*/
1189double FitsABTColRd1F::ReadKey(const char *keyname)
1190{
1191 return FitsOpenFile::ReadKey(GetFitsPtr(),keyname);
1192}
1193
1194/*!
1195 Read a fitsheader key into long
1196 \param keyname : name of the key
1197 \return value into long
1198*/
1199long FitsABTColRd1F::ReadKeyL(const char *keyname)
1200{
1201 return FitsOpenFile::ReadKeyL(GetFitsPtr(),keyname);
1202}
1203
1204/*!
1205 Read a fitsheader key into long long
1206 \param keyname : name of the key
1207 \return value into long long
1208*/
1209LONGLONG FitsABTColRd1F::ReadKeyLL(const char *keyname)
1210{
1211 return FitsOpenFile::ReadKeyLL(GetFitsPtr(),keyname);
1212}
1213
1214/*!
1215 Read a fitsheader key into string
1216 \param keyname : name of the key
1217 \return value into string
1218*/
1219string FitsABTColRd1F::ReadKeyS(const char *keyname)
1220{
1221 return FitsOpenFile::ReadKeyS(GetFitsPtr(),keyname);
1222}
1223
1224/////////////////////////////////////////////////
1225int FitsABTColRd1F::GetColNum(const char *colname)
1226 // Get column number from column name
1227{
1228 if(strlen(colname)<1 || NBcol<1) return -1;
1229 string slab(colname);
1230 for(int ColNum=0;ColNum<NBcol;ColNum++)
1231 if(slab == ColLabel[ColNum]) return ColNum;
1232 return -1;
1233}
1234
1235/////////////////////////////////////////////////
1236/*!
1237 Read row "n" element "nfirstel" of column "ColNum" and return the value into a double
1238 \warning be carefull for the range: row = [0,NRows[
1239 \return value in double
1240 \param n : number of the row to be read.
1241 \verbatim
1242 usebuffer == true : use read optimisation with bufferisation
1243 == false : no optimisation with bufferisation
1244 just read one value
1245 \endverbatim
1246*/
1247double FitsABTColRd1F::Read(int ColNum,LONGLONG n,long nfirstel)
1248// Attention: n=nline [0,NBline[, cfistio veut [1,NBline]
1249// Attention: colnum [0,NBcol[ , cfistio veut [1,NBcol]
1250// Attention: nfirstel [0,ColRepeat[ , cfistio veut [1,ColRepeat]
1251{
1252 int sta=0;
1253 if(ColNum<0 || ColNum>=NBcol)
1254 throw RangeCheckError("FitsABTColRd1F::Read try to read outside column range\n");
1255 if(n<0 || n>=NBline)
1256 throw RangeCheckError("FitsABTColRd1F::Read try to read outside line range\n");
1257 if(nfirstel<0 || nfirstel>=ColRepeat[ColNum])
1258 throw RangeCheckError("FitsABTColRd1F::Read try to read outside element range: nfirstel>repeat\n");
1259
1260 double val;
1261 fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,n+1,nfirstel+1,1,NULL,&val,NULL,&sta);
1262 if(sta) {
1263 FitsOpenFile::printerror(sta);
1264 throw NotAvailableOperation("FitsABTColRd1F::Read: Error Reading Fits file\n");
1265 }
1266 return val;
1267}
1268
1269
1270/*!
1271 Read row "n" element "nfirstel" and return a complex value
1272*/
1273complex<r_8> FitsABTColRd1F::ReadComplex(int ColNum,LONGLONG n,long nfirstel)
1274{
1275 int sta=0;
1276 if(ColNum<0 || ColNum>=NBcol)
1277 throw RangeCheckError("FitsABTColRd1F::ReadComplex try to read outside column range\n");
1278 if(n<0 || n>=NBline)
1279 throw RangeCheckError("FitsABTColRd1F::ReadComplex try to read outside line range\n");
1280 if(nfirstel<0 || nfirstel>=ColRepeat[ColNum])
1281 throw RangeCheckError("FitsABTColRd1F::ReadComplex try to read outside element range: nfirstel>repeat\n");
1282
1283 r_8 val[2];
1284 fits_read_col(GetFitsPtr(),TDBLCOMPLEX,ColNum+1,n+1,nfirstel+1,1,NULL,val,NULL,&sta);
1285 if(sta) {
1286 FitsOpenFile::printerror(sta);
1287 throw NotAvailableOperation("FitsABTColRd1F::ReadComplex: Error Reading Fits file\n");
1288 }
1289 return complex<r_8>(val[0],val[1]);
1290}
1291
1292/*!
1293 Read row "n" element "nfirstel" and return in string (internal pointer)
1294*/
1295char* FitsABTColRd1F::ReadInStr(int ColNum,LONGLONG n,long nfirstel)
1296{
1297 int sta=0;
1298 if(ColNum<0 || ColNum>=NBcol)
1299 throw RangeCheckError("FitsABTColRd1F::ReadInStr try to read outside column range\n");
1300 if(n<0 || n>=NBline)
1301 throw RangeCheckError("FitsABTColRd1F::ReadInStr try to read outside line range\n");
1302 if(nfirstel<0 || nfirstel>=ColRepeat[ColNum])
1303 throw RangeCheckError("FitsABTColRd1F::ReadInStr try to read outside element range: nfirstel>repeat\n");
1304
1305 if(StrBuff[ColNum]==NULL) StrBuff[ColNum] = new char[ColDispWidth[ColNum]+5];
1306 char nullstr[]="";
1307
1308 fits_read_col(GetFitsPtr(),TSTRING,ColNum+1,n+1,nfirstel+1,1,nullstr,&(StrBuff[ColNum]),NULL,&sta);
1309 if(sta) {
1310 FitsOpenFile::printerror(sta);
1311 throw NotAvailableOperation("FitsABTColRd::ReadInStr: Error Reading Fits file\n");
1312 }
1313
1314 return StrBuff[ColNum];
1315}
1316
1317/*! Print on stream os */
1318void FitsABTColRd1F::Print(ostream& os,int lp) const
1319{
1320 os<<"FitsABTColRd1F:Print ("<<NulVal<<")"
1321 <<" ncols="<<NBcol<<" nrows="<<NBline;
1322 os<<"\n... "<<FileName()<<"["<<HDU()<<"/"<<NHDU()<<" type="<<HDUType()<<"]"<<endl;
1323 if(lp>0 && NBcol>0) {
1324 for(int ColNum=0;ColNum<NBcol;ColNum++) {
1325 os<<"..Col="<<ColNum<<" Label="<<ColLabel[ColNum]<<" TypeCode="<<ColTypeCode[ColNum]
1326 <<" TUnit="<<ColTUnit[ColNum]<<" TForm="<<ColTForm[ColNum]<<" Repeat="<<ColRepeat[ColNum]
1327 <<" DispWidth="<<ColDispWidth[ColNum]
1328 <<endl;
1329 }
1330 }
1331}
1332
1333///////////////////////////////////////////////////////////////////
1334///////////////////////////////////////////////////////////////////
1335///////////////////////////////////////////////////////////////////
1336///////////////////////////////////////////////////////////////////
1337
1338/*!
1339 Constructor.
1340 Same as before but the column is identified by its column number
1341 \param colnum : number of the column to be read
1342 \warning col = [0,ncol[
1343*/
1344FitsABTColRead1F::FitsABTColRead1F(string fname,int ihdu,int lp)
1345: FitsABTColRd1F(new FitsOpenFile(fname),ihdu,lp)
1346{
1347}
1348
1349/*! Constructor. see below */
1350FitsABTColRead1F::FitsABTColRead1F(const char * cfname,int ihdu,int lp)
1351: FitsABTColRd1F(new FitsOpenFile(cfname),ihdu,lp)
1352{
1353}
1354
1355/*! Destructor. */
1356FitsABTColRead1F::~FitsABTColRead1F()
1357{
1358 Delete(); // ?? inutile ??
1359 // On detruit le FitsOpenFile, cad qu'on ferme (fits_file_close) le fichier FITS
1360 if(FitsOF!=NULL) delete FitsOF;
1361}
1362
1363///////////////////////////////////////////////////////////////////
1364///////////////////////////////////////////////////////////////////
1365///////////////////////////////////////////////////////////////////
1366///////////////////////////////////////////////////////////////////
1367
1368//! Class for reading a 2D image from a FITS file
1369
1370/*!
1371 \class SOPHYA::FitsImg2DRd
1372 \ingroup FitsIOServer
1373 Class for reading a 2D image from a FITS file
1374*/
1375
1376//////////////////////////////////////////////////////////////
1377/*!
1378 Constructor.
1379 \param fof : Pointer to the Class for opening the FITS file
1380 \param ihdu : number of the HDU where the image is.
1381 \param lp : debug level
1382 \verbatim
1383 - if ihdu<=0 first IMAGE hdu is taken
1384 - if ihdu>nhdu ihdu is set to nhdu
1385 \endverbatim
1386 \warning ihdu = [1,nhdu]
1387*/
1388FitsImg2DRd::FitsImg2DRd(FitsOpenFile* fof,int ihdu,int lp)
1389{
1390 Init(fof,ihdu,lp);
1391}
1392
1393/*! Constructor by copy */
1394FitsImg2DRd::FitsImg2DRd(FitsImg2DRd& fbt)
1395{
1396 Init(fbt.GetFitsOpenFile(),fbt.HDU(),fbt.DbgLevel);
1397}
1398
1399/*! Constructor by default */
1400FitsImg2DRd::FitsImg2DRd()
1401{
1402 Naxis[0] = Naxis[1] = 0;
1403 SetNulVal(); SetDebug(0);
1404 FitsOF = NULL;
1405}
1406
1407/*! Init routine called by the constructor */
1408void FitsImg2DRd::Init(FitsOpenFile* fof,int ihdu,int lp)
1409{
1410 // Initialisation des Parametres Generaux
1411 Naxis[0] = Naxis[1] = 0;
1412 SetNulVal(); SetDebug(lp);
1413 FitsOF = NULL;
1414
1415 // Caracteristiques du FitsOpenFile
1416 FitsOF = fof;
1417 if(FitsOF==NULL)
1418 throw NullPtrError("FitsImg2DRd::Init: FitsOpenFile pointer is NULL\n");
1419
1420 if(GetFitsPtr()==NULL)
1421 throw NullPtrError("FitsImg2DRd::Init: FitsPtr pointer is NULL\n");
1422
1423 int sta = 0;
1424 if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU();
1425
1426 // Get HDU 2D image
1427 // ATTENTION: ... cf blabla equivalent dans FitsABTColRd::Init()
1428 if(FitsOF->GetPosStatus()==false) {
1429 if(ihdu==0) { // find the first IMAGE_HDU
1430 FitsOF->MoveToFirst(IMAGE_HDU);
1431 } else {
1432 int rc = FitsOF->MoveToHDU(ihdu);
1433 if(rc!=ihdu)
1434 throw RangeCheckError("FitsImg2DRd::Init: Error moving to requested HDU\n");
1435 }
1436 } else { // Fits file has already been positionned
1437 if(ihdu>0 && ihdu!=HDU())
1438 throw RangeCheckError("FitsImg2DRd::Init: file already posit. at another HDU\n");
1439 }
1440
1441 // Check HDUType and set position status to TRUE
1442 if(HDUType()!=IMAGE_HDU)
1443 throw TypeMismatchExc("FitsImg2DRd::Init: HDU not IMAGE_HDU\n");
1444 FitsOF->SetPosStatus(true);
1445
1446 // Get NAXIS 1 et 2
1447 int nfound=0;
1448 // car fits_read_keys_lnglng n'est pas prototype dans longnam.h
1449 if(ffgknjj(GetFitsPtr(),"NAXIS",1,2,Naxis,&nfound,&sta)) {
1450 FitsOpenFile::printerror(sta);
1451 throw RangeCheckError("FitsImg2DRd::Init: Error reading NAXIS cards\n");
1452 }
1453 if(DbgLevel>1)
1454 cout<<"...Init(hdu="<<HDU()<<") NAXIS1="<<Naxis[0]<<" NAXIS2="
1455 <<Naxis[1]<<" (nfound="<<nfound<<")"<<endl;
1456 if(nfound!=2 || Naxis[0]<=0 || Naxis[1]<=0)
1457 throw NotAvailableOperation("FitsImg2DRd::Init: bad Naxis[0-1] value\n");
1458
1459}
1460
1461/*! Destructor. */
1462FitsImg2DRd::~FitsImg2DRd()
1463{
1464 //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
1465 Naxis[0] = Naxis[1] = 0;
1466}
1467
1468//////////////////////////////////////////////////////////////
1469/*!
1470 Read a fitsheader key into double
1471 \param keyname : name of the key
1472 \return value into double
1473*/
1474double FitsImg2DRd::ReadKey(const char *keyname)
1475{
1476 return FitsOpenFile::ReadKey(GetFitsPtr(),keyname);
1477}
1478
1479/*!
1480 Read a fitsheader key into long
1481 \param keyname : name of the key
1482 \return value into long
1483*/
1484long FitsImg2DRd::ReadKeyL(const char *keyname)
1485{
1486 return FitsOpenFile::ReadKeyL(GetFitsPtr(),keyname);
1487}
1488
1489/*!
1490 Read a fitsheader key into long long
1491 \param keyname : name of the key
1492 \return value into long long
1493*/
1494LONGLONG FitsImg2DRd::ReadKeyLL(const char *keyname)
1495{
1496 return FitsOpenFile::ReadKeyLL(GetFitsPtr(),keyname);
1497}
1498
1499/*!
1500 Read a fitsheader key into string
1501 \param keyname : name of the key
1502 \return value into string
1503*/
1504string FitsImg2DRd::ReadKeyS(const char *keyname)
1505{
1506 return FitsOpenFile::ReadKeyS(GetFitsPtr(),keyname);
1507}
1508
1509//////////////////////////////////////////////////////////////
1510/* REMARQUE:
1511 * Si une image FITS a NAXIS1=100 et NAXIS2=50
1512 * alors un tableau 2D juste assez grand pour contenir l'image
1513 * doit etre declare array[50][100] (et non pas array[100][50])
1514 * array[NAXIS2][NAXIS1]
1515 */
1516/*!
1517Read image into a TMatrix<uint_2>
1518\warning TMatrix data(Naxis2,Naxis1)
1519*/
1520LONGLONG FitsImg2DRd::Read(TMatrix<uint_2>& data)
1521{
1522 int sta=0;
1523 uint_2* arr = new uint_2[Naxis[0]];
1524 data.ReSize(Naxis[1],Naxis[0]);
1525
1526 for(LONGLONG j=0;j<Naxis[1];j++) {
1527 LONGLONG deb = j*Naxis[0]+1, nel = Naxis[0];
1528 fits_read_img(GetFitsPtr(),TUSHORT,deb,nel,&NulVal,arr,NULL,&sta);
1529 if(sta) {
1530 FitsOpenFile::printerror(sta); delete [] arr;
1531 throw
1532 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<uint_2>): Error Reading Fits file\n");
1533 }
1534 for(LONGLONG i=0;i<Naxis[0];i++) data(j,i) = arr[i];
1535 }
1536
1537 delete [] arr;
1538 return Naxis[0]*Naxis[1];
1539}
1540
1541/*! Read image into a TMatrix<int_4> */
1542LONGLONG FitsImg2DRd::Read(TMatrix<int_4>& data)
1543{
1544 int sta=0;
1545 int_4* arr = new int_4[Naxis[0]];
1546 data.ReSize(Naxis[1],Naxis[0]);
1547 int T = (sizeof(long)==4) ? TLONG: TINT;
1548
1549 for(LONGLONG j=0;j<Naxis[1];j++) {
1550 LONGLONG deb = j*Naxis[0]+1, nel = Naxis[0];
1551 fits_read_img(GetFitsPtr(),T,deb,nel,&NulVal,arr,NULL,&sta);
1552 if(sta) {
1553 FitsOpenFile::printerror(sta); delete [] arr;
1554 throw
1555 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<int_4>): Error Reading Fits file\n");
1556 }
1557 for(LONGLONG i=0;i<Naxis[0];i++) data(j,i) = arr[i];
1558 }
1559
1560 delete [] arr;
1561 return Naxis[0]*Naxis[1];
1562}
1563
1564/*! Read image into a TMatrix<int_8> */
1565LONGLONG FitsImg2DRd::Read(TMatrix<int_8>& data)
1566{
1567 int sta=0;
1568 int_8* arr = new int_8[Naxis[0]];
1569 data.ReSize(Naxis[1],Naxis[0]);
1570
1571 for(LONGLONG j=0;j<Naxis[1];j++) {
1572 LONGLONG deb = j*Naxis[0]+1, nel = Naxis[0];
1573 fits_read_img(GetFitsPtr(),TLONGLONG,deb,nel,&NulVal,arr,NULL,&sta);
1574 if(sta) {
1575 FitsOpenFile::printerror(sta); delete [] arr;
1576 throw
1577 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<int_8>): Error Reading Fits file\n");
1578 }
1579 for(LONGLONG i=0;i<Naxis[0];i++) data(j,i) = arr[i];
1580 }
1581
1582 delete [] arr;
1583 return Naxis[0]*Naxis[1];
1584}
1585
1586/*! Read image into a TMatrix<float> */
1587LONGLONG FitsImg2DRd::Read(TMatrix<float>& data)
1588{
1589 int sta=0;
1590 float* arr = new float[Naxis[0]];
1591 data.ReSize(Naxis[1],Naxis[0]);
1592
1593 for(LONGLONG j=0;j<Naxis[1];j++) {
1594 LONGLONG deb = j*Naxis[0]+1, nel = Naxis[0];
1595 fits_read_img(GetFitsPtr(),TFLOAT,deb,nel,&NulVal,arr,NULL,&sta);
1596 if(sta) {
1597 FitsOpenFile::printerror(sta); delete [] arr;
1598 throw
1599 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<float>): Error Reading Fits file\n");
1600 }
1601 for(LONGLONG i=0;i<Naxis[0];i++) data(j,i) = arr[i];
1602 }
1603
1604 delete [] arr;
1605 return Naxis[0]*Naxis[1];
1606}
1607
1608/*! Read image into a TMatrix<double> */
1609LONGLONG FitsImg2DRd::Read(TMatrix<double>& data)
1610{
1611 int sta=0;
1612 double* arr = new double[Naxis[0]];
1613 data.ReSize(Naxis[1],Naxis[0]);
1614
1615 for(LONGLONG j=0;j<Naxis[1];j++) {
1616 LONGLONG deb = j*Naxis[0]+1, nel = Naxis[0];
1617 fits_read_img(GetFitsPtr(),TDOUBLE,deb,nel,&NulVal,arr,NULL,&sta);
1618 if(sta) {
1619 FitsOpenFile::printerror(sta); delete [] arr;
1620 throw
1621 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<double>): Error Reading Fits file\n");
1622 }
1623 for(LONGLONG i=0;i<Naxis[0];i++) data(j,i) = arr[i];
1624 }
1625
1626 delete [] arr;
1627 return Naxis[0]*Naxis[1];
1628}
1629
1630/*! Read image pixel numcol,numrow with numcol=[0,Naxis1[ and numrow=[0,Naxis2[ */
1631double FitsImg2DRd::Read(LONGLONG numcol, LONGLONG numrow)
1632{
1633 int sta=0;
1634 if(numcol<0 || numrow<0 || numcol>=Naxis[0] || numrow>=Naxis[1])
1635 throw
1636 NotAvailableOperation("FitsImg2DRd::Read(col,row): bad col/row number\n");
1637
1638 LONGLONG deb = numrow*Naxis[0] + numcol + 1;
1639 double val = 0.;
1640 fits_read_img(GetFitsPtr(),TDOUBLE,deb,1,&NulVal,&val,NULL,&sta);
1641
1642 if(sta) {
1643 FitsOpenFile::printerror(sta);
1644 throw
1645 NotAvailableOperation("FitsImg2DRd::Read(col,num): Error Reading Fits file\n");
1646 }
1647
1648 return val;
1649}
1650
1651///////////////////////////////////////////////////////////////////
1652///////////////////////////////////////////////////////////////////
1653///////////////////////////////////////////////////////////////////
1654///////////////////////////////////////////////////////////////////
1655
1656//! Class for reading a 2D image from a FITS file
1657
1658/*!
1659 \class SOPHYA::FitsImg2DRead
1660 \ingroup FitsIOServer
1661 Class for reading a 2D image from a FITS file
1662*/
1663
1664//////////////////////////////////////////////////////////////
1665/*!
1666 Constructor.
1667 \param fname : name of the FITS file
1668 \param ihdu : number of the HDU where the image is.
1669 \param lp : debug level
1670 \verbatim
1671 - if ihdu<=0 first IMAGE hdu is taken
1672 - if ihdu>nhdu ihdu is set to nhdu
1673 \endverbatim
1674 \warning ihdu = [1,nhdu]
1675*/
1676FitsImg2DRead::FitsImg2DRead(string fname,int ihdu,int lp)
1677: FitsImg2DRd(new FitsOpenFile(fname),ihdu,lp)
1678{
1679}
1680
1681/*! Constructor. see below */
1682FitsImg2DRead::FitsImg2DRead(const char * cfname,int ihdu,int lp)
1683: FitsImg2DRd(new FitsOpenFile(cfname),ihdu,lp)
1684{
1685}
1686
1687/*! Constructor by default */
1688FitsImg2DRead::FitsImg2DRead()
1689: FitsImg2DRd()
1690{
1691}
1692
1693/*! Constructor by copy */
1694FitsImg2DRead::FitsImg2DRead(FitsImg2DRead& fimg)
1695{
1696 // --- ATTENTION ---
1697 // FitsImg2DRead ferme le fichier FITS: il faut dupliquer le FitsOpenFile
1698 FitsOpenFile* fof = new FitsOpenFile(*fimg.GetFitsOpenFile());
1699 Init(fof,fimg.HDU(),fimg.DbgLevel);
1700}
1701
1702/*! Destructor. */
1703FitsImg2DRead::~FitsImg2DRead()
1704{
1705 // On detruit le FitsOpenFile, cad qu'on ferme (fits_file_close) le fichier FITS
1706 if(FitsOF!=NULL) delete FitsOF;
1707}
1708
1709
1710
1711///////////////////////////////////////////////////////////////////
1712///////////////////////////////////////////////////////////////////
1713///////////////////////////////////////////////////////////////////
1714///////////////////////////////////////////////////////////////////
1715
1716//! Class for reading a 3D image from a FITS file
1717
1718/*!
1719 \class SOPHYA::FitsImg3DRd
1720 \ingroup FitsIOServer
1721 Class for reading a 3D image from a FITS file
1722*/
1723
1724//////////////////////////////////////////////////////////////
1725/*!
1726 Constructor.
1727 \param fof : Pointer to the Class for opening the FITS file
1728 \param ihdu : number of the HDU where the 3D image is.
1729 \param lp : debug level
1730 \verbatim
1731 - if ihdu<=0 first IMAGE hdu is taken
1732 - if ihdu>nhdu ihdu is set to nhdu
1733 \endverbatim
1734 \warning ihdu = [1,nhdu]
1735*/
1736FitsImg3DRd::FitsImg3DRd(FitsOpenFile* fof,int ihdu,int lp)
1737{
1738 Init(fof,ihdu,lp);
1739}
1740
1741/*! Constructor by copy */
1742FitsImg3DRd::FitsImg3DRd(FitsImg3DRd& fbt)
1743{
1744 Init(fbt.GetFitsOpenFile(),fbt.HDU(),fbt.DbgLevel);
1745}
1746
1747/*! Constructor by default */
1748FitsImg3DRd::FitsImg3DRd()
1749{
1750 Naxis[0] = Naxis[1] = Naxis[2] = 0;
1751 SetNulVal(); SetDebug(0);
1752 FitsOF = NULL;
1753}
1754
1755/*! Init routine called by the constructor */
1756void FitsImg3DRd::Init(FitsOpenFile* fof,int ihdu,int lp)
1757{
1758 // Initialisation des Parametres Generaux
1759 Naxis[0] = Naxis[1] = Naxis[2] = 0;
1760 SetNulVal(); SetDebug(lp);
1761 FitsOF = NULL;
1762
1763 // Caracteristiques du FitsOpenFile
1764 FitsOF = fof;
1765 if(FitsOF==NULL)
1766 throw NullPtrError("FitsImg3DRd::Init: FitsOpenFile pointer is NULL\n");
1767
1768 if(GetFitsPtr()==NULL)
1769 throw NullPtrError("FitsImg3DRd::Init: FitsPtr pointer is NULL\n");
1770
1771 int sta = 0;
1772 if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU();
1773
1774 // Get HDU 3D image
1775 // ATTENTION: ... cf blabla equivalent dans FitsABTColRd::Init()
1776 if(FitsOF->GetPosStatus()==false) {
1777 if(ihdu==0) { // find the first IMAGE_HDU
1778 FitsOF->MoveToFirst(IMAGE_HDU);
1779 } else {
1780 int rc = FitsOF->MoveToHDU(ihdu);
1781 if(rc!=ihdu)
1782 throw RangeCheckError("FitsImg3DRd::Init: Error moving to requested HDU\n");
1783 }
1784 } else { // Fits file has already been positionned
1785 if(ihdu>0 && ihdu!=HDU())
1786 throw RangeCheckError("FitsImg3DRd::Init: file already posit. at another HDU\n");
1787 }
1788
1789 // Check HDUType and set position status to TRUE
1790 if(HDUType()!=IMAGE_HDU)
1791 throw TypeMismatchExc("FitsImg3DRd::Init: HDU not IMAGE_HDU\n");
1792 FitsOF->SetPosStatus(true);
1793
1794 // Get NAXIS 1, 2 et 3
1795 int nfound=0;
1796 // car fits_read_keys_lnglng n'est pas prototype dans longnam.h
1797 if(ffgknjj(GetFitsPtr(),"NAXIS",1,3,Naxis,&nfound,&sta)) {
1798 FitsOpenFile::printerror(sta);
1799 throw RangeCheckError("FitsImg3DRd::Init: Error reading NAXIS cards\n");
1800 }
1801 if(DbgLevel>1)
1802 cout<<"...Init(hdu="<<HDU()<<") NAXIS1="<<Naxis[0]<<" NAXIS2="
1803 <<Naxis[1]<<" NAXIS3="<<Naxis[2]<<" (nfound="<<nfound<<")"<<endl;
1804 if(nfound!=3 || Naxis[0]<=0 || Naxis[1]<=0 || Naxis[2]<=0)
1805 throw NotAvailableOperation("FitsImg3DRd::Init: bad Naxis[0-2] value\n");
1806
1807}
1808
1809/*! Destructor. */
1810FitsImg3DRd::~FitsImg3DRd()
1811{
1812 //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
1813 Naxis[0] = Naxis[1] = Naxis[2] = 0;
1814}
1815
1816//////////////////////////////////////////////////////////////
1817/*!
1818 Read a fitsheader key into double
1819 \param keyname : name of the key
1820 \return value into double
1821*/
1822double FitsImg3DRd::ReadKey(const char *keyname)
1823{
1824 return FitsOpenFile::ReadKey(GetFitsPtr(),keyname);
1825}
1826
1827/*!
1828 Read a fitsheader key into long
1829 \param keyname : name of the key
1830 \return value into long
1831*/
1832long FitsImg3DRd::ReadKeyL(const char *keyname)
1833{
1834 return FitsOpenFile::ReadKeyL(GetFitsPtr(),keyname);
1835}
1836
1837/*!
1838 Read a fitsheader key into long long
1839 \param keyname : name of the key
1840 \return value into long long
1841*/
1842LONGLONG FitsImg3DRd::ReadKeyLL(const char *keyname)
1843{
1844 return FitsOpenFile::ReadKeyLL(GetFitsPtr(),keyname);
1845}
1846
1847/*!
1848 Read a fitsheader key into string
1849 \param keyname : name of the key
1850 \return value into string
1851*/
1852string FitsImg3DRd::ReadKeyS(const char *keyname)
1853{
1854 return FitsOpenFile::ReadKeyS(GetFitsPtr(),keyname);
1855}
1856
1857//////////////////////////////////////////////////////////////
1858/* REMARQUE:
1859 * Dans TArray A(naxis1,naxis2,naxis3);
1860 * A(i,j,k) -> i varie le plus vite et k le moins vite
1861 */
1862/*!
1863Read 3D image into a TArray<uint_2>
1864*/
1865LONGLONG FitsImg3DRd::Read(TArray<uint_2>& data)
1866{
1867 int sta=0;
1868 uint_2* arr = new uint_2[Naxis[0]];
1869 sa_size_t ndim[3] = {Naxis[0],Naxis[1],Naxis[2]}; data.ReSize(3,ndim);
1870
1871 for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
1872 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
1873 fits_read_img(GetFitsPtr(),TUSHORT,deb,nel,&NulVal,arr,NULL,&sta);
1874 if(sta) {
1875 FitsOpenFile::printerror(sta); delete [] arr;
1876 throw
1877 NotAvailableOperation("FitsImg3DRd::Read(TArray<uint_2>): Error Reading Fits file\n");
1878 }
1879 for(LONGLONG i=0;i<Naxis[0];i++) data(i,j,k) = arr[i];
1880 }
1881
1882 delete [] arr;
1883 return Naxis[0]*Naxis[1]*Naxis[2];
1884}
1885
1886/*! Read 3D image into a TArray<int_4> */
1887LONGLONG FitsImg3DRd::Read(TArray<int_4>& data)
1888{
1889 int sta=0;
1890 int_4* arr = new int_4[Naxis[0]];
1891 sa_size_t ndim[3] = {Naxis[0],Naxis[1],Naxis[2]}; data.ReSize(3,ndim);
1892 int T = (sizeof(long)==4) ? TLONG: TINT;
1893
1894 for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
1895 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
1896 fits_read_img(GetFitsPtr(),T,deb,nel,&NulVal,arr,NULL,&sta);
1897 if(sta) {
1898 FitsOpenFile::printerror(sta); delete [] arr;
1899 throw
1900 NotAvailableOperation("FitsImg3DRd::Read(TArray<int_4>): Error Reading Fits file\n");
1901 }
1902 for(LONGLONG i=0;i<Naxis[0];i++) data(i,j,k) = arr[i];
1903 }
1904
1905 delete [] arr;
1906 return Naxis[0]*Naxis[1]*Naxis[2];
1907}
1908
1909/*! Read 3D image into a TArray<int_8> */
1910LONGLONG FitsImg3DRd::Read(TArray<int_8>& data)
1911{
1912 int sta=0;
1913 int_8* arr = new int_8[Naxis[0]];
1914 sa_size_t ndim[3] = {Naxis[0],Naxis[1],Naxis[2]}; data.ReSize(3,ndim);
1915
1916 for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
1917 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
1918 fits_read_img(GetFitsPtr(),TLONGLONG,deb,nel,&NulVal,arr,NULL,&sta);
1919 if(sta) {
1920 FitsOpenFile::printerror(sta); delete [] arr;
1921 throw
1922 NotAvailableOperation("FitsImg3DRd::Read(TArray<int_8>): Error Reading Fits file\n");
1923 }
1924 for(LONGLONG i=0;i<Naxis[0];i++) data(i,j,k) = arr[i];
1925 }
1926
1927 delete [] arr;
1928 return Naxis[0]*Naxis[1]*Naxis[2];
1929}
1930
1931/*! Read 3D image into a TArray<float> */
1932LONGLONG FitsImg3DRd::Read(TArray<float>& data)
1933{
1934 int sta=0;
1935 float* arr = new float[Naxis[0]];
1936 sa_size_t ndim[3] = {Naxis[0],Naxis[1],Naxis[2]}; data.ReSize(3,ndim);
1937
1938 for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
1939 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
1940 fits_read_img(GetFitsPtr(),TFLOAT,deb,nel,&NulVal,arr,NULL,&sta);
1941 if(sta) {
1942 FitsOpenFile::printerror(sta); delete [] arr;
1943 throw
1944 NotAvailableOperation("FitsImg3DRd::Read(TArray<float>): Error Reading Fits file\n");
1945 }
1946 for(LONGLONG i=0;i<Naxis[0];i++) data(i,j,k) = arr[i];
1947 }
1948
1949 delete [] arr;
1950 return Naxis[0]*Naxis[1]*Naxis[2];
1951}
1952
1953/*! Read 3D image into a TArray<double> */
1954LONGLONG FitsImg3DRd::Read(TArray<double>& data)
1955{
1956 int sta=0;
1957 double* arr = new double[Naxis[0]];
1958 sa_size_t ndim[3] = {Naxis[0],Naxis[1],Naxis[2]}; data.ReSize(3,ndim);
1959
1960 for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
1961 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
1962 fits_read_img(GetFitsPtr(),TDOUBLE,deb,nel,&NulVal,arr,NULL,&sta);
1963 if(sta) {
1964 FitsOpenFile::printerror(sta); delete [] arr;
1965 throw
1966 NotAvailableOperation("FitsImg3DRd::Read(TArray<double>): Error Reading Fits file\n");
1967 }
1968 for(LONGLONG i=0;i<Naxis[0];i++) data(i,j,k) = arr[i];
1969 }
1970
1971 delete [] arr;
1972 return Naxis[0]*Naxis[1]*Naxis[2];
1973}
1974
1975/*! Read 3D image into a TVector<int_4> */
1976LONGLONG FitsImg3DRd::Read(LONGLONG j, LONGLONG k, TVector<int_4>& data)
1977{
1978 if(j<0 || k<0 || j>=Naxis[1] || k>=Naxis[2])
1979 throw NotAvailableOperation("FitsImg3DRd::Read(TVector<int_4>): bad j/k number\n");
1980 int sta=0;
1981 if(data.Size() != Naxis[0]) data.ReSize(Naxis[0]);
1982 int T = (sizeof(long)==4) ? TLONG: TINT;
1983 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
1984 fits_read_img(GetFitsPtr(),T,deb,nel,&NulVal,data.Data(),NULL,&sta);
1985 if(sta) {
1986 FitsOpenFile::printerror(sta);
1987 throw
1988 NotAvailableOperation("FitsImg3DRd::Read(TVector<int_4>): Error Reading Fits file\n");
1989 }
1990 return Naxis[0];
1991}
1992
1993/*! Read 3D image into a TVector<float> */
1994LONGLONG FitsImg3DRd::Read(LONGLONG j, LONGLONG k, TVector<float>& data)
1995{
1996 if(j<0 || k<0 || j>=Naxis[1] || k>=Naxis[2])
1997 throw NotAvailableOperation("FitsImg3DRd::Read(TVector<float>): bad j/k number\n");
1998 int sta=0;
1999 if(data.Size() != Naxis[0]) data.ReSize(Naxis[0]);
2000 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
2001 fits_read_img(GetFitsPtr(),TFLOAT,deb,nel,&NulVal,data.Data(),NULL,&sta);
2002 if(sta) {
2003 FitsOpenFile::printerror(sta);
2004 throw
2005 NotAvailableOperation("FitsImg3DRd::Read(TVector<float>): Error Reading Fits file\n");
2006 }
2007 return Naxis[0];
2008}
2009
2010/*! Read 3D image into a TVector<double> */
2011LONGLONG FitsImg3DRd::Read(LONGLONG j, LONGLONG k, TVector<double>& data)
2012{
2013 if(j<0 || k<0 || j>=Naxis[1] || k>=Naxis[2])
2014 throw NotAvailableOperation("FitsImg3DRd::Read(TVector<double>): bad j/k number\n");
2015 int sta=0;
2016 if(data.Size() != Naxis[0]) data.ReSize(Naxis[0]);
2017 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
2018 fits_read_img(GetFitsPtr(),TDOUBLE,deb,nel,&NulVal,data.Data(),NULL,&sta);
2019 if(sta) {
2020 FitsOpenFile::printerror(sta);
2021 throw
2022 NotAvailableOperation("FitsImg3DRd::Read(TVector<double>): Error Reading Fits file\n");
2023 }
2024 return Naxis[0];
2025}
2026
2027/*! Read 3D image pixel i,j,k with i=[0,Naxis1[ , j=[0,Naxis2[ , k=[0,Naxis3[ */
2028double FitsImg3DRd::Read(LONGLONG i, LONGLONG j, LONGLONG k)
2029{
2030 int sta=0;
2031 if(i<0 || j<0 || k<0 || i>=Naxis[0] || j>=Naxis[1] || k>=Naxis[2])
2032 throw
2033 NotAvailableOperation("FitsImg3DRd::Read(i,j,k): bad i/j/k number\n");
2034
2035 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+i+1;
2036 double val = 0.;
2037 fits_read_img(GetFitsPtr(),TDOUBLE,deb,1,&NulVal,&val,NULL,&sta);
2038
2039 if(sta) {
2040 FitsOpenFile::printerror(sta);
2041 throw
2042 NotAvailableOperation("FitsImg3DRd::Read(i,j,k): Error Reading Fits file\n");
2043 }
2044
2045 return val;
2046}
2047
2048///////////////////////////////////////////////////////////////////
2049///////////////////////////////////////////////////////////////////
2050///////////////////////////////////////////////////////////////////
2051///////////////////////////////////////////////////////////////////
2052
2053//! Class for reading a 3D image from a FITS file
2054
2055/*!
2056 \class SOPHYA::FitsImg3DRead
2057 \ingroup FitsIOServer
2058 Class for reading a 3D image from a FITS file
2059*/
2060
2061//////////////////////////////////////////////////////////////
2062/*!
2063 Constructor.
2064 \param fname : name of the FITS file
2065 \param ihdu : number of the HDU where the 3D image is.
2066 \param lp : debug level
2067 \verbatim
2068 - if ihdu<=0 first IMAGE hdu is taken
2069 - if ihdu>nhdu ihdu is set to nhdu
2070 \endverbatim
2071 \warning ihdu = [1,nhdu]
2072*/
2073FitsImg3DRead::FitsImg3DRead(string fname,int ihdu,int lp)
2074: FitsImg3DRd(new FitsOpenFile(fname),ihdu,lp)
2075{
2076}
2077
2078/*! Constructor. see below */
2079FitsImg3DRead::FitsImg3DRead(const char * cfname,int ihdu,int lp)
2080: FitsImg3DRd(new FitsOpenFile(cfname),ihdu,lp)
2081{
2082}
2083
2084/*! Constructor by default */
2085FitsImg3DRead::FitsImg3DRead()
2086: FitsImg3DRd()
2087{
2088}
2089
2090/*! Constructor by copy */
2091FitsImg3DRead::FitsImg3DRead(FitsImg3DRead& fimg)
2092{
2093 // --- ATTENTION ---
2094 // FitsImg3DRead ferme le fichier FITS: il faut dupliquer le FitsOpenFile
2095 FitsOpenFile* fof = new FitsOpenFile(*fimg.GetFitsOpenFile());
2096 Init(fof,fimg.HDU(),fimg.DbgLevel);
2097}
2098
2099/*! Destructor. */
2100FitsImg3DRead::~FitsImg3DRead()
2101{
2102 // On detruit le FitsOpenFile, cad qu'on ferme (fits_file_close) le fichier FITS
2103 if(FitsOF!=NULL) delete FitsOF;
2104}
Note: See TracBrowser for help on using the repository browser.