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

Last change on this file since 2789 was 2789, checked in by cmv, 20 years ago

ajouts de commentaires cmv 31/05/2005

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