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

Last change on this file since 3740 was 3660, checked in by cmv, 16 years ago

intro FABTColRead1F, cmv 19/10/2009

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