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

Last change on this file since 2456 was 2456, checked in by cmv, 22 years ago

amelioration architecture classe cmv 18/11/03

File size: 33.8 KB
Line 
1/* Lecteur de colonne de table Fits (binaire ou ASCII) avec buffer */
2#include "machdefs.h"
3#include <stdlib.h>
4#include <stdio.h>
5#include "pexceptions.h"
6#include "fabtcolread.h"
7
8///////////////////////////////////////////////////////////////////
9///////////////////////////////////////////////////////////////////
10///////////////////////////////////////////////////////////////////
11///////////////////////////////////////////////////////////////////
12
13//! Class for opening a FITS file for reading
14
15/*!
16 \class SOPHYA::FitsOpenFile
17 \ingroup FitsIOServer
18 Class for opening a FITS file for reading
19*/
20
21/*!
22 Constructor.
23 \param fname : FITS file name to be opened for reading
24*/
25FitsOpenFile::FitsOpenFile(string fname)
26{
27 Init(fname.c_str());
28}
29
30/*!
31 Constructor.
32 \param cfname : FITS file name to be opened for reading
33*/
34FitsOpenFile::FitsOpenFile(const char *cfname)
35{
36 Init(cfname);
37}
38
39/*!
40 Constructor by default.
41*/
42FitsOpenFile::FitsOpenFile()
43{
44 FitsFN = "";
45 NHdu = IHdu = HduType = 0;
46 HasBeenPos = false;
47 FitsPtr = NULL;
48}
49
50/*!
51 Constructor by copy.
52*/
53FitsOpenFile::FitsOpenFile(FitsOpenFile& fof)
54{
55 Init(fof.FileName().c_str());
56}
57
58/*!
59 Destructor.
60*/
61FitsOpenFile::~FitsOpenFile()
62{
63 Delete();
64 FitsFN = "";
65 NHdu = IHdu = HduType = 0;
66 HasBeenPos = false;
67}
68
69/*!
70 Delete routine called by the destructor.
71*/
72void FitsOpenFile::Delete(void)
73{
74 if(FitsPtr != NULL) {
75 int sta = 0;
76 if(fits_close_file(FitsPtr,&sta)) printerror(sta);
77 FitsPtr = NULL;
78 }
79}
80
81/*! Init routine called by the constructor */
82void FitsOpenFile::Init(const char* fname)
83{
84 // Parametres Generaux
85 FitsFN = fname;
86 NHdu = IHdu = HduType = 0;
87 HasBeenPos = false;
88 FitsPtr = NULL;
89
90 // Ouverture du fichier
91 if(FitsFN.size() <= 0 )
92 throw ParmError("FitsOpenFile::Init: Fits file name error\n");
93
94 int sta = 0;
95 if(fits_open_file(&FitsPtr,FitsFN.c_str(),READONLY,&sta)) {
96 printerror(sta);
97 FitsPtr = NULL;
98 throw NullPtrError("FitsOpenFile::Init: Error opening Fits file\n");
99 }
100
101 // Get number of hdu
102 if(fits_get_num_hdus(FitsPtr,&NHdu,&sta)) {
103 printerror(sta);
104 NHdu = 0;
105 Delete();
106 throw NotAvailableOperation("FitsOpenFile::Init: Error getting NHdu\n");
107 }
108 if(NHdu<=0) {
109 Delete();
110 throw SzMismatchError("FitsOpenFile::Init: Bad NHdu\n");
111 }
112
113 MoveToHDU(1);
114}
115
116/*! Move to an HDU
117\param ihdu: hdu number to move
118\warning ihdu = [1,nhdu]
119\return 0 if positionning failed, ihdu if success
120*/
121int FitsOpenFile::MoveToHDU(int ihdu)
122{
123 if(FitsPtr==NULL)
124 throw NullPtrError("FitsOpenFile::MoveToHDU: no fits file open FitsPtr==NULL\n");
125 int ihdusave = IHdu;
126 if(ihdu<=0) ihdu=1; if(ihdu>NHdu) ihdu=NHdu;
127 int sta=0;
128 if(fits_movabs_hdu(FitsPtr,ihdu,&HduType,&sta)) {
129 printerror(sta);
130 // On se repositionne ou on etait
131 fits_movabs_hdu(FitsPtr,ihdusave,&HduType,&sta);
132 IHdu = ihdusave;
133 } else IHdu = ihdu;
134 return IHdu;
135}
136
137/*! Move to the first HDU of a certain type
138\param hdutype: type of the hdu
139\param hdudeb: start at that hdu
140\return the type of HDU the file is positionned
141*/
142int FitsOpenFile::MoveToFirst(int hdutype,int ihdudeb)
143{
144 if(ihdudeb<=0) ihdudeb=1; if(ihdudeb>NHdu) ihdudeb=NHdu;
145 int ihdusave = IHdu;
146 for(int ihdu=ihdudeb;ihdu<=NHdu;ihdu++) {
147 MoveToHDU(ihdu);
148 if(HduType==hdutype) break;
149 }
150 // Si echec, on se repositionne ou on etait
151 if(HduType!=hdutype) MoveToHDU(ihdusave);
152 return HduType;
153}
154
155/*! Move to the last HDU of a certain type
156\param hdutype: type of the hdu
157\param hdudeb: stop at that hdu
158\return the type of HDU the file is positionned
159*/
160int FitsOpenFile::MoveToLast(int hdutype,int ihdudeb)
161{
162 if(ihdudeb<=0) ihdudeb=1; if(ihdudeb>NHdu) ihdudeb=NHdu;
163 int ihdusave = IHdu;
164 for(int ihdu=NHdu;ihdu>=ihdudeb;ihdu--) {
165 MoveToHDU(ihdu);
166 if(HduType==hdutype) break;
167 }
168 // Si echec, on se repositionne ou on etait
169 if(HduType!=hdutype) MoveToHDU(ihdusave);
170 return HduType;
171}
172
173/*! Print */
174void FitsOpenFile::Print(void)
175{
176 cout<<"FitsOpenFile::Print: "<<FitsFN
177 <<" hdu="<<IHdu<<"/"<<NHdu<<" type="<<HduType
178 <<" hasbeenpos="<<HasBeenPos<<endl;
179}
180
181//////////////////////////////////////////////////////////////
182//// Methodes statiques
183//////////////////////////////////////////////////////////////
184/*!
185 Read a fitsheader key into double
186 \param fitsptr : cfitio pointer to Fits file
187 \param keyname : name of the key
188 \return value into double
189*/
190double FitsOpenFile::ReadKey(fitsfile *fitsptr,char *keyname)
191{
192 if(keyname==NULL || fitsptr==NULL) return 0.;
193 int sta=0; double val=0.;
194 if(fits_read_key(fitsptr,TDOUBLE,keyname,&val,NULL,&sta))
195 printerror(sta);
196 return val;
197}
198
199/*!
200 Read a fitsheader key into long
201 \param fitsptr : cfitio pointer to Fits file
202 \param keyname : name of the key
203 \return value into long
204*/
205long FitsOpenFile::ReadKeyL(fitsfile *fitsptr,char *keyname)
206{
207 if(keyname==NULL || fitsptr==NULL) return 0;
208 int sta=0; long val=0;
209 if(fits_read_key(fitsptr,TLONG,keyname,&val,NULL,&sta))
210 printerror(sta);
211 return val;
212}
213
214/*!
215 Read a fitsheader key into string
216 \param fitsptr : cfitio pointer to Fits file
217 \param keyname : name of the key
218 \return value into string
219*/
220string FitsOpenFile::ReadKeyS(fitsfile *fitsptr,char *keyname)
221{
222 if(keyname==NULL || fitsptr==NULL) return (string)"";
223 int sta=0; char val[FLEN_VALUE];
224 if(fits_read_key(fitsptr,TSTRING,keyname,val,NULL,&sta))
225 printerror(sta);
226 string sval = val;
227 return sval;
228}
229
230/*!
231 CFitsIO error printing routine
232 \param sta : cfitio error return code
233*/
234 void FitsOpenFile::printerror(int sta)
235 {
236 int stat = sta;
237 fits_report_error(stdout,stat);
238 fflush(stdout);
239 return;
240 }
241
242///////////////////////////////////////////////////////////////////
243///////////////////////////////////////////////////////////////////
244///////////////////////////////////////////////////////////////////
245///////////////////////////////////////////////////////////////////
246
247///////////////////////////////////////////////////////////////////
248//! Class for reading a column in a FITS ASCII or BINARY table
249
250/*!
251 \class SOPHYA::FitsABTColRd
252 \ingroup FitsIOServer
253 Class for reading a column in a FITS ASCII or BINARY table
254 \verbatim
255 -- Exemple:
256 // Open the fits file with FitsOpenFile
257 FitsOpenFile fof = new FitsOpenFile("myfits.fits");
258 // Select the column to be read
259 FitsABTColRd fbt(fof,"BoloMuv_28",0,1000,1,3);
260 FitsABTColRd fbt2(fof,"BoloMuv_29",0,1000,1,3);
261 fbt.SetDebug(3);
262 fbt.Print(3);
263 // Read element by element
264 for(long i=0;i<fbt.GetNbLine();i++) {
265 double x = fbt.Read(i);
266 double y = fbt2.Read(i);
267 if(i%lpmod==0) cout<<i<<": "<<x<<", "<<y<<endl;
268 }
269 // Read into a vector
270 TVector<double> data;
271 long n = fbt.Read(32,50,data);
272 cout<<"Number of values read: "<<n<<endl;
273 data.ReSize(100);
274 n = fbt.Read(10,-1,data);
275 cout<<"Number of values read: "<<n<<endl;
276 TVector<double> data2;
277 fbt2.Read(32,50,data);
278 // Close the fits file
279 delete fof;
280 \endverbatim
281*/
282
283//////////////////////////////////////////////////////////////
284/*!
285 Constructor.
286 \param fof : Pointer to the Class for opening the FITS file
287 \param collabel : label of the column to be read
288 \param ihdu : number of the HDU where the column is.
289 \param blen : read buffer length
290 \param bsens : buffer reading direction
291 \param lp : debug level
292 \verbatim
293 - if ihdu<=0 first BINARY or ASCII table is taken
294 - if ihdu>nhdu ihdu is set to nhdu
295 - bsens>0 read forward
296 bsens<0 read backward
297 bsens==0 read centered
298 \endverbatim
299 \warning ihdu = [1,nhdu]
300*/
301FitsABTColRd::FitsABTColRd(FitsOpenFile* fof,string collabel
302 ,int ihdu,long blen,long bsens,int lp)
303{
304 Init(fof,collabel.c_str(),-1,ihdu,blen,bsens,lp);
305}
306
307/*!
308 Constructor.
309 Same as before but the column is identified by its column number
310 \param colnum : number of the column to be read
311 \warning col = [0,ncol[
312*/
313FitsABTColRd::FitsABTColRd(FitsOpenFile* fof,int colnum
314 ,int ihdu,long blen,long bsens,int lp)
315{
316 Init(fof,"",colnum,ihdu,blen,bsens,lp);
317}
318
319/*! Constructor by copy */
320FitsABTColRd::FitsABTColRd(FitsABTColRd& fbt)
321{
322 Init(fbt.GetFitsOpenFile(),fbt.GetColLabel().c_str()
323 ,fbt.GetColNum(),fbt.HDU()
324 ,fbt.GetBLen(),fbt.GetBSens(),fbt.DbgLevel);
325}
326
327/*! Constructor by default */
328FitsABTColRd::FitsABTColRd()
329{
330 ColLabel = ""; ColTUnit = ""; ColTForm = "";
331 ColNum = -1; ColTypeCode = 0;
332 NBcol = 0; NBline = 0;
333 SetNulVal(); SetDebug(0);
334 NFitsRead = 0;
335 FitsOF = NULL; FitsPtr = NULL;
336 LineDeb = LineFin = -1;
337 Buffer = NULL;
338}
339
340/*! Init routine called by the constructor */
341void FitsABTColRd::Init(FitsOpenFile* fof,const char* collabel,int colnum
342 ,int ihdu,long blen,long bsens,int lp)
343{
344 // Initialisation des Parametres Generaux
345 ColLabel=collabel; ColTUnit=""; ColTForm=""; ColNum=colnum; ColTypeCode=0;
346 NBcol = 0; NBline = 0;
347 SetNulVal(); SetDebug(lp);
348 NFitsRead = 0;
349 FitsOF = NULL; FitsPtr = NULL;
350 LineDeb = LineFin = -1;
351 Buffer = NULL;
352
353 // Caracteristiques du FitsOpenFile
354 FitsOF = fof;
355 if(FitsOF==NULL)
356 throw NullPtrError("FitsABTColRd::Init: FitsOpenFile pointer is NULL\n");
357
358 FitsPtr = FitsOF->GetFitsPtr();
359 if(FitsPtr==NULL)
360 throw NullPtrError("FitsABTColRd::Init: FitsPtr pointer is NULL\n");
361
362 int sta = 0;
363 if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU();
364
365 // Get HDU for bin/ascii table
366 // ATTENTION: le fichier est ouvert mais non positionne sur un HDU,
367 // une classe utilisant ce fichier doit le positionner sur un HDU.
368 // Par contre, si une autre classe utilise ce meme FitsOpenFile,
369 // elle ne peut le positionner que sur ce meme HDU !
370 if(FitsOF->GetPosStatus()==false) {
371 if(ihdu==0) { // find the first BINARY then the first ASCII
372 int rc = FitsOF->MoveToFirst(BINARY_TBL);
373 if(rc!=BINARY_TBL) FitsOF->MoveToFirst(ASCII_TBL);
374 } else {
375 int rc = FitsOF->MoveToHDU(ihdu);
376 if(rc!=ihdu)
377 throw RangeCheckError("FitsABTColRd::Init: Error moving to requested HDU\n");
378 }
379 } else { // Fits file has already been positionned
380 if(ihdu>0 && ihdu!=HDU())
381 throw RangeCheckError("FitsABTColRd::Init: file already posit. at another HDU\n");
382 }
383
384 // Check HDUType and set position status to TRUE
385 if(HDUType()!=BINARY_TBL && HDUType()!=ASCII_TBL)
386 throw TypeMismatchExc("FitsABTColRd::Init: HDU not ASCII/BINARY table\n");
387 if(DbgLevel>1) cout<<"...Init ihdu="<<ihdu<<" HduType="<<HDUType()<<endl;
388 FitsOF->SetPosStatus(true);
389
390 // Get number of columns
391 if(fits_get_num_cols(FitsPtr,&NBcol,&sta)) {
392 FitsOpenFile::printerror(sta);
393 throw NotAvailableOperation("FitsABTColRd::Init: Error getting number of columns\n");
394 }
395 if(DbgLevel>1) cout<<"...Init NBcol="<<NBcol<<endl;
396 if(NBcol<1)
397 throw RangeCheckError("FitsABTColRd::Init: Bad number of colums\n");
398
399 // Get number of rows
400 if(fits_get_num_rows(FitsPtr,&NBline,&sta)) {
401 FitsOpenFile::printerror(sta);
402 throw NotAvailableOperation("FitsABTColRd::Init: Error getting number of rows\n");
403 }
404 if(DbgLevel>1) cout<<"...Init NBline="<<NBline<<endl;
405 if(NBline<1)
406 throw RangeCheckError("FitsABTColRd::Init: Bad number of rows\n");
407
408 // Get column number
409 char labelcol[128];
410 if(ColLabel.size() > 0) {
411 strcpy(labelcol,ColLabel.c_str());
412 if(fits_get_colnum(FitsPtr,CASESEN,labelcol,&ColNum,&sta)) {
413 FitsOpenFile::printerror(sta);
414 throw NotAvailableOperation("FitsABTColRd::Init: Error getting column name\n");
415 }
416 ColNum--; // Convention [0,ncol[
417 }
418 if(DbgLevel>1) cout<<"...Init ColNum="<<ColNum<<endl;
419 if(ColNum<0 || ColNum>=NBcol)
420 throw RangeCheckError("FitsABTColRd::Init: Bad column number\n");
421
422 // Get column type
423 if(fits_get_coltype(FitsPtr,ColNum+1,&ColTypeCode,NULL,NULL,&sta)) {
424 FitsOpenFile::printerror(sta);
425 throw ParmError("FitsABTColRd::Init: Error getting column type\n");
426 }
427 if(DbgLevel>1) cout<<"...Init ColTypeCode="<<ColTypeCode<<endl;
428 if(ColTypeCode==TSTRING || ColTypeCode==TCOMPLEX || ColTypeCode==TDBLCOMPLEX
429 || ColTypeCode<0 )
430 throw ParmError("FitsABTColRd::Init: Selected column is not Numerical\n");
431
432 // Get column name back, tunit, tform
433 char tunit[64], tform[64], tdisp[64];
434 long repeat=0; double tscale=1., tzero=0.;
435 int rc=0;
436 if(HDUType()==BINARY_TBL) {
437 fits_get_bcolparms(FitsPtr,ColNum+1,labelcol,tunit,tform
438 ,&repeat,&tscale,&tzero,NULL,tdisp,&sta);
439 } else {
440 fits_get_acolparms(FitsPtr,ColNum+1,labelcol,&repeat,tunit,tform
441 ,&tscale,&tzero,NULL,tdisp,&sta);
442 }
443 if(rc) {
444 FitsOpenFile::printerror(sta);
445 throw RangeCheckError("FitsABTColRd::Init: Error getting the column caracteristics\n");
446 }
447 ColLabel = labelcol;
448 ColTUnit = tunit;
449 ColTForm = tform;
450
451 // Set the buffer for reading
452 ChangeBuffer(blen,bsens);
453
454 if(DbgLevel)
455 cout<<"FitsABTColRd::Init Num="<<ColNum<<" Label="<<ColLabel
456 <<" TypeCode="<<ColTypeCode<<" TUnit="<<ColTUnit<<" TForm="<<ColTForm<<endl;
457 if(DbgLevel>1)
458 cout<<" (repeat="<<repeat<<",tscale="<<tscale<<",tzero="<<tzero
459 <<",tdisp="<<tdisp<<")"<<endl;
460
461}
462
463/*! Destructor. */
464FitsABTColRd::~FitsABTColRd()
465{
466 Delete();
467}
468
469/*! Delete called by the destructor */
470void FitsABTColRd::Delete(void)
471{
472 if(Buffer!=NULL) {delete [] Buffer; Buffer=NULL;}
473 LineDeb = LineFin = -1;
474 //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
475}
476
477//////////////////////////////////////////////////////////////
478/*! Change the buffer caracteristiques (see creator) */
479void FitsABTColRd::ChangeBuffer(long blen,long bsens)
480{
481 long oldnbuffer = NBuffer;
482
483 // Compute buffer caracteristics
484 BuffLen = (blen<=0)? 1: blen;
485 BuffSens = bsens;
486 NBuffer = BuffLen;
487 if(bsens==0 && NBuffer%2==0) NBuffer++;
488
489 // De-allocate if necessary
490 if(Buffer!=NULL) {
491 // On des-alloue si pas assez de place
492 // ou si l'ancienne place est beaucoup trop grande (>25%)
493 if(oldnbuffer<NBuffer || (oldnbuffer>NBuffer+long(0.25*NBuffer)) )
494 {delete [] Buffer; Buffer=NULL;}
495 }
496
497 // Re-allocate
498 if(Buffer==NULL) Buffer = new double[NBuffer];
499
500 // Tell program that nothing is into buffer
501 LineDeb = LineFin = -1;
502}
503
504//////////////////////////////////////////////////////////////
505/*!
506 Read a fitsheader key into double
507 \param keyname : name of the key
508 \return value into double
509*/
510double FitsABTColRd::ReadKey(char *keyname)
511{
512 return FitsOpenFile::ReadKey(FitsPtr,keyname);
513}
514
515/*!
516 Read a fitsheader key into long
517 \param keyname : name of the key
518 \return value into long
519*/
520long FitsABTColRd::ReadKeyL(char *keyname)
521{
522 return FitsOpenFile::ReadKeyL(FitsPtr,keyname);
523}
524
525/*!
526 Read a fitsheader key into string
527 \param keyname : name of the key
528 \return value into string
529*/
530string FitsABTColRd::ReadKeyS(char *keyname)
531{
532 return FitsOpenFile::ReadKeyS(FitsPtr,keyname);
533}
534
535/////////////////////////////////////////////////
536/*!
537 Read row "n" and return the value into a double
538 \warning be carefull for the range: row = [0,NRows[
539 \return value in double
540 \param n : number of the row to be read.
541 \verbatim
542 usebuffer == true : use read optimisation with bufferisation
543 == false : no optimisation with bufferisation
544 just read one value
545 \endverbatim
546*/
547double FitsABTColRd::Read(long n,bool usebuffer)
548// Attention: n=nline [0,NBline[, cfistio veut [1,NBline]
549// Attention: colnum [0,NBcol[ , cfistio veut [1,NBcol]
550{
551 int sta=0;
552 if(n<0 || n>=NBline)
553 throw RangeCheckError("FitsABTColRd::Read try to read outside line range\n");
554
555 // Pas de bufferisation, on lit betement
556 if(NBuffer==1 || !usebuffer) {
557 NFitsRead++;
558 double val;
559 fits_read_col(FitsPtr,TDOUBLE,ColNum+1,n+1,1,1,NULL,&val,NULL,&sta);
560 if(sta) {
561 FitsOpenFile::printerror(sta);
562 throw NotAvailableOperation("FitsABTColRd::Read: Error Reading Fits file\n");
563 }
564 // On ne remplit Buffer[0] que si on a choisit
565 // un mode de lecture non bufferise (n==1) DES LE DEBUT.
566 // Si on a initialement choisit un mode bufferise (avec n>1),
567 // Buffer contient les valeurs chargees auparavent.
568 // Il ne faut pas faire {Buffer[0]=val; LineDeb=LineFin=n;}
569 // car on perd l'info de ces valeurs.
570 if(NBuffer==1) {Buffer[0]=val; LineDeb=LineFin=n;}
571 return val;
572 }
573
574 // Gestion avec bufferisation
575 if(!Buffer)
576 throw RangeCheckError("FitsABTColRd::Read: Buffer not allocated\n");
577 if(n<LineDeb || n>LineFin) {
578 NFitsRead++;
579 long row1,row2,nrow;
580 if(BuffSens>0) { // Cas remplissage forward
581 row1 = n+1;
582 row2 = row1+NBuffer-1; if(row2>NBline) row2 = NBline;
583 } else if(BuffSens<0) { // Cas remplissage backward
584 row2 = n+1;
585 row1 = row2-NBuffer+1; if(row1<1) row1 = 1;
586 } else { // Cas remplissage centre
587 row1 = n+1 - NBuffer/2; if(row1<1) row1 = 1;
588 row2 = n+1 + NBuffer/2; if(row2>NBline) row2 = NBline;
589 }
590 nrow = row2 - row1 + 1;
591 LineDeb = row1-1; LineFin = row2-1;
592 //cout<<"DBG-FitsRead: row1="<<row1<<" row2="<<row2<<" nrow="<<nrow
593 // <<" LineDeb,Fin="<<LineDeb<<","<<LineFin<<endl;
594 fits_read_col(FitsPtr,TDOUBLE,ColNum+1,row1,1,nrow,NULL,Buffer,NULL,&sta);
595 if(sta) {
596 FitsOpenFile::printerror(sta);
597 LineDeb = LineFin = -1;
598 throw NotAvailableOperation("FitsABTColRd::Read: Error Reading Fits file\n");
599 }
600 }
601
602 long ibuf = n-LineDeb;
603 return Buffer[ibuf];
604}
605
606/*!
607 Read rows from "n1" to "n2" and return the values into TVector of double
608 \return NREAD the number of values read (n2-n1+1).
609 \warning row = [0,NRows[, the routine read [n1,n2]
610 \verbatim
611 - if n2<0 then read [n1,n2] where "n2=min(n1+vector_size-1,nrows-1)"
612 - Last row read is ALWAYS: "n2 = n1 + NREAD -1"
613 - The TVector is never resized if not necessary
614 -------------------------------------------------------------------------
615 - ex: suppose the column table contains 10 elements: nrows=10, rows=[0,9]
616
617 TVector<double> V(5);
618 bt.Read(3,5,V) -> read rows=3,4,5 -> V.Size()==5 -> return 3
619 bt.Read(3,-1,V) -> read rows=3,4,5,6,7 -> V.Size()==5 -> return 5
620 bt.Read(7,-1,V) -> read rows=7,8,9 -> V.Size()==5 -> return 3
621 bt.Read(2,-1,V) -> read rows=2,3,4,5,6 -> V.Size()==5 -> return 5
622 bt.Read(-1,5,V) -> throw exception
623
624 TVector<double> V(5);
625 bt.Read(3,99,V) -> read rows=3,4,5,6,7,8,9 -> V.Size()==7 -> return 7
626
627 TVector<double> V(5);
628 bt.Read(2,8,V) -> read rows=2,3,4,5,6,7,8 -> V.Size()==7 -> return 7
629
630 TVector<double> V;
631 bt.Read(3,5,V) -> read rows=3,4,5 -> V.Size()==3 -> return 3
632
633 TVector<double> V;
634 bt.Read(3,-1,V) -> throw exception
635 -------------------------------------------------------------------------
636 \endverbatim
637*/
638long FitsABTColRd::Read(long n1,long n2,TVector<double>& data)
639{
640 if(n1<0 || n1>=NBline)
641 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
642 if(data.Size()<=0 && n2<n1)
643 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
644 if(n2<0) n2 = n1 + data.Size()-1;
645 if(n2>=NBline) n2 = NBline-1;
646
647 sa_size_t nread = n2-n1+1;
648 if(data.Size()<nread) data.SetSize(nread);
649
650 //for(long i=n1;i<=n2;i++) data(i-n1) = Read(i);
651 int sta=0;
652 fits_read_col(FitsPtr,TDOUBLE,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
653 if(sta) {
654 FitsOpenFile::printerror(sta);
655 throw NotAvailableOperation("FitsABTColRd::Read_TVector<double>: Error Reading Fits file\n");
656 }
657
658 return nread;
659}
660
661/*! idem before but for TVector of float */
662long FitsABTColRd::Read(long n1,long n2,TVector<float>& data)
663{
664 if(n1<0 || n1>=NBline)
665 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
666 if(data.Size()<=0 && n2<n1)
667 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
668 if(n2<0) n2 = n1 + data.Size()-1;
669 if(n2>=NBline) n2 = NBline-1;
670
671 sa_size_t nread = n2-n1+1;
672 if(data.Size()<nread) data.SetSize(nread);
673
674 //for(long i=n1;i<=n2;i++) data(i-n1) = Read(i);
675 int sta=0;
676 fits_read_col(FitsPtr,TFLOAT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
677 if(sta) {
678 FitsOpenFile::printerror(sta);
679 throw NotAvailableOperation("FitsABTColRd::Read_TVector<float>: Error Reading Fits file\n");
680 }
681
682 return nread;
683}
684
685/*! idem before but for TVector of unsigned short */
686long FitsABTColRd::Read(long n1,long n2,TVector<uint_2>& data)
687{
688 if(n1<0 || n1>=NBline)
689 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
690 if(data.Size()<=0 && n2<n1)
691 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
692 if(n2<0) n2 = n1 + data.Size()-1;
693 if(n2>=NBline) n2 = NBline-1;
694
695 sa_size_t nread = n2-n1+1;
696 if(data.Size()<nread) data.SetSize(nread);
697
698 int sta=0;
699 fits_read_col(FitsPtr,TUSHORT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
700 if(sta) {
701 FitsOpenFile::printerror(sta);
702 throw NotAvailableOperation("FitsABTColRd::Read_TVector<uint_2>: Error Reading Fits file\n");
703 }
704
705 return nread;
706}
707
708/*! idem before but for TVector of int_4 */
709long FitsABTColRd::Read(long n1,long n2,TVector<int_4>& data)
710{
711 if(n1<0 || n1>=NBline)
712 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
713 if(data.Size()<=0 && n2<n1)
714 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
715 if(n2<0) n2 = n1 + data.Size()-1;
716 if(n2>=NBline) n2 = NBline-1;
717
718 sa_size_t nread = n2-n1+1;
719 if(data.Size()<nread) data.SetSize(nread);
720
721 //for(long i=n1;i<=n2;i++) data(i-n1) = Read(i);
722 int sta=0;
723 int T = (sizeof(long)==4) ? TLONG: TINT;
724 fits_read_col(FitsPtr,T,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
725 if(sta) {
726 FitsOpenFile::printerror(sta);
727 throw NotAvailableOperation("FitsABTColRd::Read_TVector<int_4>: Error Reading Fits file\n");
728 }
729
730 return nread;
731}
732
733/*! idem before but for TVector of int_8 */
734long FitsABTColRd::Read(long n1,long n2,TVector<int_8>& data)
735{
736#ifdef TLONGLONG
737 if(n1<0 || n1>=NBline)
738 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 1srt line \n");
739 if(data.Size()<=0 && n2<n1)
740 throw RangeCheckError("FitsABTColRd::Read TVector bad requested 2sd line \n");
741 if(n2<0) n2 = n1 + data.Size()-1;
742 if(n2>=NBline) n2 = NBline-1;
743
744 sa_size_t nread = n2-n1+1;
745 if(data.Size()<nread) data.SetSize(nread);
746
747 int sta=0;
748 fits_read_col(FitsPtr,TLONGLONG,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
749 if(sta) {
750 FitsOpenFile::printerror(sta);
751 throw NotAvailableOperation("FitsABTColRd::Read_TVector<int_8>: Error Reading Fits file\n");
752 }
753
754 return nread;
755#else
756 throw PException("FitsABTColRd::Read(..,TVector<int_8>&) Not in that cfitsio version");
757#endif
758}
759
760/////////////////////////////////////////////////
761/*!
762 Return the number of the first row where "val1"<=val<="val2" starting at row "rowstart"
763 \verbatim
764 - The search is performed from "rowstart" to the end
765 in ascending order (from "rowstart" to nrows).
766 - Warning: "rowstart<0" means "rowstart==0" (search all the table column)
767 That is the default
768 \endverbatim
769 \return <0 means not found
770*/
771long FitsABTColRd::FirstRow(double val1,double val2,long rowstart)
772{
773 long row = -1;
774 if(NBline==0) return row;
775 // Change buffer for efficiency
776 long bsens=BuffSens; bool bchange=false;
777 if(bsens<=0) {ChangeBuffer(BuffLen,1); bchange=true;}
778 if(rowstart<0) rowstart = 0;
779 if(rowstart>=NBline) rowstart = NBline-1;
780 for(long i=rowstart;i<NBline;i++) {
781 double val = Read(i);
782 if(val<val1 || val>val2) continue;
783 row = i;
784 break;
785 }
786 if(bchange) ChangeBuffer(BuffLen,bsens);
787 return row;
788}
789
790/*!
791 Return the number of the first row where val1<=val<=val2 starting at row rowstart
792 \return <0 means not found
793 \verbatim
794 - The search is performed from "rowstart" to the beginning
795 in descending order (from "rowstart" to 0).
796 - Warning: "rowstart<0" means "rowstart==nrows-1" (search all the table column)
797 That is the default
798 \endverbatim
799*/
800long FitsABTColRd::LastRow(double val1,double val2,long rowstart)
801{
802 long row = -1;
803 if(NBline==0) return row;
804 // Change buffer for efficiency
805 long bsens=BuffSens; bool bchange=false;
806 if(bsens>=0) {ChangeBuffer(BuffLen,-1); bchange=true;}
807 if(rowstart<0 || rowstart>=NBline) rowstart = NBline-1;
808 for(long i=rowstart;i>=0;i--) {
809 double val = Read(i);
810 if(val<val1 || val>val2) continue;
811 row = i;
812 break;
813 }
814 if(bchange) ChangeBuffer(BuffLen,bsens);
815 return row;
816}
817
818/*! Print on stream os */
819void FitsABTColRd::Print(ostream& os,int lp) const
820{
821 os<<"FitsABTColRd:Print ("<<BuffLen<<","<<BuffSens<<","<<NulVal<<")"
822 <<" ncols="<<NBcol<<" nrows="<<NBline;
823 if(lp>0) os<<" NRead="<<NFitsRead;
824 os<<"\n... "<<FileName()<<"["<<HDU()<<"/"<<NHDU()<<" type="<<HDUType()<<"]"
825 <<"\n... Label["<<ColNum<<"]="<<ColLabel<<" TypeCode="<<ColTypeCode
826 <<" TUnit="<<ColTUnit<<" TForm="<<ColTForm
827 <<endl;
828}
829
830///////////////////////////////////////////////////////////////////
831///////////////////////////////////////////////////////////////////
832///////////////////////////////////////////////////////////////////
833///////////////////////////////////////////////////////////////////
834
835//! Class for reading a column in a FITS ASCII or BINARY table with fits file opening
836
837/*!
838 \class SOPHYA::FitsABTColRead
839 \ingroup FitsIOServer
840 Class for reading a column in a FITS ASCII or BINARY table with fits file opening
841 \verbatim
842 -- Exemple:
843 FitsABTColRead fbt("myfits.fits","BoloMuv_28",0,1000,1,3);
844 fbt.SetDebug(3);
845 fbt.Print(3);
846 // Read element by element
847 for(long i=0;i<fbt.GetNbLine();i++) {
848 double x = fbt.Read(i);
849 if(i%lpmod==0) cout<<i<<": "<<x<<endl;
850 }
851 // Read into a vector
852 TVector<double> data;
853 long n = fbt.Read(32,50,data);
854 cout<<"Number of values read: "<<n<<endl;
855 data.ReSize(100);
856 n = fbt.Read(10,-1,data);
857 cout<<"Number of values read: "<<n<<endl;
858 \endverbatim
859*/
860
861
862//////////////////////////////////////////////////////////////
863/*!
864 Constructor.
865 \param fname : FITS file name to be read
866 \param collabel : label of the column to be read
867 \param ihdu : number of the HDU where the column is.
868 \param blen : read buffer length
869 \param bsens : buffer reading direction
870 \param lp : debug level
871 \verbatim
872 - if ihdu<=0 first BINARY or ASCII table is taken
873 - if ihdu>nhdu ihdu is set to nhdu
874 - bsens>0 read forward
875 bsens<0 read backward
876 bsens==0 read centered
877 \endverbatim
878 \warning ihdu = [1,nhdu]
879*/
880FitsABTColRead::FitsABTColRead(string fname,string collabel
881 ,int ihdu,long blen,long bsens,int lp)
882: FitsABTColRd(new FitsOpenFile(fname),collabel,ihdu,blen,bsens,lp)
883{
884}
885
886/*!
887 Constructor.
888 Same as before but the column is identified by its column number
889 \param colnum : number of the column to be read
890 \warning col = [0,ncol[
891*/
892FitsABTColRead::FitsABTColRead(string fname,int colnum
893 ,int ihdu,long blen,long bsens,int lp)
894: FitsABTColRd(new FitsOpenFile(fname),colnum,ihdu,blen,bsens,lp)
895{
896}
897
898/*! Constructor. see below */
899FitsABTColRead::FitsABTColRead(const char * cfname,const char* collabel
900 ,int ihdu,long blen,long bsens,int lp)
901: FitsABTColRd(new FitsOpenFile(cfname),collabel,ihdu,blen,bsens,lp)
902{
903}
904
905/*! Constructor. see below */
906FitsABTColRead::FitsABTColRead(const char * cfname,int colnum
907 ,int ihdu,long blen,long bsens,int lp)
908: FitsABTColRd(new FitsOpenFile(cfname),colnum,ihdu,blen,bsens,lp)
909{
910}
911/*! Constructor by default */
912FitsABTColRead::FitsABTColRead()
913{
914}
915
916/*! Constructor by copy */
917FitsABTColRead::FitsABTColRead(FitsABTColRead& fbt)
918{
919 // --- ATTENTION ---
920 // FitsABTColRead ferme le fichier FITS: il faut dupliquer le FitsOpenFile
921 FitsOpenFile* fof = new FitsOpenFile(*fbt.GetFitsOpenFile());
922 Init(fof,fbt.GetColLabel().c_str()
923 ,fbt.GetColNum(),fbt.HDU()
924 ,fbt.GetBLen(),fbt.GetBSens(),fbt.DbgLevel);
925}
926
927/*! Destructor. */
928FitsABTColRead::~FitsABTColRead()
929{
930 Delete();
931 if(FitsOF!=NULL) delete FitsOF;
932}
933
934///////////////////////////////////////////////////////////////////
935//! Class for reading a 2D image from a FITS file
936
937/*!
938 \class SOPHYA::FitsImg2DRd
939 \ingroup FitsIOServer
940 Class for reading a 2D image from a FITS file
941*/
942
943//////////////////////////////////////////////////////////////
944/*!
945 Constructor.
946 \param fof : Pointer to the Class for opening the FITS file
947 \param ihdu : number of the HDU where the image is.
948 \param lp : debug level
949 \verbatim
950 - if ihdu<=0 first IMAGE hdu is taken
951 - if ihdu>nhdu ihdu is set to nhdu
952 \endverbatim
953 \warning ihdu = [1,nhdu]
954*/
955FitsImg2DRd::FitsImg2DRd(FitsOpenFile* fof,int ihdu,int lp)
956{
957 Init(fof,ihdu,lp);
958}
959
960/*! Constructor by copy */
961FitsImg2DRd::FitsImg2DRd(FitsImg2DRd& fbt)
962{
963 Init(fbt.GetFitsOpenFile(),fbt.HDU(),fbt.DbgLevel);
964}
965
966/*! Constructor by default */
967FitsImg2DRd::FitsImg2DRd()
968{
969 Naxis[0] = Naxis[1] = 0;
970 SetNulVal(); SetDebug(0);
971 FitsOF = NULL; FitsPtr = NULL;
972}
973
974/*! Init routine called by the constructor */
975void FitsImg2DRd::Init(FitsOpenFile* fof,int ihdu,int lp)
976{
977 // Initialisation des Parametres Generaux
978 Naxis[0] = Naxis[1] = 0;
979 SetNulVal(); SetDebug(lp);
980 FitsOF = NULL; FitsPtr = NULL;
981
982 // Caracteristiques du FitsOpenFile
983 FitsOF = fof;
984 if(FitsOF==NULL)
985 throw NullPtrError("FitsImg2DRd::Init: FitsOpenFile pointer is NULL\n");
986
987 FitsPtr = FitsOF->GetFitsPtr();
988 if(FitsPtr==NULL)
989 throw NullPtrError("FitsImg2DRd::Init: FitsPtr pointer is NULL\n");
990
991 int sta = 0;
992 if(ihdu<0) ihdu=0; if(ihdu>NHDU()) ihdu=NHDU();
993
994 // Get HDU 2D image
995 // ATTENTION: ... cf blabla equivalent dans FitsABTColRd::Init()
996 if(FitsOF->GetPosStatus()==false) {
997 if(ihdu==0) { // find the first IMAGE_HDU
998 FitsOF->MoveToFirst(IMAGE_HDU);
999 } else {
1000 int rc = FitsOF->MoveToHDU(ihdu);
1001 if(rc!=ihdu)
1002 throw RangeCheckError("FitsABTColRd::Init: Error moving to requested HDU\n");
1003 }
1004 } else { // Fits file has already been positionned
1005 if(ihdu>0 && ihdu!=HDU())
1006 throw RangeCheckError("FitsABTColRd::Init: file already posit. at another HDU\n");
1007 }
1008
1009 // Check HDUType and set position status to TRUE
1010 if(HDUType()!=IMAGE_HDU)
1011 throw TypeMismatchExc("FitsImg2DRd::Init: HDU not IMAGE_HDU\n");
1012 FitsOF->SetPosStatus(true);
1013
1014 // Get NAXIS 1 et 2
1015 int nfound=0;
1016 if(fits_read_keys_lng(FitsPtr,"NAXIS",1,2,Naxis,&nfound,&sta)) {
1017 FitsOpenFile::printerror(sta);
1018 throw RangeCheckError("FitsImg2DRd::Init: Error reading NAXIS cards\n");
1019 }
1020 if(DbgLevel>1)
1021 cout<<"...Init(hdu="<<HDU()<<") NAXIS1="<<Naxis[0]<<" NAXIS2="
1022 <<Naxis[1]<<" (nfound="<<nfound<<")"<<endl;
1023 if(nfound!=2 || Naxis[0]<=0 || Naxis[1]<=0)
1024 throw NotAvailableOperation("FitsImg2DRd::Init: bad Naxis[0-1] value\n");
1025
1026}
1027
1028/*! Destructor. */
1029FitsImg2DRd::~FitsImg2DRd()
1030{
1031 //--- Surtout on ne "fits_close_file" pas le fichier FITS !!!
1032 Naxis[0] = Naxis[1] = 0;
1033}
1034
1035//////////////////////////////////////////////////////////////
1036/*!
1037 Read a fitsheader key into double
1038 \param keyname : name of the key
1039 \return value into double
1040*/
1041double FitsImg2DRd::ReadKey(char *keyname)
1042{
1043 return FitsOpenFile::ReadKey(FitsPtr,keyname);
1044}
1045
1046/*!
1047 Read a fitsheader key into long
1048 \param keyname : name of the key
1049 \return value into long
1050*/
1051long FitsImg2DRd::ReadKeyL(char *keyname)
1052{
1053 return FitsOpenFile::ReadKeyL(FitsPtr,keyname);
1054}
1055
1056/*!
1057 Read a fitsheader key into string
1058 \param keyname : name of the key
1059 \return value into string
1060*/
1061string FitsImg2DRd::ReadKeyS(char *keyname)
1062{
1063 return FitsOpenFile::ReadKeyS(FitsPtr,keyname);
1064}
1065
1066//////////////////////////////////////////////////////////////
1067/* REMARQUE:
1068 * Si une image FITS a NAXIS1=100 et NAXIS2=50
1069 * alors un tableau 2D juste assez grand pour contenir l'image
1070 * doit etre declare array[50][100] (et non pas array[100][50])
1071 * array[NAXIS2][NAXIS1]
1072 */
1073/*!
1074Read image into a TMatrix<uint_2>
1075\warning TMatrix data(Naxis2,Naxis1)
1076*/
1077long FitsImg2DRd::Read(TMatrix<uint_2>& data)
1078{
1079 int sta=0;
1080 uint_2* arr = new uint_2[Naxis[0]];
1081 data.ReSize(Naxis[1],Naxis[0]);
1082
1083 for(int j=0;j<Naxis[1];j++) {
1084 long deb = j*Naxis[0]+1, nel = Naxis[0];
1085 fits_read_img(FitsPtr,TUSHORT,deb,nel,&NulVal,arr,NULL,&sta);
1086 if(sta) {
1087 FitsOpenFile::printerror(sta); delete [] arr;
1088 throw
1089 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<uint_2>): Error Reading Fits file\n");
1090 }
1091 for(int i=0;i<Naxis[0];i++) data(j,i) = arr[i];
1092 }
1093
1094 delete [] arr;
1095 return Naxis[0]*Naxis[1];
1096 }
1097
1098/*! Read image into a TMatrix<int_4> */
1099long FitsImg2DRd::Read(TMatrix<int_4>& data)
1100{
1101 int sta=0;
1102 int_4* arr = new int_4[Naxis[0]];
1103 data.ReSize(Naxis[1],Naxis[0]);
1104 int T = (sizeof(long)==4) ? TLONG: TINT;
1105
1106 for(int j=0;j<Naxis[1];j++) {
1107 long deb = j*Naxis[0]+1, nel = Naxis[0];
1108 fits_read_img(FitsPtr,T,deb,nel,&NulVal,arr,NULL,&sta);
1109 if(sta) {
1110 FitsOpenFile::printerror(sta); delete [] arr;
1111 throw
1112 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<int_4>): Error Reading Fits file\n");
1113 }
1114 for(int i=0;i<Naxis[0];i++) data(j,i) = arr[i];
1115 }
1116
1117 delete [] arr;
1118 return Naxis[0]*Naxis[1];
1119 }
1120
1121/*! Read image into a TMatrix<int_8> */
1122long FitsImg2DRd::Read(TMatrix<int_8>& data)
1123{
1124 int sta=0;
1125 int_8* arr = new int_8[Naxis[0]];
1126 data.ReSize(Naxis[1],Naxis[0]);
1127
1128 for(int j=0;j<Naxis[1];j++) {
1129 long deb = j*Naxis[0]+1, nel = Naxis[0];
1130 fits_read_img(FitsPtr,TLONGLONG,deb,nel,&NulVal,arr,NULL,&sta);
1131 if(sta) {
1132 FitsOpenFile::printerror(sta); delete [] arr;
1133 throw
1134 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<int_8>): Error Reading Fits file\n");
1135 }
1136 for(int i=0;i<Naxis[0];i++) data(j,i) = arr[i];
1137 }
1138
1139 delete [] arr;
1140 return Naxis[0]*Naxis[1];
1141 }
1142
1143/*! Read image into a TMatrix<float> */
1144long FitsImg2DRd::Read(TMatrix<float>& data)
1145{
1146 int sta=0;
1147 float* arr = new float[Naxis[0]];
1148 data.ReSize(Naxis[1],Naxis[0]);
1149
1150 for(int j=0;j<Naxis[1];j++) {
1151 long deb = j*Naxis[0]+1, nel = Naxis[0];
1152 fits_read_img(FitsPtr,TFLOAT,deb,nel,&NulVal,arr,NULL,&sta);
1153 if(sta) {
1154 FitsOpenFile::printerror(sta); delete [] arr;
1155 throw
1156 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<float>): Error Reading Fits file\n");
1157 }
1158 for(int i=0;i<Naxis[0];i++) data(j,i) = arr[i];
1159 }
1160
1161 delete [] arr;
1162 return Naxis[0]*Naxis[1];
1163 }
1164
1165/*! Read image into a TMatrix<double> */
1166long FitsImg2DRd::Read(TMatrix<double>& data)
1167{
1168 int sta=0;
1169 double* arr = new double[Naxis[0]];
1170 data.ReSize(Naxis[1],Naxis[0]);
1171
1172 for(int j=0;j<Naxis[1];j++) {
1173 long deb = j*Naxis[0]+1, nel = Naxis[0];
1174 fits_read_img(FitsPtr,TDOUBLE,deb,nel,&NulVal,arr,NULL,&sta);
1175 if(sta) {
1176 FitsOpenFile::printerror(sta); delete [] arr;
1177 throw
1178 NotAvailableOperation("FitsImg2DRd::Read(TMatrix<double>): Error Reading Fits file\n");
1179 }
1180 for(int i=0;i<Naxis[0];i++) data(j,i) = arr[i];
1181 }
1182
1183 delete [] arr;
1184 return Naxis[0]*Naxis[1];
1185 }
Note: See TracBrowser for help on using the repository browser.