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

Last change on this file since 1657 was 1657, checked in by cmv, 24 years ago

possibilite d'ecrire directement des TVector fabtwriter cmv 27/9/01

File size: 10.5 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//! Class for reading a column in a FITS ASCII or BINARY table
8
9/*!
10 \class SOPHYA::FitsABTColRead
11 \ingroup FitsIOServer
12 Class for reading a column in a FITS ASCII or BINARY table
13 \verbatim
14 Exemple:
15 FitsABTColRead fbt("myfits.fits","BoloMuv_28",0,1000,1,3);
16 fbt.SetDebug(3);
17 fbt.Print(3);
18 for(long i=0;i<fbt.GetNbLine();i++) {
19 double x = fbt.Read(i);
20 if(i%lpmod==0) cout<<i<<": "<<x<<endl;
21 }
22 \endverbatim
23*/
24
25//////////////////////////////////////////////////////////////
26/*!
27 Constructor.
28 \verbatim
29 fname : FITS file name to be read
30 collabel : label of the column to be read
31 ihdu : number of the HDU where the column is.
32 if ihdu=0 or ihdu>nhdu first binary or ASCII table is taken
33 Warning: ihdu = [1,nhdu]
34 blen : read buffer length
35 bsens : read buffer reading direction
36 (bsens>0 forward, bsens<0 backward, bsens==0 centered)
37 lp : debug level
38 \endverbatim
39*/
40FitsABTColRead::FitsABTColRead(string fname,string collabel
41 ,int ihdu,long blen,long bsens,int lp)
42{
43Init(fname.c_str(),collabel.c_str(),-1,ihdu,blen,bsens,lp);
44}
45
46/*!
47 Constructor.
48 \verbatim
49 Same as before but the column is identified by its number
50 colnum : number of the column to be read
51 WARNING: col = [0,ncol[
52 \endverbatim
53*/
54FitsABTColRead::FitsABTColRead(string fname,int colnum
55 ,int ihdu,long blen,long bsens,int lp)
56{
57Init(fname.c_str(),"",colnum,ihdu,blen,bsens,lp);
58}
59
60/*! Constructor. see below */
61FitsABTColRead::FitsABTColRead(const char * cfname,const char* collabel
62 ,int ihdu,long blen,long bsens,int lp)
63{
64Init(cfname,collabel,-1,ihdu,blen,bsens,lp);
65}
66
67/*! Constructor. see below */
68FitsABTColRead::FitsABTColRead(const char * cfname,int colnum
69 ,int ihdu,long blen,long bsens,int lp)
70{
71Init(cfname,"",colnum,ihdu,blen,bsens,lp);
72}
73
74/*! Constructor by copy */
75FitsABTColRead::FitsABTColRead(FitsABTColRead& fbt)
76{
77Init(fbt.GetFileName().c_str(),fbt.GetColLabel().c_str()
78 ,fbt.GetColNum(),fbt.GetHDU()
79 ,fbt.GetBLen(),fbt.GetBSens(),fbt.DbgLevel);
80}
81
82/*! Init routine called by the constructor */
83void FitsABTColRead::Init(const char* fname,const char* collabel,int colnum
84 ,int ihdu,long blen,long bsens,int lp)
85{
86 // Parametres Generaux
87 FitsFN = fname;
88 ColLabel = collabel;
89 ColTUnit = "";
90 ColTForm = "";
91 ColNum = colnum;
92 ColTypeCode = 0;
93 IHdu = ihdu;
94 NHdu = 0;
95 HduType = 0;
96 NBcol = 0;
97 NBline = 0;
98 SetNulVal();
99 SetDebug(lp);
100 NFitsRead = 0;
101 FitsPtr = NULL;
102 LineDeb = LineFin = -1;
103 Buffer = NULL;
104 ChangeBuffer(blen,bsens);
105
106 //////////////////////////
107 // Ouverture du fichier //
108 //////////////////////////
109
110 int sta=0;
111 if(FitsFN.size() <= 0 ) {
112 IHdu = -1; Delete();
113 throw ParmError("FitsABTColRead::Init: Fits file name error\n");
114 }
115 const char * cfitsfn = FitsFN.c_str();
116
117 // Open fits
118 if(fits_open_file(&FitsPtr,cfitsfn,READONLY,&sta)) {
119 printerror(sta); Delete();
120 throw NullPtrError("FitsABTColRead::Init: Error opening Fits file\n");
121 }
122
123 // Get number of hdu
124 if(fits_get_num_hdus(FitsPtr,&NHdu,&sta)) {
125 printerror(sta); Delete();
126 throw NotAvailableOperation("FitsABTColRead::Init: Error getting NHdu\n");
127 }
128 if(DbgLevel>1) cout<<"FitsABTColRead::Init NHdu="<<NHdu<<endl;
129 if(NHdu<=0) {
130 Delete();
131 throw SzMismatchError("FitsABTColRead::Init: Bad NHdu\n");
132 }
133
134 // Get HDU for bin/ascii table
135 // si IHdu <=0 || >NHdu on cherche la 1ere bin/ascii table
136 // sinon on se positionne sur IHdu
137 if(IHdu<=0 || IHdu>NHdu)
138 for(int ihdu=1;ihdu<=NHdu;ihdu++) {
139 if(fits_movabs_hdu(FitsPtr,ihdu,&HduType,&sta)) printerror(sta);
140 if(DbgLevel>1) cout<<"...Init ihdu="
141 <<ihdu<<" HduType="<<HduType<<endl;
142 if(HduType==BINARY_TBL || HduType==ASCII_TBL) {IHdu = ihdu; break;}
143 }
144 if(IHdu<=0 || IHdu>NHdu) {
145 cout<<"NO BINARY or ASCII hdu found"<<endl;
146 IHdu = 0; Delete();
147 throw TypeMismatchExc("FitsABTColRead::Init: NO BINARY or ASCII hdu found\n");
148 }
149 if(fits_movabs_hdu(FitsPtr,IHdu,&HduType,&sta)) {
150 printerror(sta); Delete();
151 throw RangeCheckError("FitsABTColRead::Init: Error moving to requested HDU\n");
152 }
153 if(HduType!=BINARY_TBL && HduType!=ASCII_TBL) {
154 Delete();
155 throw TypeMismatchExc("FitsABTColRead::Init: HDU not ASCII/BINARY table\n");
156 }
157
158 // Get number of columns
159 if(fits_get_num_cols(FitsPtr,&NBcol,&sta)) {
160 printerror(sta); Delete();
161 throw NotAvailableOperation("FitsABTColRead::Init: Error getting number of columns\n");
162 }
163 if(DbgLevel>1) cout<<"...Init NBcol="<<NBcol<<endl;
164 if(NBcol<1) {
165 Delete();
166 throw RangeCheckError("FitsABTColRead::Init: Bad number of colums\n");
167 }
168
169 // Get number of rows
170 if(fits_get_num_rows(FitsPtr,&NBline,&sta)) {
171 printerror(sta); Delete();
172 throw NotAvailableOperation("FitsABTColRead::Init: Error getting number of rows\n");
173 }
174 if(DbgLevel>1) cout<<"...Init NBline="<<NBline<<endl;
175 if(NBline<1) {
176 Delete();
177 throw RangeCheckError("FitsABTColRead::Init: Bad number of rows\n");
178 }
179
180 // Get column number
181 char labelcol[256];
182 if(ColLabel.size() > 0) {
183 strcpy(labelcol,ColLabel.c_str());
184 if(fits_get_colnum(FitsPtr,CASESEN,labelcol,&ColNum,&sta)) {
185 printerror(sta); Delete();
186 throw NotAvailableOperation("FitsABTColRead::Init: Error getting column name\n");
187 }
188 ColNum--; // Convention [0,ncol[
189 }
190 if(DbgLevel>1) cout<<"...Init ColNum="<<ColNum<<endl;
191 if(ColNum<0 || ColNum>=NBcol) {
192 Delete();
193 throw RangeCheckError("FitsABTColRead::Init: Bad column number\n");
194 }
195
196 // Get column type
197 int ColTypeCode;
198 if(fits_get_coltype(FitsPtr,ColNum+1,&ColTypeCode,NULL,NULL,&sta)) {
199 printerror(sta); Delete();
200 throw ParmError("FitsABTColRead::Init: Error getting column type\n");
201 }
202 if(DbgLevel>1) cout<<"...Init ColTypeCode="<<ColTypeCode<<endl;
203 if(ColTypeCode==TSTRING || ColTypeCode==TCOMPLEX || ColTypeCode==TDBLCOMPLEX) {
204 Delete();
205 throw ParmError("FitsABTColRead::Init: Selected column is not Numerical\n");
206 }
207
208 // Get column name back, tunit, tform
209 char tunit[64], tform[64];
210 int rc=0;
211 if(HduType==BINARY_TBL) {
212 fits_get_bcolparms(FitsPtr,ColNum+1,labelcol,tunit,tform,NULL,NULL,NULL,NULL,NULL,&sta);
213 } else {
214 fits_get_acolparms(FitsPtr,ColNum+1,labelcol,NULL,tunit,tform,NULL,NULL,NULL,NULL,&sta);
215 }
216 if(rc) {
217 printerror(sta); Delete();
218 throw RangeCheckError("FitsABTColRead::Init: Error getting the column caracteristics\n");
219 }
220 ColLabel = labelcol;
221 ColTUnit = tunit;
222 ColTForm = tform;
223
224 if(DbgLevel)
225 cout<<"FitsABTColRead::Init Num="<<ColNum<<" Label="<<ColLabel
226 <<" TypeCode="<<ColTypeCode
227 <<" TUnit="<<ColTUnit<<" TForm="<<ColTForm<<endl;
228
229}
230
231/*! Destructor. */
232FitsABTColRead::~FitsABTColRead()
233{
234 Delete();
235}
236
237
238//////////////////////////////////////////////////////////////
239/*! Change the buffer caracteristiques (see creator) */
240void FitsABTColRead::ChangeBuffer(long blen,long bsens)
241{
242 long oldnbuffer = NBuffer;
243
244 // Compute buffer caracteristics
245 BuffLen = (blen<=0)? 1: blen;
246 BuffSens = bsens;
247 NBuffer = BuffLen;
248 if(bsens==0 && NBuffer%2==0) NBuffer++;
249
250 // De-allocate if necessary
251 if(Buffer!=NULL && oldnbuffer!=NBuffer)
252 {delete [] Buffer; Buffer=NULL;}
253
254 // Re-allocate
255 if(Buffer==NULL) Buffer = new double[NBuffer];
256
257 // Tell program that nothing is into buffer
258 LineDeb = LineFin = -1;
259}
260
261/*! Delete called by the destructor */
262void FitsABTColRead::Delete()
263{
264 if(Buffer!=NULL) {delete [] Buffer; Buffer=NULL;}
265 LineDeb = LineFin = -1;
266 int sta = 0;
267 if(fits_close_file(FitsPtr,&sta)) printerror(sta);
268 FitsPtr = NULL;
269}
270
271/////////////////////////////////////////////////
272/*!
273 Read row "n" and return the value cats into double
274 \verbatim
275 WARNING: row = [0,NRows[
276 \endverbatim
277*/
278double FitsABTColRead::Read(long n)
279// Attention: n=nline [0,NBline[, cfistio veut [1,NBline]
280// Attention: colnum [0,NBcol[ , cfistio veut [1,NBcol]
281{
282 int sta=0,anynul;
283 if(n<0 || n>=NBline)
284 throw RangeCheckError("FitsABTColRead::Read try to read outside line range\n");
285
286 // Pas de bufferisation, on lit betement
287 if(NBuffer==1) {
288 NFitsRead++;
289 fits_read_col_dbl(FitsPtr,ColNum+1,n+1,1,1,NulVal,Buffer,&anynul,&sta);
290 if(sta) {
291 printerror(sta);
292 throw NotAvailableOperation("FitsABTColRead::Read: Error Reading Fits file\n");
293 }
294 return Buffer[0];
295 }
296
297 // Gestion avec bufferisation
298 if(!Buffer) {
299 cout<<"FitsABTNtuIntf::Read Buffer not allocated"<<endl;
300 return 0;
301 }
302 if(n<LineDeb || n>LineFin) {
303 NFitsRead++;
304 long row1,row2,nrow;
305 if(BuffSens>0) { // Cas remplissage forward
306 row1 = n+1;
307 row2 = row1+NBuffer-1; if(row2>NBline) row2 = NBline;
308 } else if(BuffSens<0) { // Cas remplissage backward
309 row2 = n+1;
310 row1 = row2-NBuffer+1; if(row1<1) row1 = 1;
311 } else { // Cas remplissage centre
312 row1 = n+1 - NBuffer/2; if(row1<1) row1 = 1;
313 row2 = n+1 + NBuffer/2; if(row2>NBline) row2 = NBline;
314 }
315 nrow = row2 - row1 + 1;
316 LineDeb = row1-1; LineFin = row2-1;
317 //cout<<"DBG-FitsRead: row1="<<row1<<" row2="<<row2<<" nrow="<<nrow
318 // <<" LineDeb,Fin="<<LineDeb<<","<<LineFin<<endl;
319 fits_read_col_dbl(FitsPtr,ColNum+1,row1,1,nrow,NulVal,Buffer,&anynul,&sta);
320 if(sta) {
321 printerror(sta);
322 LineDeb = LineFin = -1;
323 throw NotAvailableOperation("FitsABTColRead::Read: Error Reading Fits file\n");
324 }
325 }
326
327 long ibuf = n-LineDeb;
328 return Buffer[ibuf];
329}
330
331/*!
332 Read rows from "n1" to "n2" and return the values cats in a TVector of double
333 \verbatim
334 There are n2-n1+1 values returned
335 WARNING: row = [0,NRows[
336 \endverbatim
337*/
338void FitsABTColRead::Read(long n1,long n2,TVector<double>& data)
339{
340 if(n1<0 || n1>=NBline || n2<0 || n2>=NBline || n1>n2)
341 throw RangeCheckError("FitsABTColRead::Read TVector bad requested line range\n");
342
343 sa_size_t n = n2-n1+1;
344 if(data.Size()<n) data.SetSize(n);
345 // Il faut faire mieux mais comment ????
346 for(long i=n1;i<=n2;i++) data(i-n1) = Read(i);
347}
348
349/////////////////////////////////////////////////
350void FitsABTColRead::printerror(int sta) const
351{
352 int stat = sta;
353 fits_report_error(stdout,stat);
354 fflush(stdout);
355 return;
356}
357
358/*! Print on stream os */
359void FitsABTColRead::Print(ostream& os,int lp) const
360{
361 os<<"FitsABTColRead:Print ("<<BuffLen<<","<<BuffSens<<","<<NulVal<<")"
362 <<" ncols="<<NBcol<<" nrows="<<NBline;
363 if(lp>0) os<<" NRead="<<NFitsRead;
364 os<<"\n... "<<FitsFN<<"["<<IHdu<<"/"<<NHdu<<"]"
365 <<"\n... Label["<<ColNum<<"]="<<ColLabel
366 <<" TypeCode="<<ColTypeCode
367 <<" TUnit="<<ColTUnit<<" TForm="<<ColTForm
368 <<endl;
369}
Note: See TracBrowser for help on using the repository browser.