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

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

Creation du FITS TOI reader et Writer (du pauvre) cmv 26/9/2001

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 BuffLen = (blen<=0) ? 1: blen;
101 BuffSens = bsens;
102 NFitsRead = 0;
103 FitsPtr = NULL;
104 LineDeb = LineFin = -1;
105 Buffer = NULL;
106 NBuffer = 0;
107
108 //////////////////////////
109 // Ouverture du fichier //
110 //////////////////////////
111
112 int sta=0;
113 if(FitsFN.size() <= 0 ) {
114 IHdu = -1;
115 throw ParmError("FitsABTColRead::Init: Fits file name error\n");
116 }
117 const char * cfitsfn = FitsFN.c_str();
118
119 // Open fits
120 if(fits_open_file(&FitsPtr,cfitsfn,READONLY,&sta)) {
121 printerror(sta); Delete();
122 throw NullPtrError("FitsABTColRead::Init: Error opening Fits file\n");
123 }
124
125 // Get number of hdu
126 if(fits_get_num_hdus(FitsPtr,&NHdu,&sta)) {
127 printerror(sta); Delete();
128 throw NotAvailableOperation("FitsABTColRead::Init: Error getting NHdu\n");
129 }
130 if(DbgLevel>1) cout<<"FitsABTColRead::Init NHdu="<<NHdu<<endl;
131 if(NHdu<=0) {
132 Delete();
133 throw SzMismatchError("FitsABTColRead::Init: Bad NHdu\n");
134 }
135
136 // Get HDU for bin/ascii table
137 // si IHdu <=0 || >NHdu on cherche la 1ere bin/ascii table
138 // sinon on se positionne sur IHdu
139 if(IHdu<=0 || IHdu>NHdu)
140 for(int ihdu=1;ihdu<=NHdu;ihdu++) {
141 if(fits_movabs_hdu(FitsPtr,ihdu,&HduType,&sta)) printerror(sta);
142 if(DbgLevel>1) cout<<"...Init ihdu="
143 <<ihdu<<" HduType="<<HduType<<endl;
144 if(HduType==BINARY_TBL || HduType==ASCII_TBL) {IHdu = ihdu; break;}
145 }
146 if(IHdu<=0 || IHdu>NHdu) {
147 IHdu = 0;
148 cout<<"NO BINARY or ASCII hdu found"<<endl;
149 Delete();
150 throw TypeMismatchExc("FitsABTColRead::Init: NO BINARY or ASCII hdu found\n");
151 }
152 if(fits_movabs_hdu(FitsPtr,IHdu,&HduType,&sta)) {
153 printerror(sta); Delete();
154 throw RangeCheckError("FitsABTColRead::Init: Error moving to requested HDU\n");
155 }
156 if(HduType!=BINARY_TBL && HduType!=ASCII_TBL) {
157 Delete();
158 throw TypeMismatchExc("FitsABTColRead::Init: HDU not ASCII/BINARY table\n");
159 }
160
161 // Get number of columns
162 if(fits_get_num_cols(FitsPtr,&NBcol,&sta)) {
163 printerror(sta); Delete();
164 throw NotAvailableOperation("FitsABTColRead::Init: Error getting number of columns\n");
165 }
166 if(DbgLevel>1) cout<<"...Init NBcol="<<NBcol<<endl;
167 if(NBcol<1) {
168 Delete();
169 throw RangeCheckError("FitsABTColRead::Init: Bad number of colums\n");
170 }
171
172 // Get number of rows
173 if(fits_get_num_rows(FitsPtr,&NBline,&sta)) {
174 printerror(sta); Delete();
175 throw NotAvailableOperation("FitsABTColRead::Init: Error getting number of rows\n");
176 }
177 if(DbgLevel>1) cout<<"...Init NBline="<<NBline<<endl;
178 if(NBline<1) {
179 Delete();
180 throw RangeCheckError("FitsABTColRead::Init: Bad number of rows\n");
181 }
182
183 // Get column number
184 char labelcol[256];
185 if(ColLabel.size() > 0) {
186 strcpy(labelcol,ColLabel.c_str());
187 if(fits_get_colnum(FitsPtr,CASESEN,labelcol,&ColNum,&sta)) {
188 printerror(sta); Delete();
189 throw NotAvailableOperation("FitsABTColRead::Init: Error getting column name\n");
190 }
191 ColNum--; // Convention [0,ncol[
192 }
193 if(DbgLevel>1) cout<<"...Init ColNum="<<ColNum<<endl;
194 if(ColNum<0 || ColNum>=NBcol) {
195 Delete();
196 throw RangeCheckError("FitsABTColRead::Init: Bad column number\n");
197 }
198
199 // Get column type
200 int ColTypeCode;
201 if(fits_get_coltype(FitsPtr,ColNum+1,&ColTypeCode,NULL,NULL,&sta)) {
202 printerror(sta); Delete();
203 throw ParmError("FitsABTColRead::Init: Error getting column type\n");
204 }
205 if(DbgLevel>1) cout<<"...Init ColTypeCode="<<ColTypeCode<<endl;
206 if(ColTypeCode==TSTRING || ColTypeCode==TCOMPLEX || ColTypeCode==TDBLCOMPLEX) {
207 Delete();
208 throw ParmError("FitsABTColRead::Init: Selected column is not Numerical\n");
209 }
210
211 // Get column name back, tunit, tform
212 char tunit[64], tform[64];
213 int rc=0;
214 if(HduType==BINARY_TBL) {
215 fits_get_bcolparms(FitsPtr,ColNum+1,labelcol,tunit,tform,NULL,NULL,NULL,NULL,NULL,&sta);
216 } else {
217 fits_get_acolparms(FitsPtr,ColNum+1,labelcol,NULL,tunit,tform,NULL,NULL,NULL,NULL,&sta);
218 }
219 if(rc) {
220 printerror(sta); Delete();
221 throw RangeCheckError("FitsABTColRead::Init: Error getting the column caracteristics\n");
222 }
223 ColLabel = labelcol;
224 ColTUnit = tunit;
225 ColTForm = tform;
226
227 if(DbgLevel)
228 cout<<"FitsABTColRead::Init Num="<<ColNum<<" Label="<<ColLabel
229 <<" TypeCode="<<ColTypeCode
230 <<" TUnit="<<ColTUnit<<" TForm="<<ColTForm<<endl;
231
232 // Prepare buffer
233 NBuffer = (BuffSens==0) ? BuffLen+1: BuffLen;
234 Buffer = new double[NBuffer];
235}
236
237/*! Destructor. */
238FitsABTColRead::~FitsABTColRead()
239{
240 Delete();
241}
242
243
244//////////////////////////////////////////////////////////////
245/*! Change the buffer caracteristiques (see creator) */
246void FitsABTColRead::ChangeBuffer(long blen,long bsens)
247{
248 BuffLen = (blen<=0)? 1: blen;
249 BuffSens = bsens;
250
251 // De-allocate
252 if(Buffer==NULL) return;
253 delete [] Buffer; Buffer=NULL;
254
255 // Tell program that nothing is into buffer
256 LineDeb = LineFin = -1;
257
258 // Re-allocate
259 NBuffer = (BuffSens==0) ? BuffLen+1: BuffLen;
260 Buffer = new double[NBuffer];
261}
262
263/*! Delete called by the destructor */
264void FitsABTColRead::Delete()
265{
266 if(Buffer==NULL) return;
267 delete [] Buffer; Buffer=NULL;
268 LineDeb = LineFin = -1;
269 int sta = 0;
270 if(fits_close_file(FitsPtr,&sta)) printerror(sta);
271 FitsPtr = NULL;
272}
273
274/////////////////////////////////////////////////
275/*!
276 Read row "n" and return the value cats into double
277 \verbatim
278 WARNING: row = [0,NRows[
279 \endverbatim
280*/
281r_8 FitsABTColRead::Read(long n)
282// Attention: n=nline [0,NBline[, cfistio veut [1,NBline]
283// Attention: colnum [0,NBcol[ , cfistio veut [1,NBcol]
284{
285 int sta=0,anynul;
286 if(n<0 || n>=NBline)
287 throw RangeCheckError("FitsABTColRead::Read try to read outside line range\n");
288
289 // Pas de bufferisation, on lit betement
290 if(BuffLen==1) {
291 NFitsRead++;
292 fits_read_col_dbl(FitsPtr,ColNum+1,n+1,1,1,NulVal,Buffer,&anynul,&sta);
293 if(sta) {
294 printerror(sta);
295 throw NotAvailableOperation("FitsABTColRead::Read: Error Reading Fits file\n");
296 }
297 return Buffer[0];
298 }
299
300 // Gestion avec bufferisation
301 if(!Buffer) {
302 cout<<"FitsABTNtuIntf::Read Buffer not allocated"<<endl;
303 return 0;
304 }
305 if(n<LineDeb || n>LineFin) {
306 NFitsRead++;
307 long row1,row2,nrow;
308 if(BuffSens>0) { // Cas remplissage forward
309 row1 = n+1;
310 row2 = row1+BuffLen-1; if(row2>NBline) row2 = NBline;
311 } else if(BuffSens<0) { // Cas remplissage backward
312 row2 = n+1;
313 row1 = row2-BuffLen+1; if(row1<1) row1 = 1;
314 } else { // Cas remplissage centre
315 row1 = n+1 - BuffLen/2; if(row1<1) row1 = 1;
316 row2 = n+1 + BuffLen/2; if(row2>NBline) row2 = NBline;
317 }
318 nrow = row2 - row1 + 1;
319 LineDeb = row1-1; LineFin = row2-1;
320 //cout<<"DBG-FitsRead: row1="<<row1<<" row2="<<row2<<" nrow="<<nrow
321 // <<" LineDeb,Fin="<<LineDeb<<","<<LineFin<<endl;
322 fits_read_col_dbl(FitsPtr,ColNum+1,row1,1,nrow,NulVal,Buffer,&anynul,&sta);
323 if(sta) {
324 printerror(sta);
325 LineDeb = LineFin = -1;
326 throw NotAvailableOperation("FitsABTColRead::Read: Error Reading Fits file\n");
327 }
328 }
329
330 long ibuf = n-LineDeb;
331 return Buffer[ibuf];
332}
333
334/*!
335 Read rows from "n1" to "n2" and return the values cats in a TVector of double
336 \verbatim
337 There are n2-n1+1 values returned
338 WARNING: row = [0,NRows[
339 \endverbatim
340*/
341void FitsABTColRead::Read(long n1,long n2,TVector<r_8>& data)
342{
343 if(n1<0 || n1>=NBline || n2<0 || n2>=NBline || n1>n2)
344 throw RangeCheckError("FitsABTColRead::Read TVector bad requested line range\n");
345
346 sa_size_t n = n2-n1+1;
347 if(data.Size()<n) data.SetSize(n);
348 // Il faut faire mieux mais comment ????
349 for(long i=n1;i<=n2;i++) data(i-n1) = Read(i);
350}
351
352/////////////////////////////////////////////////
353void FitsABTColRead::printerror(int sta) const
354{
355 int stat = sta;
356 fits_report_error(stdout,stat);
357 fflush(stdout);
358 return;
359}
360
361/*! Print on stream os */
362void FitsABTColRead::Print(ostream& os,int lp) const
363{
364 os<<"FitsABTColRead:Print ("<<BuffLen<<","<<BuffSens<<","<<NulVal<<")"
365 <<" ncols="<<NBcol<<" nrows="<<NBline;
366 if(lp>0) os<<" NRead="<<NFitsRead;
367 os<<"\n... "<<FitsFN<<"["<<IHdu<<"/"<<NHdu<<"]"
368 <<"\n... Label["<<ColNum<<"]="<<ColLabel
369 <<" TypeCode="<<ColTypeCode
370 <<" TUnit="<<ColTUnit<<" TForm="<<ColTForm
371 <<endl;
372}
Note: See TracBrowser for help on using the repository browser.