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

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

bintable avec elements vecteur, cmv 02/10/2011

File size: 62.8 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 = "";
[4023]351 ColNum = -1; ColTypeCode = 0; ColRepeat=0;
[2449]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
[4023]365 ColLabel=collabel; ColTUnit=""; ColTForm=""; ColNum=colnum; ColTypeCode=0; ColRepeat=0;
[2456]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;
[4023]471 ColRepeat = repeat;
[1654]472
[2456]473 // Set the buffer for reading
474 ChangeBuffer(blen,bsens);
475
[1654]476 if(DbgLevel)
[2449]477 cout<<"FitsABTColRd::Init Num="<<ColNum<<" Label="<<ColLabel
[4023]478 <<" TypeCode="<<ColTypeCode<<" TUnit="<<ColTUnit<<" TForm="<<ColTForm<<" Repeat="<<ColRepeat<<endl;
[2173]479 if(DbgLevel>1)
[4023]480 cout<<" (tscale="<<tscale<<",tzero="<<tzero<<",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
[4023]505 BuffLen = (blen<=0 || ColRepeat!=1)? 1: blen;
[1654]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/*!
[4023]568 Read row "n" element "nfirstel" and return the value into a double
[1659]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*/
[4023]578double FitsABTColRd::Read(LONGLONG n,long nfirstel,bool usebuffer)
[1654]579// Attention: n=nline [0,NBline[, cfistio veut [1,NBline]
580// Attention: colnum [0,NBcol[ , cfistio veut [1,NBcol]
[4023]581// Attention: nfirstel [0,ColRepeat[ , cfistio veut [1,ColRepeat]
[1654]582{
[1659]583 int sta=0;
[1654]584 if(n<0 || n>=NBline)
[2449]585 throw RangeCheckError("FitsABTColRd::Read try to read outside line range\n");
[4023]586 if(nfirstel<0 || nfirstel>=ColRepeat)
587 throw RangeCheckError("FitsABTColRd::Read try to read outside element range: nfirstel>repeat\n");
[1654]588
[4023]589 // Pas de bufferisation (ou repeat=1), on lit betement
590 if(NBuffer==1 || !usebuffer || ColRepeat!=1) {
[1654]591 NFitsRead++;
[1659]592 double val;
[4023]593 fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,n+1,nfirstel+1,1,NULL,&val,NULL,&sta);
[1654]594 if(sta) {
[2453]595 FitsOpenFile::printerror(sta);
[2449]596 throw NotAvailableOperation("FitsABTColRd::Read: Error Reading Fits file\n");
[1654]597 }
[1659]598 // On ne remplit Buffer[0] que si on a choisit
599 // un mode de lecture non bufferise (n==1) DES LE DEBUT.
600 // Si on a initialement choisit un mode bufferise (avec n>1),
601 // Buffer contient les valeurs chargees auparavent.
602 // Il ne faut pas faire {Buffer[0]=val; LineDeb=LineFin=n;}
603 // car on perd l'info de ces valeurs.
604 if(NBuffer==1) {Buffer[0]=val; LineDeb=LineFin=n;}
605 return val;
[1654]606 }
607
[4023]608 // Gestion avec bufferisation (uniquement dans le cas repeat=1)
[1659]609 if(!Buffer)
[2449]610 throw RangeCheckError("FitsABTColRd::Read: Buffer not allocated\n");
[1654]611 if(n<LineDeb || n>LineFin) {
612 NFitsRead++;
[3128]613 LONGLONG row1,row2,nrow;
[1654]614 if(BuffSens>0) { // Cas remplissage forward
615 row1 = n+1;
[1657]616 row2 = row1+NBuffer-1; if(row2>NBline) row2 = NBline;
[1654]617 } else if(BuffSens<0) { // Cas remplissage backward
618 row2 = n+1;
[1657]619 row1 = row2-NBuffer+1; if(row1<1) row1 = 1;
[1654]620 } else { // Cas remplissage centre
[1657]621 row1 = n+1 - NBuffer/2; if(row1<1) row1 = 1;
622 row2 = n+1 + NBuffer/2; if(row2>NBline) row2 = NBline;
[1654]623 }
624 nrow = row2 - row1 + 1;
625 LineDeb = row1-1; LineFin = row2-1;
626 //cout<<"DBG-FitsRead: row1="<<row1<<" row2="<<row2<<" nrow="<<nrow
627 // <<" LineDeb,Fin="<<LineDeb<<","<<LineFin<<endl;
[3114]628 fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,row1,1,nrow,NULL,Buffer,NULL,&sta);
[1654]629 if(sta) {
[2453]630 FitsOpenFile::printerror(sta);
[1654]631 LineDeb = LineFin = -1;
[2449]632 throw NotAvailableOperation("FitsABTColRd::Read: Error Reading Fits file\n");
[1654]633 }
634 }
635
636 long ibuf = n-LineDeb;
637 return Buffer[ibuf];
638}
639
640/*!
[1659]641 Read rows from "n1" to "n2" and return the values into TVector of double
642 \return NREAD the number of values read (n2-n1+1).
643 \warning row = [0,NRows[, the routine read [n1,n2]
[1654]644 \verbatim
[1659]645 - if n2<0 then read [n1,n2] where "n2=min(n1+vector_size-1,nrows-1)"
646 - Last row read is ALWAYS: "n2 = n1 + NREAD -1"
647 - The TVector is never resized if not necessary
648 -------------------------------------------------------------------------
649 - ex: suppose the column table contains 10 elements: nrows=10, rows=[0,9]
650
651 TVector<double> V(5);
652 bt.Read(3,5,V) -> read rows=3,4,5 -> V.Size()==5 -> return 3
653 bt.Read(3,-1,V) -> read rows=3,4,5,6,7 -> V.Size()==5 -> return 5
654 bt.Read(7,-1,V) -> read rows=7,8,9 -> V.Size()==5 -> return 3
655 bt.Read(2,-1,V) -> read rows=2,3,4,5,6 -> V.Size()==5 -> return 5
656 bt.Read(-1,5,V) -> throw exception
657
658 TVector<double> V(5);
659 bt.Read(3,99,V) -> read rows=3,4,5,6,7,8,9 -> V.Size()==7 -> return 7
660
661 TVector<double> V(5);
662 bt.Read(2,8,V) -> read rows=2,3,4,5,6,7,8 -> V.Size()==7 -> return 7
663
664 TVector<double> V;
665 bt.Read(3,5,V) -> read rows=3,4,5 -> V.Size()==3 -> return 3
666
667 TVector<double> V;
668 bt.Read(3,-1,V) -> throw exception
669 -------------------------------------------------------------------------
[1654]670 \endverbatim
671*/
[3128]672LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<double>& data)
[1654]673{
[4023]674 if(ColRepeat>1)
675 throw RangeCheckError("FitsABTColRd::Read TVector not-implemented for repeat>1 \n");
[1659]676 if(n1<0 || n1>=NBline)
[2449]677 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
[1659]678 if(data.Size()<=0 && n2<n1)
[2449]679 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
[1659]680 if(n2<0) n2 = n1 + data.Size()-1;
681 if(n2>=NBline) n2 = NBline-1;
[1654]682
[3128]683 LONGLONG nread = n2-n1+1;
[1659]684 if(data.Size()<nread) data.SetSize(nread);
685
[3128]686 //for(LONGLONG i=n1;i<=n2;i++) data(i-n1) = Read(i);
[1659]687 int sta=0;
[3114]688 fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
[1659]689 if(sta) {
[2453]690 FitsOpenFile::printerror(sta);
[2449]691 throw NotAvailableOperation("FitsABTColRd::Read_TVector<double>: Error Reading Fits file\n");
[1659]692 }
693
694 return nread;
[1654]695}
696
[1659]697/*! idem before but for TVector of float */
[3128]698LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<float>& data)
[1659]699{
[4023]700 if(ColRepeat>1)
701 throw RangeCheckError("FitsABTColRd::Read TVector not-implemented for repeat>1 \n");
[1659]702 if(n1<0 || n1>=NBline)
[2449]703 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
[1659]704 if(data.Size()<=0 && n2<n1)
[2449]705 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
[1659]706 if(n2<0) n2 = n1 + data.Size()-1;
707 if(n2>=NBline) n2 = NBline-1;
708
[3128]709 LONGLONG nread = n2-n1+1;
[1659]710 if(data.Size()<nread) data.SetSize(nread);
711
[3128]712 //for(LONGLONG i=n1;i<=n2;i++) data(i-n1) = Read(i);
[1659]713 int sta=0;
[3114]714 fits_read_col(GetFitsPtr(),TFLOAT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
[1659]715 if(sta) {
[2453]716 FitsOpenFile::printerror(sta);
[2449]717 throw NotAvailableOperation("FitsABTColRd::Read_TVector<float>: Error Reading Fits file\n");
[1659]718 }
719
720 return nread;
721}
722
[2170]723/*! idem before but for TVector of unsigned short */
[3128]724LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<uint_2>& data)
[2170]725{
[4023]726 if(ColRepeat>1)
727 throw RangeCheckError("FitsABTColRd::Read TVector not-implemented for repeat>1 \n");
[2170]728 if(n1<0 || n1>=NBline)
[2449]729 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
[2170]730 if(data.Size()<=0 && n2<n1)
[2449]731 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
[2170]732 if(n2<0) n2 = n1 + data.Size()-1;
733 if(n2>=NBline) n2 = NBline-1;
734
[3128]735 LONGLONG nread = n2-n1+1;
[2170]736 if(data.Size()<nread) data.SetSize(nread);
737
738 int sta=0;
[3114]739 fits_read_col(GetFitsPtr(),TUSHORT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
[2170]740 if(sta) {
[2453]741 FitsOpenFile::printerror(sta);
[2449]742 throw NotAvailableOperation("FitsABTColRd::Read_TVector<uint_2>: Error Reading Fits file\n");
[2170]743 }
744
745 return nread;
746}
747
[1659]748/*! idem before but for TVector of int_4 */
[3128]749LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<int_4>& data)
[1659]750{
[4023]751 if(ColRepeat>1)
752 throw RangeCheckError("FitsABTColRd::Read TVector not-implemented for repeat>1 \n");
[1659]753 if(n1<0 || n1>=NBline)
[2449]754 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
[1659]755 if(data.Size()<=0 && n2<n1)
[2449]756 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
[1659]757 if(n2<0) n2 = n1 + data.Size()-1;
758 if(n2>=NBline) n2 = NBline-1;
759
[3128]760 LONGLONG nread = n2-n1+1;
[1659]761 if(data.Size()<nread) data.SetSize(nread);
762
[3128]763 //for(LONGLONG i=n1;i<=n2;i++) data(i-n1) = Read(i);
[1659]764 int sta=0;
765 int T = (sizeof(long)==4) ? TLONG: TINT;
[3114]766 fits_read_col(GetFitsPtr(),T,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
[1659]767 if(sta) {
[2453]768 FitsOpenFile::printerror(sta);
[2449]769 throw NotAvailableOperation("FitsABTColRd::Read_TVector<int_4>: Error Reading Fits file\n");
[1659]770 }
771
772 return nread;
773}
774
[2169]775/*! idem before but for TVector of int_8 */
[3128]776LONGLONG FitsABTColRd::Read(LONGLONG n1,LONGLONG n2,TVector<int_8>& data)
[2169]777{
778#ifdef TLONGLONG
[4023]779 if(ColRepeat>1)
780 throw RangeCheckError("FitsABTColRd::Read TVector not-implemented for repeat>1 \n");
[2169]781 if(n1<0 || n1>=NBline)
[2449]782 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
[2169]783 if(data.Size()<=0 && n2<n1)
[2449]784 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
[2169]785 if(n2<0) n2 = n1 + data.Size()-1;
786 if(n2>=NBline) n2 = NBline-1;
787
[3128]788 LONGLONG nread = n2-n1+1;
[2169]789 if(data.Size()<nread) data.SetSize(nread);
790
791 int sta=0;
[3114]792 fits_read_col(GetFitsPtr(),TLONGLONG,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
[2169]793 if(sta) {
[2453]794 FitsOpenFile::printerror(sta);
[2449]795 throw NotAvailableOperation("FitsABTColRd::Read_TVector<int_8>: Error Reading Fits file\n");
[2169]796 }
797
798 return nread;
799#else
[2449]800 throw PException("FitsABTColRd::Read(..,TVector<int_8>&) Not in that cfitsio version");
[2169]801#endif
802}
803
[1654]804/////////////////////////////////////////////////
[1659]805/*!
806 Return the number of the first row where "val1"<=val<="val2" starting at row "rowstart"
[4023]807 for element "nfirstel"
[1659]808 \verbatim
809 - The search is performed from "rowstart" to the end
810 in ascending order (from "rowstart" to nrows).
811 - Warning: "rowstart<0" means "rowstart==0" (search all the table column)
812 That is the default
813 \endverbatim
814 \return <0 means not found
815*/
[4023]816LONGLONG FitsABTColRd::FirstRow(long nfirstel,double val1,double val2,LONGLONG rowstart)
[1659]817{
[4023]818 if(nfirstel<0 || nfirstel>=ColRepeat)
819 throw RangeCheckError("FitsABTColRd::FirstRow try to read outside element range: nfirstel>repeat\n");
[3128]820 LONGLONG row = -1;
[1659]821 if(NBline==0) return row;
822 // Change buffer for efficiency
823 long bsens=BuffSens; bool bchange=false;
824 if(bsens<=0) {ChangeBuffer(BuffLen,1); bchange=true;}
825 if(rowstart<0) rowstart = 0;
826 if(rowstart>=NBline) rowstart = NBline-1;
[3128]827 for(LONGLONG i=rowstart;i<NBline;i++) {
[4023]828 double val = Read(i,nfirstel);
[1659]829 if(val<val1 || val>val2) continue;
830 row = i;
831 break;
832 }
833 if(bchange) ChangeBuffer(BuffLen,bsens);
834 return row;
835}
836
837/*!
[4023]838 Return the number of the last row where val1<=val<=val2 starting at row rowstart
839 for element "nfirstel"
[1659]840 \return <0 means not found
841 \verbatim
842 - The search is performed from "rowstart" to the beginning
843 in descending order (from "rowstart" to 0).
844 - Warning: "rowstart<0" means "rowstart==nrows-1" (search all the table column)
845 That is the default
846 \endverbatim
847*/
[4023]848LONGLONG FitsABTColRd::LastRow(long nfirstel,double val1,double val2,LONGLONG rowstart)
[1659]849{
[4023]850 if(nfirstel<0 || nfirstel>=ColRepeat)
851 throw RangeCheckError("FitsABTColRd::FirstRow try to read outside element range: nfirstel>repeat\n");
[3128]852 LONGLONG row = -1;
[1659]853 if(NBline==0) return row;
854 // Change buffer for efficiency
855 long bsens=BuffSens; bool bchange=false;
856 if(bsens>=0) {ChangeBuffer(BuffLen,-1); bchange=true;}
857 if(rowstart<0 || rowstart>=NBline) rowstart = NBline-1;
[3128]858 for(LONGLONG i=rowstart;i>=0;i--) {
[4023]859 double val = Read(i,nfirstel);
[1659]860 if(val<val1 || val>val2) continue;
861 row = i;
862 break;
863 }
864 if(bchange) ChangeBuffer(BuffLen,bsens);
865 return row;
866}
867
[1654]868/*! Print on stream os */
[2449]869void FitsABTColRd::Print(ostream& os,int lp) const
[1654]870{
[2449]871 os<<"FitsABTColRd:Print ("<<BuffLen<<","<<BuffSens<<","<<NulVal<<")"
[1654]872 <<" ncols="<<NBcol<<" nrows="<<NBline;
873 if(lp>0) os<<" NRead="<<NFitsRead;
[2456]874 os<<"\n... "<<FileName()<<"["<<HDU()<<"/"<<NHDU()<<" type="<<HDUType()<<"]"
875 <<"\n... Label["<<ColNum<<"]="<<ColLabel<<" TypeCode="<<ColTypeCode
[4023]876 <<" TUnit="<<ColTUnit<<" TForm="<<ColTForm<<" Repeat="<<ColRepeat
[1654]877 <<endl;
878}
[2449]879
880///////////////////////////////////////////////////////////////////
881///////////////////////////////////////////////////////////////////
882///////////////////////////////////////////////////////////////////
883///////////////////////////////////////////////////////////////////
884
885//! Class for reading a column in a FITS ASCII or BINARY table with fits file opening
886
887/*!
888 \class SOPHYA::FitsABTColRead
889 \ingroup FitsIOServer
[2789]890 Class for reading a column in a FITS ASCII or BINARY table with fits file opening.
891 The FITS file is opened each time you instanciate a FitsABTColRead.
892 So reading "n" columns of the same FITS table by instanciating "n"
893 FitsABTColRead, will open "n" times te FITS file.
894 Use FitsABTColRd if you want to open the FITS file only once.
[2449]895 \verbatim
896 -- Exemple:
897 FitsABTColRead fbt("myfits.fits","BoloMuv_28",0,1000,1,3);
898 fbt.SetDebug(3);
899 fbt.Print(3);
900 // Read element by element
[3128]901 for(LONGLONG i=0;i<fbt.GetNbLine();i++) {
[2449]902 double x = fbt.Read(i);
903 if(i%lpmod==0) cout<<i<<": "<<x<<endl;
904 }
905 // Read into a vector
906 TVector<double> data;
[3128]907 LONGLONG n = fbt.Read(32,50,data);
[2449]908 cout<<"Number of values read: "<<n<<endl;
909 data.ReSize(100);
910 n = fbt.Read(10,-1,data);
911 cout<<"Number of values read: "<<n<<endl;
912 \endverbatim
913*/
914
915
916//////////////////////////////////////////////////////////////
917/*!
918 Constructor.
919 \param fname : FITS file name to be read
920 \param collabel : label of the column to be read
921 \param ihdu : number of the HDU where the column is.
922 \param blen : read buffer length
923 \param bsens : buffer reading direction
924 \param lp : debug level
925 \verbatim
[2456]926 - if ihdu<=0 first BINARY or ASCII table is taken
927 - if ihdu>nhdu ihdu is set to nhdu
[2449]928 - bsens>0 read forward
929 bsens<0 read backward
930 bsens==0 read centered
931 \endverbatim
932 \warning ihdu = [1,nhdu]
933*/
934FitsABTColRead::FitsABTColRead(string fname,string collabel
935 ,int ihdu,long blen,long bsens,int lp)
936: FitsABTColRd(new FitsOpenFile(fname),collabel,ihdu,blen,bsens,lp)
937{
938}
939
940/*!
941 Constructor.
942 Same as before but the column is identified by its column number
943 \param colnum : number of the column to be read
944 \warning col = [0,ncol[
945*/
946FitsABTColRead::FitsABTColRead(string fname,int colnum
947 ,int ihdu,long blen,long bsens,int lp)
948: FitsABTColRd(new FitsOpenFile(fname),colnum,ihdu,blen,bsens,lp)
949{
950}
951
952/*! Constructor. see below */
953FitsABTColRead::FitsABTColRead(const char * cfname,const char* collabel
954 ,int ihdu,long blen,long bsens,int lp)
955: FitsABTColRd(new FitsOpenFile(cfname),collabel,ihdu,blen,bsens,lp)
956{
957}
958
959/*! Constructor. see below */
960FitsABTColRead::FitsABTColRead(const char * cfname,int colnum
961 ,int ihdu,long blen,long bsens,int lp)
962: FitsABTColRd(new FitsOpenFile(cfname),colnum,ihdu,blen,bsens,lp)
963{
964}
965/*! Constructor by default */
966FitsABTColRead::FitsABTColRead()
[2791]967: FitsABTColRd()
[2449]968{
969}
970
971/*! Constructor by copy */
972FitsABTColRead::FitsABTColRead(FitsABTColRead& fbt)
973{
974 // --- ATTENTION ---
975 // FitsABTColRead ferme le fichier FITS: il faut dupliquer le FitsOpenFile
976 FitsOpenFile* fof = new FitsOpenFile(*fbt.GetFitsOpenFile());
977 Init(fof,fbt.GetColLabel().c_str()
[2456]978 ,fbt.GetColNum(),fbt.HDU()
[2449]979 ,fbt.GetBLen(),fbt.GetBSens(),fbt.DbgLevel);
980}
981
982/*! Destructor. */
983FitsABTColRead::~FitsABTColRead()
984{
[2789]985 Delete(); // ?? inutile ??
986 // On detruit le FitsOpenFile, cad qu'on ferme (fits_file_close) le fichier FITS
[2449]987 if(FitsOF!=NULL) delete FitsOF;
988}
[2453]989
990///////////////////////////////////////////////////////////////////
[2791]991///////////////////////////////////////////////////////////////////
992///////////////////////////////////////////////////////////////////
993///////////////////////////////////////////////////////////////////
994
[3660]995FitsABTColRd1F::FitsABTColRd1F(FitsOpenFile* fof,int ihdu,long blen,long bsens,int lp)
996{
997 Init(fof,ihdu,blen,bsens,lp);
998}
999
1000/*! Init routine called by the constructor */
1001void FitsABTColRd1F::Init(FitsOpenFile* fof,int ihdu,long blen,long bsens,int lp)
1002{
1003 // Initialisation des Parametres Generaux
[4023]1004 ColLabel.resize(0); ColTUnit.resize(0); ColTForm.resize(0); ColTypeCode.resize(0); ColRepeat.resize(0);
[3660]1005 NBcol = 0; NBline = 0;
1006 SetNulVal(); SetDebug(lp);
1007 FitsOF = NULL;
1008 LineDeb.resize(0); LineFin.resize(0);
1009 Buffer = NULL;
1010
1011 // Caracteristiques du FitsOpenFile
1012 FitsOF = fof;
1013 if(FitsOF==NULL)
1014 throw NullPtrError("FitsABTColRd1F::Init: FitsOpenFile pointer is NULL\n");
1015
1016 if(GetFitsPtr()==NULL)
1017 throw NullPtrError("FitsABTColRd1F::Init: FitsPtr pointer is NULL\n");
1018
1019 int sta = 0;
1020 if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU();
1021
1022 // Get HDU for bin/ascii table
1023 // ATTENTION: le fichier est ouvert mais non positionne sur un HDU,
1024 // une classe utilisant ce fichier doit le positionner sur un HDU.
1025 // Par contre, si une autre classe utilise ce meme FitsOpenFile,
1026 // elle ne peut le positionner que sur ce meme HDU !
1027 if(FitsOF->GetPosStatus()==false) {
1028 if(ihdu==0) { // find the first BINARY then the first ASCII
1029 int rc = FitsOF->MoveToFirst(BINARY_TBL);
1030 if(rc!=BINARY_TBL) FitsOF->MoveToFirst(ASCII_TBL);
1031 } else {
1032 int rc = FitsOF->MoveToHDU(ihdu);
1033 if(rc!=ihdu)
1034 throw RangeCheckError("FitsABTColRd1F::Init: Error moving to requested HDU\n");
1035 }
1036 } else { // Fits file has already been positionned
1037 if(ihdu>0 && ihdu!=HDU())
1038 throw RangeCheckError("FitsABTColRd1F::Init: file already posit. at another HDU\n");
1039 }
1040
1041 // Check HDUType and set position status to TRUE
1042 if(HDUType()!=BINARY_TBL && HDUType()!=ASCII_TBL)
1043 throw TypeMismatchExc("FitsABTColRd1F::Init: HDU not ASCII/BINARY table\n");
1044 if(DbgLevel>1) cout<<"...Init ihdu="<<ihdu<<" HduType="<<HDUType()<<endl;
1045 FitsOF->SetPosStatus(true);
1046
1047 // Get number of columns
1048 if(fits_get_num_cols(GetFitsPtr(),&NBcol,&sta)) {
1049 FitsOpenFile::printerror(sta);
1050 throw NotAvailableOperation("FitsABTColRd1F::Init: Error getting number of columns\n");
1051 }
1052 if(DbgLevel>1) cout<<"...Init NBcol="<<NBcol<<endl;
1053 if(NBcol<1)
1054 throw RangeCheckError("FitsABTColRd1F::Init: Bad number of colums\n");
1055
1056 // Get number of rows
1057 if(fits_get_num_rowsll(GetFitsPtr(),&NBline,&sta)) {
1058 FitsOpenFile::printerror(sta);
1059 throw NotAvailableOperation("FitsABTColRd1F::Init: Error getting number of rows\n");
1060 }
1061 if(DbgLevel>1) cout<<"...Init NBline="<<NBline<<endl;
1062 if(NBline<1)
1063 throw RangeCheckError("FitsABTColRd1F::Init: Bad number of rows\n");
1064
1065 // --- Boucle sur les colonnes
1066 for(int ColNum=0;ColNum<NBcol;ColNum++) { // ***** ColNum
1067 // Get column type
1068 ColTypeCode.push_back(-999);
1069 if(fits_get_coltypell(GetFitsPtr(),ColNum+1,&ColTypeCode[ColNum],NULL,NULL,&sta)) {
1070 FitsOpenFile::printerror(sta);
1071 throw ParmError("FitsABTColRd1F::Init: Error getting column type\n");
1072 }
1073 if(DbgLevel>1) cout<<"...Init ColTypeCode="<<ColTypeCode[ColNum]<<endl;
1074 if(ColTypeCode[ColNum]==TSTRING || ColTypeCode[ColNum]==TCOMPLEX
1075 || ColTypeCode[ColNum]==TDBLCOMPLEX || ColTypeCode[ColNum]<0 )
1076 throw ParmError("FitsABTColRd1F::Init: Selected column is not Numerical\n");
1077 // Get column name, tunit, tform
1078 char labelcol[128];
1079 char tunit[64], tform[64], tdisp[64];
1080 LONGLONG repeat=0; double tscale=1., tzero=0.;
1081 int rc=0;
1082 if(HDUType()==BINARY_TBL) {
1083 fits_get_bcolparmsll(GetFitsPtr(),ColNum+1,labelcol,tunit,tform
1084 ,&repeat,&tscale,&tzero,NULL,tdisp,&sta);
1085 } else {
1086 long repeatlng;
1087 fits_get_acolparms(GetFitsPtr(),ColNum+1,labelcol,&repeatlng,tunit,tform
1088 ,&tscale,&tzero,NULL,tdisp,&sta);
1089 repeat = repeatlng;
1090 }
1091 if(rc) {
1092 FitsOpenFile::printerror(sta);
1093 throw RangeCheckError("FitsABTColRd1F::Init: Error getting the column caracteristics\n");
1094 }
1095 ColLabel.push_back(labelcol);
1096 ColTUnit.push_back(tunit);
1097 ColTForm.push_back(tform);
[4023]1098 ColRepeat.push_back(repeat);
[3660]1099 // fill the default buffer limits at init
1100 LineDeb.push_back(-1);
1101 LineFin.push_back(-1);
1102 // some debug print if requested
1103 if(DbgLevel)
1104 cout<<"FitsABTColRd1F::Init Num="<<ColNum<<" Label="<<ColLabel[ColNum]
[4023]1105 <<" TypeCode="<<ColTypeCode[ColNum]<<" TUnit="<<ColTUnit[ColNum]<<" TForm="<<ColTForm[ColNum]<<" Repeat="<<ColRepeat[ColNum]<<endl;
[3660]1106 if(DbgLevel>1)
[4023]1107 cout<<" (tscale="<<tscale<<",tzero="<<tzero<<",tdisp="<<tdisp<<")"<<endl;
[3660]1108 } // ***** ColNum
1109
1110 // Set the buffer for reading
1111 ChangeBuffer(blen,bsens);
1112
1113}
1114
1115/*! Destructor. */
1116FitsABTColRd1F::~FitsABTColRd1F()
1117{
1118 Delete();
1119}
1120
1121/*! Delete called by the destructor */
1122void FitsABTColRd1F::Delete(void)
1123{
1124 if(NBcol>0 && Buffer!=NULL) {
1125 for(int ColNum=0; ColNum<NBcol; ColNum++)
1126 if(Buffer[ColNum]!=NULL) delete [] Buffer[ColNum];
1127 delete [] Buffer; Buffer=NULL;
1128 }
1129 LineDeb.resize(0); LineFin.resize(0);
1130 //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
1131}
1132
1133//////////////////////////////////////////////////////////////
1134/*! Change the buffer caracteristiques (see creator) */
1135void FitsABTColRd1F::ChangeBuffer(long blen,long bsens)
1136{
1137 long oldnbuffer = NBuffer;
1138
1139 // Compute buffer caracteristics
1140 BuffLen = (blen<=0)? 1: blen;
1141 BuffSens = bsens;
1142 NBuffer = BuffLen;
1143 if(bsens==0 && NBuffer%2==0) NBuffer++;
1144
1145 // De-allocate if necessary
1146 if(Buffer!=NULL) {
1147 // On des-alloue si pas assez de place
1148 // ou si l'ancienne place est beaucoup trop grande (>25%)
1149 if(oldnbuffer<NBuffer || (oldnbuffer>NBuffer+long(0.25*NBuffer)) ) {
1150 for(int ColNum=0; ColNum<NBcol; ColNum++) if(Buffer[ColNum]!=NULL) delete [] Buffer[ColNum];
1151 if(Buffer!=NULL) {delete [] Buffer; Buffer=NULL;}
1152 }
1153 }
1154
1155 // Re-allocate
1156 if(Buffer==NULL) {
1157 Buffer = new double*[NBcol];
1158 for(int ColNum=0; ColNum<NBcol; ColNum++) Buffer[ColNum] = new double[NBuffer];
1159 }
1160
1161 // Tell program that nothing is into buffer
1162 for(int ColNum=0; ColNum<NBcol; ColNum++) LineDeb[ColNum] = LineFin[ColNum] = -1;
1163}
1164
1165//////////////////////////////////////////////////////////////
1166/*!
1167 Read a fitsheader key into double
1168 \param keyname : name of the key
1169 \return value into double
1170*/
1171double FitsABTColRd1F::ReadKey(const char *keyname)
1172{
1173 return FitsOpenFile::ReadKey(GetFitsPtr(),keyname);
1174}
1175
1176/*!
1177 Read a fitsheader key into long
1178 \param keyname : name of the key
1179 \return value into long
1180*/
1181long FitsABTColRd1F::ReadKeyL(const char *keyname)
1182{
1183 return FitsOpenFile::ReadKeyL(GetFitsPtr(),keyname);
1184}
1185
1186/*!
1187 Read a fitsheader key into long long
1188 \param keyname : name of the key
1189 \return value into long long
1190*/
1191LONGLONG FitsABTColRd1F::ReadKeyLL(const char *keyname)
1192{
1193 return FitsOpenFile::ReadKeyLL(GetFitsPtr(),keyname);
1194}
1195
1196/*!
1197 Read a fitsheader key into string
1198 \param keyname : name of the key
1199 \return value into string
1200*/
1201string FitsABTColRd1F::ReadKeyS(const char *keyname)
1202{
1203 return FitsOpenFile::ReadKeyS(GetFitsPtr(),keyname);
1204}
1205
1206/////////////////////////////////////////////////
1207int FitsABTColRd1F::GetColNum(const char *colname)
1208 // Get column number from column name
1209{
1210 if(strlen(colname)<1 || NBcol<1) return -1;
1211 string slab(colname);
1212 for(int ColNum=0;ColNum<NBcol;ColNum++)
1213 if(slab == ColLabel[ColNum]) return ColNum;
1214 return -1;
1215}
1216
1217/////////////////////////////////////////////////
1218/*!
[4023]1219 Read row "n" element "nfirstel" of column "ColNum" and return the value into a double
[3660]1220 \warning be carefull for the range: row = [0,NRows[
1221 \return value in double
1222 \param n : number of the row to be read.
1223 \verbatim
1224 usebuffer == true : use read optimisation with bufferisation
1225 == false : no optimisation with bufferisation
1226 just read one value
1227 \endverbatim
1228*/
[4023]1229double FitsABTColRd1F::Read(int ColNum,LONGLONG n,long nfirstel,bool usebuffer)
[3660]1230// Attention: n=nline [0,NBline[, cfistio veut [1,NBline]
1231// Attention: colnum [0,NBcol[ , cfistio veut [1,NBcol]
[4023]1232// Attention: nfirstel [0,ColRepeat[ , cfistio veut [1,ColRepeat]
[3660]1233{
1234 int sta=0;
1235 if(ColNum<0 || ColNum>=NBcol)
1236 throw RangeCheckError("FitsABTColRd1F::Read try to read outside column range\n");
1237 if(n<0 || n>=NBline)
1238 throw RangeCheckError("FitsABTColRd1F::Read try to read outside line range\n");
[4023]1239 if(nfirstel<0 || nfirstel>=ColRepeat[ColNum])
1240 throw RangeCheckError("FitsABTColRd1F::Read try to read outside element range: nfirstel>repeat\n");
[3660]1241
[4023]1242 // Pas de bufferisation (ou repeat=1), on lit betement
1243 if(NBuffer==1 || !usebuffer || ColRepeat[ColNum]!=1) {
[3660]1244 double val;
[4023]1245 fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,n+1,nfirstel+1,1,NULL,&val,NULL,&sta);
[3660]1246 if(sta) {
1247 FitsOpenFile::printerror(sta);
1248 throw NotAvailableOperation("FitsABTColRd1F::Read: Error Reading Fits file\n");
1249 }
1250 // On ne remplit Buffer[ColNum][0] que si on a choisit
1251 // un mode de lecture non bufferise (n==1) DES LE DEBUT.
1252 // Si on a initialement choisit un mode bufferise (avec n>1),
1253 // Buffer contient les valeurs chargees auparavent.
1254 // Il ne faut pas faire {Buffer[0]=val; LineDeb=LineFin=n;}
1255 // car on perd l'info de ces valeurs.
1256 if(NBuffer==1) {Buffer[ColNum][0]=val; LineDeb[ColNum]=LineFin[ColNum]=n;}
1257 return val;
1258 }
1259
[4023]1260 // Gestion avec bufferisation (uniquement dans le cas repeat=1)
[3660]1261 if(!Buffer)
1262 throw RangeCheckError("FitsABTColRd1F::Read: Buffer not allocated\n");
1263 if(n<LineDeb[ColNum] || n>LineFin[ColNum]) {
1264 LONGLONG row1,row2,nrow;
1265 if(BuffSens>0) { // Cas remplissage forward
1266 row1 = n+1;
1267 row2 = row1+NBuffer-1; if(row2>NBline) row2 = NBline;
1268 } else if(BuffSens<0) { // Cas remplissage backward
1269 row2 = n+1;
1270 row1 = row2-NBuffer+1; if(row1<1) row1 = 1;
1271 } else { // Cas remplissage centre
1272 row1 = n+1 - NBuffer/2; if(row1<1) row1 = 1;
1273 row2 = n+1 + NBuffer/2; if(row2>NBline) row2 = NBline;
1274 }
1275 nrow = row2 - row1 + 1;
1276 LineDeb[ColNum] = row1-1; LineFin[ColNum] = row2-1;
1277 //cout<<"DBG-FitsRead: row1="<<row1<<" row2="<<row2<<" nrow="<<nrow
1278 // <<" LineDeb,Fin="<<LineDeb[ColNum]<<","<<LineFin[ColNum]<<endl;
1279 fits_read_col(GetFitsPtr(),TDOUBLE,ColNum+1,row1,1,nrow,NULL,Buffer[ColNum],NULL,&sta);
1280 if(sta) {
1281 FitsOpenFile::printerror(sta);
1282 LineDeb[ColNum] = LineFin[ColNum] = -1;
1283 throw NotAvailableOperation("FitsABTColRd1F::Read: Error Reading Fits file\n");
1284 }
1285 }
1286
1287 long ibuf = n-LineDeb[ColNum];
1288 return Buffer[ColNum][ibuf];
1289}
1290
1291
1292/*! Print on stream os */
1293void FitsABTColRd1F::Print(ostream& os,int lp) const
1294{
1295 os<<"FitsABTColRd1F:Print ("<<BuffLen<<","<<BuffSens<<","<<NulVal<<")"
1296 <<" ncols="<<NBcol<<" nrows="<<NBline;
1297 os<<"\n... "<<FileName()<<"["<<HDU()<<"/"<<NHDU()<<" type="<<HDUType()<<"]"<<endl;
1298 if(lp>0 && NBcol>0) {
1299 for(int ColNum=0;ColNum<NBcol;ColNum++) {
1300 os<<"..Col="<<ColNum<<" Label="<<ColLabel[ColNum]<<" TypeCode="<<ColTypeCode[ColNum]
1301 <<" TUnit="<<ColTUnit[ColNum]<<" TForm="<<ColTForm[ColNum]
1302 <<endl;
1303 }
1304 }
1305}
1306
1307///////////////////////////////////////////////////////////////////
1308///////////////////////////////////////////////////////////////////
1309///////////////////////////////////////////////////////////////////
1310///////////////////////////////////////////////////////////////////
1311
1312/*!
1313 Constructor.
1314 Same as before but the column is identified by its column number
1315 \param colnum : number of the column to be read
1316 \warning col = [0,ncol[
1317*/
1318FitsABTColRead1F::FitsABTColRead1F(string fname,int ihdu,long blen,long bsens,int lp)
1319: FitsABTColRd1F(new FitsOpenFile(fname),ihdu,blen,bsens,lp)
1320{
1321}
1322
1323/*! Constructor. see below */
1324FitsABTColRead1F::FitsABTColRead1F(const char * cfname,int ihdu,long blen,long bsens,int lp)
1325: FitsABTColRd1F(new FitsOpenFile(cfname),ihdu,blen,bsens,lp)
1326{
1327}
1328
1329/*! Destructor. */
1330FitsABTColRead1F::~FitsABTColRead1F()
1331{
1332 Delete(); // ?? inutile ??
1333 // On detruit le FitsOpenFile, cad qu'on ferme (fits_file_close) le fichier FITS
1334 if(FitsOF!=NULL) delete FitsOF;
1335}
1336
1337///////////////////////////////////////////////////////////////////
1338///////////////////////////////////////////////////////////////////
1339///////////////////////////////////////////////////////////////////
1340///////////////////////////////////////////////////////////////////
1341
[2453]1342//! Class for reading a 2D image from a FITS file
1343
1344/*!
1345 \class SOPHYA::FitsImg2DRd
1346 \ingroup FitsIOServer
1347 Class for reading a 2D image from a FITS file
1348*/
1349
1350//////////////////////////////////////////////////////////////
1351/*!
1352 Constructor.
1353 \param fof : Pointer to the Class for opening the FITS file
[2456]1354 \param ihdu : number of the HDU where the image is.
[2453]1355 \param lp : debug level
1356 \verbatim
[2456]1357 - if ihdu<=0 first IMAGE hdu is taken
1358 - if ihdu>nhdu ihdu is set to nhdu
[2453]1359 \endverbatim
1360 \warning ihdu = [1,nhdu]
1361*/
1362FitsImg2DRd::FitsImg2DRd(FitsOpenFile* fof,int ihdu,int lp)
1363{
1364 Init(fof,ihdu,lp);
1365}
1366
1367/*! Constructor by copy */
1368FitsImg2DRd::FitsImg2DRd(FitsImg2DRd& fbt)
1369{
[2456]1370 Init(fbt.GetFitsOpenFile(),fbt.HDU(),fbt.DbgLevel);
[2453]1371}
1372
1373/*! Constructor by default */
1374FitsImg2DRd::FitsImg2DRd()
1375{
1376 Naxis[0] = Naxis[1] = 0;
1377 SetNulVal(); SetDebug(0);
[3114]1378 FitsOF = NULL;
[2453]1379}
1380
1381/*! Init routine called by the constructor */
1382void FitsImg2DRd::Init(FitsOpenFile* fof,int ihdu,int lp)
1383{
1384 // Initialisation des Parametres Generaux
1385 Naxis[0] = Naxis[1] = 0;
1386 SetNulVal(); SetDebug(lp);
[3114]1387 FitsOF = NULL;
[2453]1388
1389 // Caracteristiques du FitsOpenFile
1390 FitsOF = fof;
1391 if(FitsOF==NULL)
1392 throw NullPtrError("FitsImg2DRd::Init: FitsOpenFile pointer is NULL\n");
[2456]1393
[3114]1394 if(GetFitsPtr()==NULL)
[2453]1395 throw NullPtrError("FitsImg2DRd::Init: FitsPtr pointer is NULL\n");
1396
1397 int sta = 0;
[2456]1398 if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU();
[2453]1399
1400 // Get HDU 2D image
[2456]1401 // ATTENTION: ... cf blabla equivalent dans FitsABTColRd::Init()
1402 if(FitsOF->GetPosStatus()==false) {
1403 if(ihdu==0) { // find the first IMAGE_HDU
1404 FitsOF->MoveToFirst(IMAGE_HDU);
1405 } else {
1406 int rc = FitsOF->MoveToHDU(ihdu);
1407 if(rc!=ihdu)
[3114]1408 throw RangeCheckError("FitsImg2DRd::Init: Error moving to requested HDU\n");
[2453]1409 }
[2456]1410 } else { // Fits file has already been positionned
1411 if(ihdu>0 && ihdu!=HDU())
[3114]1412 throw RangeCheckError("FitsImg2DRd::Init: file already posit. at another HDU\n");
[2453]1413 }
[2456]1414
1415 // Check HDUType and set position status to TRUE
1416 if(HDUType()!=IMAGE_HDU)
[2453]1417 throw TypeMismatchExc("FitsImg2DRd::Init: HDU not IMAGE_HDU\n");
[2456]1418 FitsOF->SetPosStatus(true);
[2453]1419
1420 // Get NAXIS 1 et 2
1421 int nfound=0;
[3128]1422 // car fits_read_keys_lnglng n'est pas prototype dans longnam.h
1423 if(ffgknjj(GetFitsPtr(),"NAXIS",1,2,Naxis,&nfound,&sta)) {
[2453]1424 FitsOpenFile::printerror(sta);
1425 throw RangeCheckError("FitsImg2DRd::Init: Error reading NAXIS cards\n");
1426 }
1427 if(DbgLevel>1)
[2456]1428 cout<<"...Init(hdu="<<HDU()<<") NAXIS1="<<Naxis[0]<<" NAXIS2="
1429 <<Naxis[1]<<" (nfound="<<nfound<<")"<<endl;
[2453]1430 if(nfound!=2 || Naxis[0]<=0 || Naxis[1]<=0)
1431 throw NotAvailableOperation("FitsImg2DRd::Init: bad Naxis[0-1] value\n");
1432
1433}
1434
1435/*! Destructor. */
1436FitsImg2DRd::~FitsImg2DRd()
1437{
1438 //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
1439 Naxis[0] = Naxis[1] = 0;
1440}
1441
1442//////////////////////////////////////////////////////////////
1443/*!
1444 Read a fitsheader key into double
1445 \param keyname : name of the key
1446 \return value into double
1447*/
[3572]1448double FitsImg2DRd::ReadKey(const char *keyname)
[2453]1449{
[3114]1450 return FitsOpenFile::ReadKey(GetFitsPtr(),keyname);
[2453]1451}
1452
1453/*!
1454 Read a fitsheader key into long
1455 \param keyname : name of the key
1456 \return value into long
1457*/
[3572]1458long FitsImg2DRd::ReadKeyL(const char *keyname)
[2453]1459{
[3114]1460 return FitsOpenFile::ReadKeyL(GetFitsPtr(),keyname);
[2453]1461}
1462
1463/*!
[3128]1464 Read a fitsheader key into long long
1465 \param keyname : name of the key
1466 \return value into long long
1467*/
[3572]1468LONGLONG FitsImg2DRd::ReadKeyLL(const char *keyname)
[3128]1469{
1470 return FitsOpenFile::ReadKeyLL(GetFitsPtr(),keyname);
1471}
1472
1473/*!
[2453]1474 Read a fitsheader key into string
1475 \param keyname : name of the key
1476 \return value into string
1477*/
[3572]1478string FitsImg2DRd::ReadKeyS(const char *keyname)
[2453]1479{
[3114]1480 return FitsOpenFile::ReadKeyS(GetFitsPtr(),keyname);
[2453]1481}
1482
1483//////////////////////////////////////////////////////////////
1484/* REMARQUE:
1485 * Si une image FITS a NAXIS1=100 et NAXIS2=50
1486 * alors un tableau 2D juste assez grand pour contenir l'image
1487 * doit etre declare array[50][100] (et non pas array[100][50])
1488 * array[NAXIS2][NAXIS1]
1489 */
1490/*!
1491Read image into a TMatrix<uint_2>
1492\warning TMatrix data(Naxis2,Naxis1)
1493*/
[3128]1494LONGLONG FitsImg2DRd::Read(TMatrix<uint_2>& data)
[2453]1495{
1496 int sta=0;
1497 uint_2* arr = new uint_2[Naxis[0]];
1498 data.ReSize(Naxis[1],Naxis[0]);
1499
[3128]1500 for(LONGLONG j=0;j<Naxis[1];j++) {
1501 LONGLONG deb = j*Naxis[0]+1, nel = Naxis[0];
[3114]1502 fits_read_img(GetFitsPtr(),TUSHORT,deb,nel,&NulVal,arr,NULL,&sta);
[2453]1503 if(sta) {
1504 FitsOpenFile::printerror(sta); delete [] arr;
1505 throw
1506 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<uint_2>): Error Reading Fits file\n");
1507 }
[3128]1508 for(LONGLONG i=0;i<Naxis[0];i++) data(j,i) = arr[i];
[2453]1509 }
1510
1511 delete [] arr;
1512 return Naxis[0]*Naxis[1];
[3188]1513}
[2453]1514
1515/*! Read image into a TMatrix<int_4> */
[3128]1516LONGLONG FitsImg2DRd::Read(TMatrix<int_4>& data)
[2453]1517{
1518 int sta=0;
1519 int_4* arr = new int_4[Naxis[0]];
1520 data.ReSize(Naxis[1],Naxis[0]);
1521 int T = (sizeof(long)==4) ? TLONG: TINT;
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(),T,deb,nel,&NulVal,arr,NULL,&sta);
[2453]1526 if(sta) {
1527 FitsOpenFile::printerror(sta); delete [] arr;
1528 throw
1529 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<int_4>): 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<int_8> */
[3128]1539LONGLONG FitsImg2DRd::Read(TMatrix<int_8>& data)
[2453]1540{
1541 int sta=0;
1542 int_8* arr = new int_8[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(),TLONGLONG,deb,nel,&NulVal,arr,NULL,&sta);
[2453]1548 if(sta) {
1549 FitsOpenFile::printerror(sta); delete [] arr;
1550 throw
1551 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<int_8>): 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<float> */
[3128]1561LONGLONG FitsImg2DRd::Read(TMatrix<float>& data)
[2453]1562{
1563 int sta=0;
1564 float* arr = new float[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(),TFLOAT,deb,nel,&NulVal,arr,NULL,&sta);
[2453]1570 if(sta) {
1571 FitsOpenFile::printerror(sta); delete [] arr;
1572 throw
1573 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<float>): 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}
[2453]1581
1582/*! Read image into a TMatrix<double> */
[3128]1583LONGLONG FitsImg2DRd::Read(TMatrix<double>& data)
[2453]1584{
1585 int sta=0;
1586 double* arr = new double[Naxis[0]];
1587 data.ReSize(Naxis[1],Naxis[0]);
1588
[3128]1589 for(LONGLONG j=0;j<Naxis[1];j++) {
1590 LONGLONG deb = j*Naxis[0]+1, nel = Naxis[0];
[3114]1591 fits_read_img(GetFitsPtr(),TDOUBLE,deb,nel,&NulVal,arr,NULL,&sta);
[2453]1592 if(sta) {
1593 FitsOpenFile::printerror(sta); delete [] arr;
1594 throw
1595 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<double>): Error Reading Fits file\n");
1596 }
[3128]1597 for(LONGLONG i=0;i<Naxis[0];i++) data(j,i) = arr[i];
[2453]1598 }
1599
1600 delete [] arr;
1601 return Naxis[0]*Naxis[1];
[3188]1602}
[2791]1603
[3188]1604/*! Read image pixel numcol,numrow with numcol=[0,Naxis1[ and numrow=[0,Naxis2[ */
1605double FitsImg2DRd::Read(LONGLONG numcol, LONGLONG numrow)
1606{
1607 int sta=0;
1608 if(numcol<0 || numrow<0 || numcol>=Naxis[0] || numrow>=Naxis[1])
1609 throw
1610 NotAvailableOperation("FitsImg2DRd::Read(col,row): bad col/row number\n");
1611
1612 LONGLONG deb = numrow*Naxis[0] + numcol + 1;
1613 double val = 0.;
1614 fits_read_img(GetFitsPtr(),TDOUBLE,deb,1,&NulVal,&val,NULL,&sta);
1615
1616 if(sta) {
1617 FitsOpenFile::printerror(sta);
1618 throw
1619 NotAvailableOperation("FitsImg2DRd::Read(col,num): Error Reading Fits file\n");
1620 }
1621
1622 return val;
1623}
1624
[2791]1625///////////////////////////////////////////////////////////////////
1626///////////////////////////////////////////////////////////////////
1627///////////////////////////////////////////////////////////////////
1628///////////////////////////////////////////////////////////////////
1629
1630//! Class for reading a 2D image from a FITS file
1631
1632/*!
1633 \class SOPHYA::FitsImg2DRead
1634 \ingroup FitsIOServer
1635 Class for reading a 2D image from a FITS file
1636*/
1637
1638//////////////////////////////////////////////////////////////
1639/*!
1640 Constructor.
1641 \param fname : name of the FITS file
1642 \param ihdu : number of the HDU where the image is.
1643 \param lp : debug level
1644 \verbatim
1645 - if ihdu<=0 first IMAGE hdu is taken
1646 - if ihdu>nhdu ihdu is set to nhdu
1647 \endverbatim
1648 \warning ihdu = [1,nhdu]
1649*/
1650FitsImg2DRead::FitsImg2DRead(string fname,int ihdu,int lp)
1651: FitsImg2DRd(new FitsOpenFile(fname),ihdu,lp)
1652{
1653}
1654
1655/*! Constructor. see below */
1656FitsImg2DRead::FitsImg2DRead(const char * cfname,int ihdu,int lp)
1657: FitsImg2DRd(new FitsOpenFile(cfname),ihdu,lp)
1658{
1659}
1660
1661/*! Constructor by default */
1662FitsImg2DRead::FitsImg2DRead()
1663: FitsImg2DRd()
1664{
1665}
1666
1667/*! Constructor by copy */
1668FitsImg2DRead::FitsImg2DRead(FitsImg2DRead& fimg)
1669{
1670 // --- ATTENTION ---
1671 // FitsImg2DRead ferme le fichier FITS: il faut dupliquer le FitsOpenFile
1672 FitsOpenFile* fof = new FitsOpenFile(*fimg.GetFitsOpenFile());
1673 Init(fof,fimg.HDU(),fimg.DbgLevel);
1674}
1675
1676/*! Destructor. */
1677FitsImg2DRead::~FitsImg2DRead()
1678{
1679 // On detruit le FitsOpenFile, cad qu'on ferme (fits_file_close) le fichier FITS
1680 if(FitsOF!=NULL) delete FitsOF;
1681}
[3114]1682
1683
1684
1685///////////////////////////////////////////////////////////////////
1686///////////////////////////////////////////////////////////////////
1687///////////////////////////////////////////////////////////////////
1688///////////////////////////////////////////////////////////////////
1689
1690//! Class for reading a 3D image from a FITS file
1691
1692/*!
1693 \class SOPHYA::FitsImg3DRd
1694 \ingroup FitsIOServer
1695 Class for reading a 3D image from a FITS file
1696*/
1697
1698//////////////////////////////////////////////////////////////
1699/*!
1700 Constructor.
1701 \param fof : Pointer to the Class for opening the FITS file
1702 \param ihdu : number of the HDU where the 3D image is.
1703 \param lp : debug level
1704 \verbatim
1705 - if ihdu<=0 first IMAGE hdu is taken
1706 - if ihdu>nhdu ihdu is set to nhdu
1707 \endverbatim
1708 \warning ihdu = [1,nhdu]
1709*/
1710FitsImg3DRd::FitsImg3DRd(FitsOpenFile* fof,int ihdu,int lp)
1711{
1712 Init(fof,ihdu,lp);
1713}
1714
1715/*! Constructor by copy */
1716FitsImg3DRd::FitsImg3DRd(FitsImg3DRd& fbt)
1717{
1718 Init(fbt.GetFitsOpenFile(),fbt.HDU(),fbt.DbgLevel);
1719}
1720
1721/*! Constructor by default */
1722FitsImg3DRd::FitsImg3DRd()
1723{
1724 Naxis[0] = Naxis[1] = Naxis[2] = 0;
1725 SetNulVal(); SetDebug(0);
1726 FitsOF = NULL;
1727}
1728
1729/*! Init routine called by the constructor */
1730void FitsImg3DRd::Init(FitsOpenFile* fof,int ihdu,int lp)
1731{
1732 // Initialisation des Parametres Generaux
1733 Naxis[0] = Naxis[1] = Naxis[2] = 0;
1734 SetNulVal(); SetDebug(lp);
1735 FitsOF = NULL;
1736
1737 // Caracteristiques du FitsOpenFile
1738 FitsOF = fof;
1739 if(FitsOF==NULL)
1740 throw NullPtrError("FitsImg3DRd::Init: FitsOpenFile pointer is NULL\n");
1741
1742 if(GetFitsPtr()==NULL)
1743 throw NullPtrError("FitsImg3DRd::Init: FitsPtr pointer is NULL\n");
1744
1745 int sta = 0;
1746 if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU();
1747
1748 // Get HDU 3D image
1749 // ATTENTION: ... cf blabla equivalent dans FitsABTColRd::Init()
1750 if(FitsOF->GetPosStatus()==false) {
1751 if(ihdu==0) { // find the first IMAGE_HDU
1752 FitsOF->MoveToFirst(IMAGE_HDU);
1753 } else {
1754 int rc = FitsOF->MoveToHDU(ihdu);
1755 if(rc!=ihdu)
1756 throw RangeCheckError("FitsImg3DRd::Init: Error moving to requested HDU\n");
1757 }
1758 } else { // Fits file has already been positionned
1759 if(ihdu>0 && ihdu!=HDU())
1760 throw RangeCheckError("FitsImg3DRd::Init: file already posit. at another HDU\n");
1761 }
1762
1763 // Check HDUType and set position status to TRUE
1764 if(HDUType()!=IMAGE_HDU)
1765 throw TypeMismatchExc("FitsImg3DRd::Init: HDU not IMAGE_HDU\n");
1766 FitsOF->SetPosStatus(true);
1767
1768 // Get NAXIS 1, 2 et 3
1769 int nfound=0;
[3128]1770 // car fits_read_keys_lnglng n'est pas prototype dans longnam.h
1771 if(ffgknjj(GetFitsPtr(),"NAXIS",1,3,Naxis,&nfound,&sta)) {
[3114]1772 FitsOpenFile::printerror(sta);
1773 throw RangeCheckError("FitsImg3DRd::Init: Error reading NAXIS cards\n");
1774 }
1775 if(DbgLevel>1)
1776 cout<<"...Init(hdu="<<HDU()<<") NAXIS1="<<Naxis[0]<<" NAXIS2="
1777 <<Naxis[1]<<" NAXIS3="<<Naxis[2]<<" (nfound="<<nfound<<")"<<endl;
1778 if(nfound!=3 || Naxis[0]<=0 || Naxis[1]<=0 || Naxis[2]<=0)
1779 throw NotAvailableOperation("FitsImg3DRd::Init: bad Naxis[0-2] value\n");
1780
1781}
1782
1783/*! Destructor. */
1784FitsImg3DRd::~FitsImg3DRd()
1785{
1786 //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
1787 Naxis[0] = Naxis[1] = Naxis[2] = 0;
1788}
1789
1790//////////////////////////////////////////////////////////////
1791/*!
1792 Read a fitsheader key into double
1793 \param keyname : name of the key
1794 \return value into double
1795*/
[3572]1796double FitsImg3DRd::ReadKey(const char *keyname)
[3114]1797{
1798 return FitsOpenFile::ReadKey(GetFitsPtr(),keyname);
1799}
1800
1801/*!
1802 Read a fitsheader key into long
1803 \param keyname : name of the key
1804 \return value into long
1805*/
[3572]1806long FitsImg3DRd::ReadKeyL(const char *keyname)
[3114]1807{
1808 return FitsOpenFile::ReadKeyL(GetFitsPtr(),keyname);
1809}
1810
1811/*!
[3128]1812 Read a fitsheader key into long long
1813 \param keyname : name of the key
1814 \return value into long long
1815*/
[3572]1816LONGLONG FitsImg3DRd::ReadKeyLL(const char *keyname)
[3128]1817{
1818 return FitsOpenFile::ReadKeyLL(GetFitsPtr(),keyname);
1819}
1820
1821/*!
[3114]1822 Read a fitsheader key into string
1823 \param keyname : name of the key
1824 \return value into string
1825*/
[3572]1826string FitsImg3DRd::ReadKeyS(const char *keyname)
[3114]1827{
1828 return FitsOpenFile::ReadKeyS(GetFitsPtr(),keyname);
1829}
1830
1831//////////////////////////////////////////////////////////////
1832/* REMARQUE:
1833 * Dans TArray A(naxis1,naxis2,naxis3);
1834 * A(i,j,k) -> i varie le plus vite et k le moins vite
1835 */
1836/*!
1837Read 3D image into a TArray<uint_2>
1838*/
[3128]1839LONGLONG FitsImg3DRd::Read(TArray<uint_2>& data)
[3114]1840{
1841 int sta=0;
1842 uint_2* arr = new uint_2[Naxis[0]];
1843 sa_size_t ndim[3] = {Naxis[0],Naxis[1],Naxis[2]}; data.ReSize(3,ndim);
1844
[3128]1845 for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
1846 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
[3114]1847 fits_read_img(GetFitsPtr(),TUSHORT,deb,nel,&NulVal,arr,NULL,&sta);
1848 if(sta) {
1849 FitsOpenFile::printerror(sta); delete [] arr;
1850 throw
1851 NotAvailableOperation("FitsImg3DRd::Read(TArray<uint_2>): Error Reading Fits file\n");
1852 }
[3128]1853 for(LONGLONG i=0;i<Naxis[0];i++) data(i,j,k) = arr[i];
[3114]1854 }
1855
1856 delete [] arr;
1857 return Naxis[0]*Naxis[1]*Naxis[2];
[3188]1858}
[3114]1859
1860/*! Read 3D image into a TArray<int_4> */
[3128]1861LONGLONG FitsImg3DRd::Read(TArray<int_4>& data)
[3114]1862{
1863 int sta=0;
1864 int_4* arr = new int_4[Naxis[0]];
1865 sa_size_t ndim[3] = {Naxis[0],Naxis[1],Naxis[2]}; data.ReSize(3,ndim);
1866 int T = (sizeof(long)==4) ? TLONG: TINT;
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(),T,deb,nel,&NulVal,arr,NULL,&sta);
1871 if(sta) {
1872 FitsOpenFile::printerror(sta); delete [] arr;
1873 throw
1874 NotAvailableOperation("FitsImg3DRd::Read(TArray<int_4>): 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<int_8> */
[3128]1884LONGLONG FitsImg3DRd::Read(TArray<int_8>& data)
[3114]1885{
1886 int sta=0;
1887 int_8* arr = new int_8[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(),TLONGLONG,deb,nel,&NulVal,arr,NULL,&sta);
1893 if(sta) {
1894 FitsOpenFile::printerror(sta); delete [] arr;
1895 throw
1896 NotAvailableOperation("FitsImg3DRd::Read(TArray<int_8>): 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<float> */
[3128]1906LONGLONG FitsImg3DRd::Read(TArray<float>& data)
[3114]1907{
1908 int sta=0;
1909 float* arr = new float[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(),TFLOAT,deb,nel,&NulVal,arr,NULL,&sta);
1915 if(sta) {
1916 FitsOpenFile::printerror(sta); delete [] arr;
1917 throw
1918 NotAvailableOperation("FitsImg3DRd::Read(TArray<float>): 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
1927/*! Read 3D image into a TArray<double> */
[3128]1928LONGLONG FitsImg3DRd::Read(TArray<double>& data)
[3114]1929{
1930 int sta=0;
1931 double* arr = new double[Naxis[0]];
1932 sa_size_t ndim[3] = {Naxis[0],Naxis[1],Naxis[2]}; data.ReSize(3,ndim);
1933
[3128]1934 for(LONGLONG k=0;k<Naxis[2];k++) for(LONGLONG j=0;j<Naxis[1];j++) {
1935 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
[3114]1936 fits_read_img(GetFitsPtr(),TDOUBLE,deb,nel,&NulVal,arr,NULL,&sta);
1937 if(sta) {
1938 FitsOpenFile::printerror(sta); delete [] arr;
1939 throw
1940 NotAvailableOperation("FitsImg3DRd::Read(TArray<double>): Error Reading Fits file\n");
1941 }
[3128]1942 for(LONGLONG i=0;i<Naxis[0];i++) data(i,j,k) = arr[i];
[3114]1943 }
1944
1945 delete [] arr;
1946 return Naxis[0]*Naxis[1]*Naxis[2];
[3188]1947}
[3114]1948
[3772]1949/*! Read 3D image into a TVector<int_4> */
1950LONGLONG FitsImg3DRd::Read(LONGLONG j, LONGLONG k, TVector<int_4>& data)
1951{
1952 if(j<0 || k<0 || j>=Naxis[1] || k>=Naxis[2])
1953 throw NotAvailableOperation("FitsImg3DRd::Read(TVector<int_4>): bad j/k number\n");
1954 int sta=0;
1955 if(data.Size() != Naxis[0]) data.ReSize(Naxis[0]);
1956 int T = (sizeof(long)==4) ? TLONG: TINT;
1957 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
1958 fits_read_img(GetFitsPtr(),T,deb,nel,&NulVal,data.Data(),NULL,&sta);
1959 if(sta) {
1960 FitsOpenFile::printerror(sta);
1961 throw
1962 NotAvailableOperation("FitsImg3DRd::Read(TVector<int_4>): Error Reading Fits file\n");
1963 }
1964 return Naxis[0];
1965}
1966
1967/*! Read 3D image into a TVector<float> */
1968LONGLONG FitsImg3DRd::Read(LONGLONG j, LONGLONG k, TVector<float>& data)
1969{
1970 if(j<0 || k<0 || j>=Naxis[1] || k>=Naxis[2])
1971 throw NotAvailableOperation("FitsImg3DRd::Read(TVector<float>): bad j/k number\n");
1972 int sta=0;
1973 if(data.Size() != Naxis[0]) data.ReSize(Naxis[0]);
1974 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
1975 fits_read_img(GetFitsPtr(),TFLOAT,deb,nel,&NulVal,data.Data(),NULL,&sta);
1976 if(sta) {
1977 FitsOpenFile::printerror(sta);
1978 throw
1979 NotAvailableOperation("FitsImg3DRd::Read(TVector<float>): Error Reading Fits file\n");
1980 }
1981 return Naxis[0];
1982}
1983
1984/*! Read 3D image into a TVector<double> */
1985LONGLONG FitsImg3DRd::Read(LONGLONG j, LONGLONG k, TVector<double>& data)
1986{
1987 if(j<0 || k<0 || j>=Naxis[1] || k>=Naxis[2])
1988 throw NotAvailableOperation("FitsImg3DRd::Read(TVector<double>): bad j/k number\n");
1989 int sta=0;
1990 if(data.Size() != Naxis[0]) data.ReSize(Naxis[0]);
1991 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+1, nel = Naxis[0];
1992 fits_read_img(GetFitsPtr(),TDOUBLE,deb,nel,&NulVal,data.Data(),NULL,&sta);
1993 if(sta) {
1994 FitsOpenFile::printerror(sta);
1995 throw
1996 NotAvailableOperation("FitsImg3DRd::Read(TVector<double>): Error Reading Fits file\n");
1997 }
1998 return Naxis[0];
1999}
2000
[3188]2001/*! Read 3D image pixel i,j,k with i=[0,Naxis1[ , j=[0,Naxis2[ , k=[0,Naxis3[ */
2002double FitsImg3DRd::Read(LONGLONG i, LONGLONG j, LONGLONG k)
2003{
2004 int sta=0;
2005 if(i<0 || j<0 || k<0 || i>=Naxis[0] || j>=Naxis[1] || k>=Naxis[2])
2006 throw
2007 NotAvailableOperation("FitsImg3DRd::Read(i,j,k): bad i/j/k number\n");
2008
2009 LONGLONG deb = Naxis[0]*(j+Naxis[1]*k)+i+1;
2010 double val = 0.;
2011 fits_read_img(GetFitsPtr(),TDOUBLE,deb,1,&NulVal,&val,NULL,&sta);
2012
2013 if(sta) {
2014 FitsOpenFile::printerror(sta);
2015 throw
2016 NotAvailableOperation("FitsImg3DRd::Read(i,j,k): Error Reading Fits file\n");
2017 }
2018
2019 return val;
2020}
2021
[3114]2022///////////////////////////////////////////////////////////////////
2023///////////////////////////////////////////////////////////////////
2024///////////////////////////////////////////////////////////////////
2025///////////////////////////////////////////////////////////////////
2026
2027//! Class for reading a 3D image from a FITS file
2028
2029/*!
2030 \class SOPHYA::FitsImg3DRead
2031 \ingroup FitsIOServer
2032 Class for reading a 3D image from a FITS file
2033*/
2034
2035//////////////////////////////////////////////////////////////
2036/*!
2037 Constructor.
2038 \param fname : name of the FITS file
2039 \param ihdu : number of the HDU where the 3D image is.
2040 \param lp : debug level
2041 \verbatim
2042 - if ihdu<=0 first IMAGE hdu is taken
2043 - if ihdu>nhdu ihdu is set to nhdu
2044 \endverbatim
2045 \warning ihdu = [1,nhdu]
2046*/
2047FitsImg3DRead::FitsImg3DRead(string fname,int ihdu,int lp)
2048: FitsImg3DRd(new FitsOpenFile(fname),ihdu,lp)
2049{
2050}
2051
2052/*! Constructor. see below */
2053FitsImg3DRead::FitsImg3DRead(const char * cfname,int ihdu,int lp)
2054: FitsImg3DRd(new FitsOpenFile(cfname),ihdu,lp)
2055{
2056}
2057
2058/*! Constructor by default */
2059FitsImg3DRead::FitsImg3DRead()
2060: FitsImg3DRd()
2061{
2062}
2063
2064/*! Constructor by copy */
2065FitsImg3DRead::FitsImg3DRead(FitsImg3DRead& fimg)
2066{
2067 // --- ATTENTION ---
2068 // FitsImg3DRead ferme le fichier FITS: il faut dupliquer le FitsOpenFile
2069 FitsOpenFile* fof = new FitsOpenFile(*fimg.GetFitsOpenFile());
2070 Init(fof,fimg.HDU(),fimg.DbgLevel);
2071}
2072
2073/*! Destructor. */
2074FitsImg3DRead::~FitsImg3DRead()
2075{
2076 // On detruit le FitsOpenFile, cad qu'on ferme (fits_file_close) le fichier FITS
2077 if(FitsOF!=NULL) delete FitsOF;
2078}
Note: See TracBrowser for help on using the repository browser.