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

Last change on this file since 2785 was 2615, checked in by cmv, 21 years ago

using namespace sophya enleve de machdefs.h, nouveau sopnamsp.h cmv 10/09/2004

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