| [1654] | 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
 | 
|---|
| [1659] | 14 |   -- Exemple:
 | 
|---|
| [1654] | 15 |   FitsABTColRead fbt("myfits.fits","BoloMuv_28",0,1000,1,3);
 | 
|---|
 | 16 |   fbt.SetDebug(3);
 | 
|---|
 | 17 |   fbt.Print(3);
 | 
|---|
| [1659] | 18 |   // Read element by element
 | 
|---|
| [1654] | 19 |   for(long i=0;i<fbt.GetNbLine();i++) {
 | 
|---|
 | 20 |     double x = fbt.Read(i);
 | 
|---|
 | 21 |     if(i%lpmod==0) cout<<i<<": "<<x<<endl;
 | 
|---|
 | 22 |   }
 | 
|---|
| [1659] | 23 |   // Read into a vector
 | 
|---|
 | 24 |   TVector<double> data;
 | 
|---|
 | 25 |   long n = fbt.Read(32,50,data);
 | 
|---|
 | 26 |     cout<<"Number of values read: "<<n<<endl;
 | 
|---|
 | 27 |   data.ReSize(100);
 | 
|---|
 | 28 |   n = fbt.Read(10,-1,data);
 | 
|---|
 | 29 |     cout<<"Number of values read: "<<n<<endl;
 | 
|---|
| [1654] | 30 |   \endverbatim
 | 
|---|
 | 31 | */
 | 
|---|
 | 32 | 
 | 
|---|
 | 33 | //////////////////////////////////////////////////////////////
 | 
|---|
 | 34 | /*!
 | 
|---|
 | 35 |   Constructor.
 | 
|---|
| [1659] | 36 |   \param fname : FITS file name to be read
 | 
|---|
 | 37 |   \param collabel : label of the column to be read
 | 
|---|
 | 38 |   \param ihdu : number of the HDU where the column is.
 | 
|---|
 | 39 |   \param blen : read buffer length
 | 
|---|
 | 40 |   \param bsens : buffer reading direction
 | 
|---|
 | 41 |   \param lp : debug level
 | 
|---|
| [1654] | 42 |   \verbatim
 | 
|---|
| [1659] | 43 |   - if ihdu=0 or ihdu>nhdu first binary or ASCII table is taken
 | 
|---|
 | 44 |   - bsens>0    read forward
 | 
|---|
 | 45 |     bsens<0    read backward
 | 
|---|
 | 46 |     bsens==0   read centered
 | 
|---|
| [1654] | 47 |   \endverbatim
 | 
|---|
| [1659] | 48 |   \warning ihdu = [1,nhdu]
 | 
|---|
| [1654] | 49 | */
 | 
|---|
 | 50 | FitsABTColRead::FitsABTColRead(string fname,string collabel
 | 
|---|
 | 51 |                             ,int ihdu,long blen,long bsens,int lp)
 | 
|---|
 | 52 | {
 | 
|---|
 | 53 | Init(fname.c_str(),collabel.c_str(),-1,ihdu,blen,bsens,lp);
 | 
|---|
 | 54 | }
 | 
|---|
 | 55 | 
 | 
|---|
 | 56 | /*!
 | 
|---|
 | 57 |   Constructor.
 | 
|---|
| [1659] | 58 |   Same as before but the column is identified by its column number
 | 
|---|
 | 59 |   \param colnum : number of the column to be read
 | 
|---|
 | 60 |   \warning col = [0,ncol[
 | 
|---|
| [1654] | 61 | */
 | 
|---|
 | 62 | FitsABTColRead::FitsABTColRead(string fname,int colnum
 | 
|---|
 | 63 |                             ,int ihdu,long blen,long bsens,int lp)
 | 
|---|
 | 64 | {
 | 
|---|
 | 65 | Init(fname.c_str(),"",colnum,ihdu,blen,bsens,lp);
 | 
|---|
 | 66 | }
 | 
|---|
 | 67 | 
 | 
|---|
 | 68 | /*! Constructor. see below */
 | 
|---|
 | 69 | FitsABTColRead::FitsABTColRead(const char * cfname,const char* collabel
 | 
|---|
 | 70 |                             ,int ihdu,long blen,long bsens,int lp)
 | 
|---|
 | 71 | {
 | 
|---|
 | 72 | Init(cfname,collabel,-1,ihdu,blen,bsens,lp);
 | 
|---|
 | 73 | }
 | 
|---|
 | 74 | 
 | 
|---|
 | 75 | /*! Constructor. see below */
 | 
|---|
 | 76 | FitsABTColRead::FitsABTColRead(const char * cfname,int colnum
 | 
|---|
 | 77 |                             ,int ihdu,long blen,long bsens,int lp)
 | 
|---|
 | 78 | {
 | 
|---|
 | 79 | Init(cfname,"",colnum,ihdu,blen,bsens,lp);
 | 
|---|
 | 80 | }
 | 
|---|
 | 81 | 
 | 
|---|
 | 82 | /*! Constructor by copy */
 | 
|---|
 | 83 | FitsABTColRead::FitsABTColRead(FitsABTColRead& fbt)
 | 
|---|
 | 84 | {
 | 
|---|
 | 85 | Init(fbt.GetFileName().c_str(),fbt.GetColLabel().c_str()
 | 
|---|
 | 86 |     ,fbt.GetColNum(),fbt.GetHDU()
 | 
|---|
 | 87 |     ,fbt.GetBLen(),fbt.GetBSens(),fbt.DbgLevel);
 | 
|---|
 | 88 | }
 | 
|---|
 | 89 | 
 | 
|---|
 | 90 | /*! Init routine called by the constructor */
 | 
|---|
 | 91 | void FitsABTColRead::Init(const char* fname,const char* collabel,int colnum
 | 
|---|
 | 92 |                         ,int ihdu,long blen,long bsens,int lp)
 | 
|---|
 | 93 | {
 | 
|---|
 | 94 |  // Parametres Generaux
 | 
|---|
 | 95 |  FitsFN = fname;
 | 
|---|
 | 96 |  ColLabel = collabel;
 | 
|---|
 | 97 |  ColTUnit = "";
 | 
|---|
 | 98 |  ColTForm = "";
 | 
|---|
 | 99 |  ColNum = colnum;
 | 
|---|
 | 100 |  ColTypeCode = 0;
 | 
|---|
 | 101 |  IHdu = ihdu;
 | 
|---|
 | 102 |  NHdu = 0;
 | 
|---|
 | 103 |  HduType = 0;
 | 
|---|
 | 104 |  NBcol = 0;
 | 
|---|
 | 105 |  NBline = 0;
 | 
|---|
 | 106 |  SetNulVal();
 | 
|---|
 | 107 |  SetDebug(lp);
 | 
|---|
 | 108 |  NFitsRead = 0;
 | 
|---|
 | 109 |  FitsPtr = NULL;
 | 
|---|
 | 110 |  LineDeb = LineFin = -1;
 | 
|---|
 | 111 |  Buffer = NULL;
 | 
|---|
| [1657] | 112 |  ChangeBuffer(blen,bsens);
 | 
|---|
| [1654] | 113 | 
 | 
|---|
 | 114 |  //////////////////////////
 | 
|---|
 | 115 |  // Ouverture du fichier //
 | 
|---|
 | 116 |  //////////////////////////
 | 
|---|
 | 117 | 
 | 
|---|
 | 118 |  int sta=0;
 | 
|---|
 | 119 |  if(FitsFN.size() <= 0 ) {
 | 
|---|
| [1657] | 120 |    IHdu = -1; Delete();
 | 
|---|
| [1654] | 121 |    throw ParmError("FitsABTColRead::Init: Fits file name error\n");
 | 
|---|
 | 122 |  }
 | 
|---|
 | 123 |  const char * cfitsfn = FitsFN.c_str();
 | 
|---|
 | 124 | 
 | 
|---|
 | 125 |  // Open fits
 | 
|---|
 | 126 |  if(fits_open_file(&FitsPtr,cfitsfn,READONLY,&sta)) {
 | 
|---|
 | 127 |    printerror(sta); Delete();
 | 
|---|
 | 128 |    throw NullPtrError("FitsABTColRead::Init: Error opening Fits file\n");
 | 
|---|
 | 129 |  }
 | 
|---|
 | 130 | 
 | 
|---|
 | 131 |  // Get number of hdu
 | 
|---|
 | 132 |  if(fits_get_num_hdus(FitsPtr,&NHdu,&sta)) {
 | 
|---|
 | 133 |    printerror(sta); Delete();
 | 
|---|
 | 134 |    throw NotAvailableOperation("FitsABTColRead::Init: Error getting NHdu\n");
 | 
|---|
 | 135 |  }
 | 
|---|
 | 136 |  if(DbgLevel>1) cout<<"FitsABTColRead::Init  NHdu="<<NHdu<<endl;
 | 
|---|
 | 137 |  if(NHdu<=0) {
 | 
|---|
 | 138 |    Delete();
 | 
|---|
 | 139 |    throw SzMismatchError("FitsABTColRead::Init: Bad NHdu\n");
 | 
|---|
 | 140 |  }
 | 
|---|
 | 141 | 
 | 
|---|
 | 142 |  // Get HDU for bin/ascii table
 | 
|---|
 | 143 |  // si IHdu <=0 || >NHdu on cherche la 1ere bin/ascii table
 | 
|---|
 | 144 |  // sinon on se positionne sur IHdu
 | 
|---|
 | 145 |  if(IHdu<=0 || IHdu>NHdu)
 | 
|---|
 | 146 |    for(int ihdu=1;ihdu<=NHdu;ihdu++) {
 | 
|---|
 | 147 |      if(fits_movabs_hdu(FitsPtr,ihdu,&HduType,&sta)) printerror(sta);
 | 
|---|
 | 148 |      if(DbgLevel>1) cout<<"...Init ihdu="
 | 
|---|
 | 149 |                         <<ihdu<<" HduType="<<HduType<<endl;
 | 
|---|
 | 150 |      if(HduType==BINARY_TBL || HduType==ASCII_TBL) {IHdu = ihdu; break;}
 | 
|---|
 | 151 |    }
 | 
|---|
 | 152 |  if(IHdu<=0 || IHdu>NHdu) {
 | 
|---|
 | 153 |    cout<<"NO BINARY or ASCII hdu found"<<endl;
 | 
|---|
| [1657] | 154 |    IHdu = 0; Delete();
 | 
|---|
| [1654] | 155 |    throw TypeMismatchExc("FitsABTColRead::Init: NO BINARY or ASCII hdu found\n");
 | 
|---|
 | 156 |  }
 | 
|---|
 | 157 |  if(fits_movabs_hdu(FitsPtr,IHdu,&HduType,&sta)) {
 | 
|---|
 | 158 |    printerror(sta); Delete();
 | 
|---|
 | 159 |    throw RangeCheckError("FitsABTColRead::Init: Error moving to requested HDU\n");
 | 
|---|
 | 160 |  }
 | 
|---|
 | 161 |  if(HduType!=BINARY_TBL && HduType!=ASCII_TBL) {
 | 
|---|
 | 162 |    Delete();
 | 
|---|
 | 163 |    throw TypeMismatchExc("FitsABTColRead::Init: HDU not ASCII/BINARY table\n");
 | 
|---|
 | 164 |  }
 | 
|---|
 | 165 | 
 | 
|---|
 | 166 |  // Get number of columns
 | 
|---|
 | 167 |  if(fits_get_num_cols(FitsPtr,&NBcol,&sta)) {
 | 
|---|
 | 168 |    printerror(sta); Delete();
 | 
|---|
 | 169 |    throw NotAvailableOperation("FitsABTColRead::Init: Error getting number of columns\n");
 | 
|---|
 | 170 |  }
 | 
|---|
 | 171 |  if(DbgLevel>1) cout<<"...Init  NBcol="<<NBcol<<endl;
 | 
|---|
 | 172 |  if(NBcol<1) {
 | 
|---|
 | 173 |    Delete();
 | 
|---|
 | 174 |    throw RangeCheckError("FitsABTColRead::Init: Bad number of colums\n");
 | 
|---|
 | 175 |  }
 | 
|---|
 | 176 | 
 | 
|---|
 | 177 |  // Get number of rows
 | 
|---|
 | 178 |  if(fits_get_num_rows(FitsPtr,&NBline,&sta)) {
 | 
|---|
 | 179 |    printerror(sta); Delete();
 | 
|---|
 | 180 |    throw NotAvailableOperation("FitsABTColRead::Init: Error getting number of rows\n");
 | 
|---|
 | 181 |  }
 | 
|---|
 | 182 |  if(DbgLevel>1) cout<<"...Init  NBline="<<NBline<<endl;
 | 
|---|
 | 183 |  if(NBline<1) {
 | 
|---|
 | 184 |    Delete();
 | 
|---|
 | 185 |    throw RangeCheckError("FitsABTColRead::Init: Bad number of rows\n");
 | 
|---|
 | 186 |  }
 | 
|---|
 | 187 | 
 | 
|---|
 | 188 |  // Get column number
 | 
|---|
| [1660] | 189 |  char labelcol[128];
 | 
|---|
| [1654] | 190 |  if(ColLabel.size() > 0) {
 | 
|---|
 | 191 |    strcpy(labelcol,ColLabel.c_str());
 | 
|---|
 | 192 |    if(fits_get_colnum(FitsPtr,CASESEN,labelcol,&ColNum,&sta)) {
 | 
|---|
 | 193 |      printerror(sta); Delete();
 | 
|---|
 | 194 |      throw NotAvailableOperation("FitsABTColRead::Init: Error getting column name\n");
 | 
|---|
 | 195 |    }
 | 
|---|
 | 196 |    ColNum--;  // Convention [0,ncol[
 | 
|---|
 | 197 |  }
 | 
|---|
 | 198 |  if(DbgLevel>1) cout<<"...Init  ColNum="<<ColNum<<endl;
 | 
|---|
 | 199 |  if(ColNum<0 || ColNum>=NBcol) {
 | 
|---|
 | 200 |    Delete();
 | 
|---|
 | 201 |    throw RangeCheckError("FitsABTColRead::Init: Bad column number\n");
 | 
|---|
 | 202 |  }
 | 
|---|
 | 203 | 
 | 
|---|
 | 204 |  // Get column type
 | 
|---|
 | 205 |  if(fits_get_coltype(FitsPtr,ColNum+1,&ColTypeCode,NULL,NULL,&sta)) {
 | 
|---|
 | 206 |    printerror(sta); Delete();
 | 
|---|
 | 207 |    throw ParmError("FitsABTColRead::Init: Error getting column type\n");
 | 
|---|
 | 208 |  }
 | 
|---|
 | 209 |  if(DbgLevel>1) cout<<"...Init ColTypeCode="<<ColTypeCode<<endl;
 | 
|---|
| [1660] | 210 |  if(ColTypeCode==TSTRING || ColTypeCode==TCOMPLEX ||  ColTypeCode==TDBLCOMPLEX
 | 
|---|
 | 211 |                          || ColTypeCode<0 ) {
 | 
|---|
| [1654] | 212 |    Delete();
 | 
|---|
 | 213 |    throw ParmError("FitsABTColRead::Init: Selected column is not Numerical\n");
 | 
|---|
 | 214 |  }
 | 
|---|
 | 215 | 
 | 
|---|
 | 216 |  // Get column name back, tunit, tform
 | 
|---|
| [2174] | 217 |  char tunit[64], tform[64], tdisp[64];
 | 
|---|
| [2173] | 218 |  long repeat=0; double tscale=1., tzero=0.;
 | 
|---|
| [1654] | 219 |  int rc=0;
 | 
|---|
 | 220 |  if(HduType==BINARY_TBL) {
 | 
|---|
| [2173] | 221 |    fits_get_bcolparms(FitsPtr,ColNum+1,labelcol,tunit,tform
 | 
|---|
| [2174] | 222 |                      ,&repeat,&tscale,&tzero,NULL,tdisp,&sta);
 | 
|---|
| [1654] | 223 |  } else {
 | 
|---|
| [2173] | 224 |    fits_get_acolparms(FitsPtr,ColNum+1,labelcol,&repeat,tunit,tform
 | 
|---|
| [2174] | 225 |                      ,&tscale,&tzero,NULL,tdisp,&sta);
 | 
|---|
| [1654] | 226 |  }
 | 
|---|
 | 227 |  if(rc) {
 | 
|---|
 | 228 |    printerror(sta); Delete();
 | 
|---|
 | 229 |    throw RangeCheckError("FitsABTColRead::Init: Error getting the column caracteristics\n");
 | 
|---|
 | 230 |  }
 | 
|---|
 | 231 |  ColLabel = labelcol;
 | 
|---|
 | 232 |  ColTUnit = tunit;
 | 
|---|
 | 233 |  ColTForm = tform;
 | 
|---|
 | 234 | 
 | 
|---|
 | 235 |  if(DbgLevel)
 | 
|---|
 | 236 |    cout<<"FitsABTColRead::Init Num="<<ColNum<<" Label="<<ColLabel
 | 
|---|
| [2173] | 237 |        <<" TypeCode="<<ColTypeCode<<" TUnit="<<ColTUnit<<" TForm="<<ColTForm<<endl;
 | 
|---|
 | 238 |  if(DbgLevel>1)
 | 
|---|
| [2174] | 239 |    cout<<"      (repeat="<<repeat<<",tscale="<<tscale<<",tzero="<<tzero
 | 
|---|
 | 240 |        <<",tdisp="<<tdisp<<")"<<endl;
 | 
|---|
| [1654] | 241 | 
 | 
|---|
 | 242 | }
 | 
|---|
 | 243 | 
 | 
|---|
 | 244 | /*! Destructor. */
 | 
|---|
 | 245 | FitsABTColRead::~FitsABTColRead()
 | 
|---|
 | 246 | {
 | 
|---|
 | 247 |  Delete();
 | 
|---|
 | 248 | }
 | 
|---|
 | 249 | 
 | 
|---|
| [1814] | 250 | //////////////////////////////////////////////////////////////
 | 
|---|
 | 251 | double FitsABTColRead::ReadKey(char *keyname)
 | 
|---|
 | 252 | {
 | 
|---|
 | 253 |  if(keyname==NULL) return 0.;
 | 
|---|
| [2087] | 254 |  int sta=0; double val=0.;
 | 
|---|
| [1814] | 255 |  if(fits_read_key(FitsPtr,TDOUBLE,keyname,&val,NULL,&sta))
 | 
|---|
 | 256 |    printerror(sta);
 | 
|---|
 | 257 |  return val;
 | 
|---|
 | 258 | }
 | 
|---|
| [1654] | 259 | 
 | 
|---|
 | 260 | //////////////////////////////////////////////////////////////
 | 
|---|
| [1659] | 261 | /*! Change the buffer caracteristiques (see creator) */
 | 
|---|
| [1654] | 262 | void FitsABTColRead::ChangeBuffer(long blen,long bsens)
 | 
|---|
 | 263 | {
 | 
|---|
| [1657] | 264 |  long oldnbuffer = NBuffer;
 | 
|---|
 | 265 | 
 | 
|---|
 | 266 |  // Compute buffer caracteristics
 | 
|---|
| [1654] | 267 |  BuffLen = (blen<=0)? 1: blen;
 | 
|---|
 | 268 |  BuffSens = bsens;
 | 
|---|
| [1657] | 269 |  NBuffer = BuffLen;
 | 
|---|
 | 270 |  if(bsens==0 && NBuffer%2==0) NBuffer++;
 | 
|---|
| [1654] | 271 | 
 | 
|---|
| [1657] | 272 |  // De-allocate if necessary
 | 
|---|
| [1659] | 273 |  if(Buffer!=NULL) {
 | 
|---|
 | 274 |    // On des-alloue si pas assez de place
 | 
|---|
 | 275 |    // ou si l'ancienne place est beaucoup trop grande (>25%)
 | 
|---|
 | 276 |    if(oldnbuffer<NBuffer || (oldnbuffer>NBuffer+long(0.25*NBuffer)) )
 | 
|---|
 | 277 |      {delete [] Buffer; Buffer=NULL;}
 | 
|---|
 | 278 |  }
 | 
|---|
| [1654] | 279 | 
 | 
|---|
| [1657] | 280 |  // Re-allocate
 | 
|---|
 | 281 |  if(Buffer==NULL) Buffer = new double[NBuffer];
 | 
|---|
 | 282 | 
 | 
|---|
| [1654] | 283 |  // Tell program that nothing is into buffer
 | 
|---|
 | 284 |  LineDeb = LineFin = -1;
 | 
|---|
 | 285 | }
 | 
|---|
 | 286 | 
 | 
|---|
 | 287 | /*! Delete called by the destructor */
 | 
|---|
 | 288 | void FitsABTColRead::Delete()
 | 
|---|
 | 289 | {
 | 
|---|
| [1657] | 290 |  if(Buffer!=NULL) {delete [] Buffer; Buffer=NULL;}
 | 
|---|
| [1654] | 291 |  LineDeb = LineFin = -1;
 | 
|---|
 | 292 |  int sta = 0;
 | 
|---|
 | 293 |  if(fits_close_file(FitsPtr,&sta)) printerror(sta);
 | 
|---|
 | 294 |  FitsPtr = NULL;
 | 
|---|
 | 295 | }
 | 
|---|
 | 296 | 
 | 
|---|
 | 297 | /////////////////////////////////////////////////
 | 
|---|
 | 298 | /*!
 | 
|---|
| [1659] | 299 |   Read row "n" and return the value into a double
 | 
|---|
 | 300 |   \warning be carefull for the range: row = [0,NRows[
 | 
|---|
 | 301 |   \return value in double
 | 
|---|
 | 302 |   \param n : number of the row to be read.
 | 
|---|
| [1654] | 303 |   \verbatim
 | 
|---|
| [1659] | 304 |   usebuffer == true  : use read optimisation with bufferisation
 | 
|---|
 | 305 |             == false : no optimisation with bufferisation
 | 
|---|
 | 306 |                        just read one value
 | 
|---|
| [1654] | 307 |   \endverbatim
 | 
|---|
 | 308 | */
 | 
|---|
| [1659] | 309 | double FitsABTColRead::Read(long n,bool usebuffer)
 | 
|---|
| [1654] | 310 | // Attention: n=nline [0,NBline[, cfistio veut [1,NBline]
 | 
|---|
 | 311 | // Attention: colnum  [0,NBcol[ , cfistio veut [1,NBcol]
 | 
|---|
 | 312 | {
 | 
|---|
| [1659] | 313 |  int sta=0;
 | 
|---|
| [1654] | 314 |  if(n<0 || n>=NBline)
 | 
|---|
 | 315 |    throw RangeCheckError("FitsABTColRead::Read try to read outside line range\n");
 | 
|---|
 | 316 | 
 | 
|---|
 | 317 |  // Pas de bufferisation, on lit betement
 | 
|---|
| [1659] | 318 |  if(NBuffer==1 || !usebuffer) {
 | 
|---|
| [1654] | 319 |    NFitsRead++;
 | 
|---|
| [1659] | 320 |    double val;
 | 
|---|
 | 321 |    fits_read_col(FitsPtr,TDOUBLE,ColNum+1,n+1,1,1,NULL,&val,NULL,&sta);
 | 
|---|
| [1654] | 322 |    if(sta) {
 | 
|---|
 | 323 |      printerror(sta);
 | 
|---|
 | 324 |      throw NotAvailableOperation("FitsABTColRead::Read: Error Reading Fits file\n");
 | 
|---|
 | 325 |    }
 | 
|---|
| [1659] | 326 |    // On ne remplit Buffer[0] que si on a choisit
 | 
|---|
 | 327 |    // un mode de lecture non bufferise (n==1) DES LE DEBUT.
 | 
|---|
 | 328 |    // Si on a initialement choisit un mode bufferise (avec n>1),
 | 
|---|
 | 329 |    // Buffer contient les valeurs chargees auparavent.
 | 
|---|
 | 330 |    // Il ne faut pas faire {Buffer[0]=val; LineDeb=LineFin=n;}
 | 
|---|
 | 331 |    // car on perd l'info de ces valeurs.
 | 
|---|
 | 332 |    if(NBuffer==1) {Buffer[0]=val; LineDeb=LineFin=n;}
 | 
|---|
 | 333 |    return val;
 | 
|---|
| [1654] | 334 |  }
 | 
|---|
 | 335 | 
 | 
|---|
 | 336 |  // Gestion avec bufferisation
 | 
|---|
| [1659] | 337 |  if(!Buffer)
 | 
|---|
 | 338 |    throw RangeCheckError("FitsABTColRead::Read: Buffer not allocated\n");
 | 
|---|
| [1654] | 339 |  if(n<LineDeb || n>LineFin) {
 | 
|---|
 | 340 |    NFitsRead++;
 | 
|---|
 | 341 |    long row1,row2,nrow;
 | 
|---|
 | 342 |    if(BuffSens>0) { // Cas remplissage forward
 | 
|---|
 | 343 |      row1 = n+1;
 | 
|---|
| [1657] | 344 |      row2 = row1+NBuffer-1; if(row2>NBline) row2 = NBline;
 | 
|---|
| [1654] | 345 |    } else if(BuffSens<0) { // Cas remplissage backward
 | 
|---|
 | 346 |      row2 = n+1;
 | 
|---|
| [1657] | 347 |      row1 = row2-NBuffer+1; if(row1<1) row1 = 1;
 | 
|---|
| [1654] | 348 |    } else { // Cas remplissage centre
 | 
|---|
| [1657] | 349 |      row1 = n+1 - NBuffer/2; if(row1<1) row1 = 1;
 | 
|---|
 | 350 |      row2 = n+1 + NBuffer/2; if(row2>NBline) row2 = NBline;
 | 
|---|
| [1654] | 351 |    }
 | 
|---|
 | 352 |    nrow = row2 - row1 + 1;
 | 
|---|
 | 353 |    LineDeb = row1-1; LineFin = row2-1;
 | 
|---|
 | 354 |    //cout<<"DBG-FitsRead: row1="<<row1<<" row2="<<row2<<" nrow="<<nrow
 | 
|---|
 | 355 |    //    <<" LineDeb,Fin="<<LineDeb<<","<<LineFin<<endl;
 | 
|---|
| [1659] | 356 |    fits_read_col(FitsPtr,TDOUBLE,ColNum+1,row1,1,nrow,NULL,Buffer,NULL,&sta);
 | 
|---|
| [1654] | 357 |    if(sta) {
 | 
|---|
 | 358 |      printerror(sta);
 | 
|---|
 | 359 |      LineDeb = LineFin = -1;
 | 
|---|
 | 360 |      throw NotAvailableOperation("FitsABTColRead::Read: Error Reading Fits file\n");
 | 
|---|
 | 361 |    }
 | 
|---|
 | 362 |  }
 | 
|---|
 | 363 | 
 | 
|---|
 | 364 |  long ibuf = n-LineDeb;
 | 
|---|
 | 365 |  return Buffer[ibuf];
 | 
|---|
 | 366 | }
 | 
|---|
 | 367 | 
 | 
|---|
 | 368 | /*!
 | 
|---|
| [1659] | 369 |   Read rows from "n1" to "n2" and return the values into TVector of double
 | 
|---|
 | 370 |   \return NREAD the number of values read (n2-n1+1).
 | 
|---|
 | 371 |   \warning row = [0,NRows[, the routine read [n1,n2]
 | 
|---|
| [1654] | 372 |   \verbatim
 | 
|---|
| [1659] | 373 |   - if n2<0 then read [n1,n2] where "n2=min(n1+vector_size-1,nrows-1)"
 | 
|---|
 | 374 |   - Last row read is ALWAYS: "n2 = n1 + NREAD -1"
 | 
|---|
 | 375 |   - The TVector is never resized if not necessary
 | 
|---|
 | 376 |   -------------------------------------------------------------------------
 | 
|---|
 | 377 |   - ex: suppose the column table contains 10 elements: nrows=10, rows=[0,9]
 | 
|---|
 | 378 | 
 | 
|---|
 | 379 |     TVector<double> V(5);
 | 
|---|
 | 380 |       bt.Read(3,5,V)  -> read rows=3,4,5     -> V.Size()==5 -> return 3
 | 
|---|
 | 381 |       bt.Read(3,-1,V) -> read rows=3,4,5,6,7 -> V.Size()==5 -> return 5
 | 
|---|
 | 382 |       bt.Read(7,-1,V) -> read rows=7,8,9     -> V.Size()==5 -> return 3
 | 
|---|
 | 383 |       bt.Read(2,-1,V) -> read rows=2,3,4,5,6 -> V.Size()==5 -> return 5
 | 
|---|
 | 384 |       bt.Read(-1,5,V) -> throw exception
 | 
|---|
 | 385 | 
 | 
|---|
 | 386 |     TVector<double> V(5);
 | 
|---|
 | 387 |       bt.Read(3,99,V) -> read rows=3,4,5,6,7,8,9 -> V.Size()==7 -> return 7
 | 
|---|
 | 388 | 
 | 
|---|
 | 389 |     TVector<double> V(5);
 | 
|---|
 | 390 |       bt.Read(2,8,V)  -> read rows=2,3,4,5,6,7,8 -> V.Size()==7 -> return 7
 | 
|---|
 | 391 | 
 | 
|---|
 | 392 |     TVector<double> V;
 | 
|---|
 | 393 |       bt.Read(3,5,V)  -> read rows=3,4,5 -> V.Size()==3 -> return 3
 | 
|---|
 | 394 | 
 | 
|---|
 | 395 |     TVector<double> V;
 | 
|---|
 | 396 |       bt.Read(3,-1,V) -> throw exception
 | 
|---|
 | 397 |   -------------------------------------------------------------------------
 | 
|---|
| [1654] | 398 |   \endverbatim
 | 
|---|
 | 399 | */
 | 
|---|
| [1659] | 400 | long FitsABTColRead::Read(long n1,long n2,TVector<double>& data)
 | 
|---|
| [1654] | 401 | {
 | 
|---|
| [1659] | 402 |  if(n1<0 || n1>=NBline)
 | 
|---|
 | 403 |    throw RangeCheckError("FitsABTColRead::Read TVector bad requested 1srt line \n");
 | 
|---|
 | 404 |  if(data.Size()<=0 && n2<n1)
 | 
|---|
 | 405 |    throw RangeCheckError("FitsABTColRead::Read TVector bad requested 2sd line \n");
 | 
|---|
 | 406 |  if(n2<0) n2 = n1 + data.Size()-1;
 | 
|---|
 | 407 |  if(n2>=NBline) n2 = NBline-1;
 | 
|---|
| [1654] | 408 | 
 | 
|---|
| [1659] | 409 |  sa_size_t nread = n2-n1+1;
 | 
|---|
 | 410 |  if(data.Size()<nread) data.SetSize(nread);
 | 
|---|
 | 411 | 
 | 
|---|
 | 412 |  //for(long i=n1;i<=n2;i++) data(i-n1) = Read(i);
 | 
|---|
 | 413 |  int sta=0;
 | 
|---|
 | 414 |  fits_read_col(FitsPtr,TDOUBLE,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
 | 
|---|
 | 415 |  if(sta) {
 | 
|---|
 | 416 |    printerror(sta);
 | 
|---|
 | 417 |    throw NotAvailableOperation("FitsABTColRead::Read_TVector<double>: Error Reading Fits file\n");
 | 
|---|
 | 418 |  }
 | 
|---|
 | 419 | 
 | 
|---|
 | 420 |  return nread;
 | 
|---|
| [1654] | 421 | }
 | 
|---|
 | 422 | 
 | 
|---|
| [1659] | 423 | /*! idem before but for TVector of float */
 | 
|---|
 | 424 | long FitsABTColRead::Read(long n1,long n2,TVector<float>& data)
 | 
|---|
 | 425 | {
 | 
|---|
 | 426 |  if(n1<0 || n1>=NBline)
 | 
|---|
 | 427 |    throw RangeCheckError("FitsABTColRead::Read TVector bad requested 1srt line \n");
 | 
|---|
 | 428 |  if(data.Size()<=0 && n2<n1)
 | 
|---|
 | 429 |    throw RangeCheckError("FitsABTColRead::Read TVector bad requested 2sd line \n");
 | 
|---|
 | 430 |  if(n2<0) n2 = n1 + data.Size()-1;
 | 
|---|
 | 431 |  if(n2>=NBline) n2 = NBline-1;
 | 
|---|
 | 432 | 
 | 
|---|
 | 433 |  sa_size_t nread = n2-n1+1;
 | 
|---|
 | 434 |  if(data.Size()<nread) data.SetSize(nread);
 | 
|---|
 | 435 | 
 | 
|---|
 | 436 |  //for(long i=n1;i<=n2;i++) data(i-n1) = Read(i);
 | 
|---|
 | 437 |  int sta=0;
 | 
|---|
 | 438 |  fits_read_col(FitsPtr,TFLOAT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
 | 
|---|
 | 439 |  if(sta) {
 | 
|---|
 | 440 |    printerror(sta);
 | 
|---|
 | 441 |    throw NotAvailableOperation("FitsABTColRead::Read_TVector<float>: Error Reading Fits file\n");
 | 
|---|
 | 442 |  }
 | 
|---|
 | 443 | 
 | 
|---|
 | 444 |  return nread;
 | 
|---|
 | 445 | }
 | 
|---|
 | 446 | 
 | 
|---|
| [2170] | 447 | /*! idem before but for TVector of unsigned short */
 | 
|---|
 | 448 | long FitsABTColRead::Read(long n1,long n2,TVector<uint_2>& data)
 | 
|---|
 | 449 | {
 | 
|---|
 | 450 |  if(n1<0 || n1>=NBline)
 | 
|---|
 | 451 |    throw RangeCheckError("FitsABTColRead::Read TVector bad requested 1srt line \n");
 | 
|---|
 | 452 |  if(data.Size()<=0 && n2<n1)
 | 
|---|
 | 453 |    throw RangeCheckError("FitsABTColRead::Read TVector bad requested 2sd line \n");
 | 
|---|
 | 454 |  if(n2<0) n2 = n1 + data.Size()-1;
 | 
|---|
 | 455 |  if(n2>=NBline) n2 = NBline-1;
 | 
|---|
 | 456 | 
 | 
|---|
 | 457 |  sa_size_t nread = n2-n1+1;
 | 
|---|
 | 458 |  if(data.Size()<nread) data.SetSize(nread);
 | 
|---|
 | 459 | 
 | 
|---|
 | 460 |  int sta=0;
 | 
|---|
 | 461 |  fits_read_col(FitsPtr,TUSHORT,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
 | 
|---|
 | 462 |  if(sta) {
 | 
|---|
 | 463 |    printerror(sta);
 | 
|---|
 | 464 |    throw NotAvailableOperation("FitsABTColRead::Read_TVector<uint_2>: Error Reading Fits file\n");
 | 
|---|
 | 465 |  }
 | 
|---|
 | 466 | 
 | 
|---|
 | 467 |  return nread;
 | 
|---|
 | 468 | }
 | 
|---|
 | 469 | 
 | 
|---|
| [1659] | 470 | /*! idem before but for TVector of int_4 */
 | 
|---|
 | 471 | long FitsABTColRead::Read(long n1,long n2,TVector<int_4>& data)
 | 
|---|
 | 472 | {
 | 
|---|
 | 473 |  if(n1<0 || n1>=NBline)
 | 
|---|
 | 474 |    throw RangeCheckError("FitsABTColRead::Read TVector bad requested 1srt line \n");
 | 
|---|
 | 475 |  if(data.Size()<=0 && n2<n1)
 | 
|---|
 | 476 |    throw RangeCheckError("FitsABTColRead::Read TVector bad requested 2sd line \n");
 | 
|---|
 | 477 |  if(n2<0) n2 = n1 + data.Size()-1;
 | 
|---|
 | 478 |  if(n2>=NBline) n2 = NBline-1;
 | 
|---|
 | 479 | 
 | 
|---|
 | 480 |  sa_size_t nread = n2-n1+1;
 | 
|---|
 | 481 |  if(data.Size()<nread) data.SetSize(nread);
 | 
|---|
 | 482 | 
 | 
|---|
 | 483 |  //for(long i=n1;i<=n2;i++) data(i-n1) = Read(i);
 | 
|---|
 | 484 |  int sta=0;
 | 
|---|
 | 485 |  int T = (sizeof(long)==4) ? TLONG: TINT;
 | 
|---|
 | 486 |  fits_read_col(FitsPtr,T,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
 | 
|---|
 | 487 |  if(sta) {
 | 
|---|
 | 488 |    printerror(sta);
 | 
|---|
| [2170] | 489 |    throw NotAvailableOperation("FitsABTColRead::Read_TVector<int_4>: Error Reading Fits file\n");
 | 
|---|
| [1659] | 490 |  }
 | 
|---|
 | 491 | 
 | 
|---|
 | 492 |  return nread;
 | 
|---|
 | 493 | }
 | 
|---|
 | 494 | 
 | 
|---|
| [2169] | 495 | /*! idem before but for TVector of int_8 */
 | 
|---|
 | 496 | long FitsABTColRead::Read(long n1,long n2,TVector<int_8>& data)
 | 
|---|
 | 497 | {
 | 
|---|
 | 498 | #ifdef TLONGLONG
 | 
|---|
 | 499 |  if(n1<0 || n1>=NBline)
 | 
|---|
 | 500 |    throw RangeCheckError("FitsABTColRead::Read TVector bad requested 1srt line \n");
 | 
|---|
 | 501 |  if(data.Size()<=0 && n2<n1)
 | 
|---|
 | 502 |    throw RangeCheckError("FitsABTColRead::Read TVector bad requested 2sd line \n");
 | 
|---|
 | 503 |  if(n2<0) n2 = n1 + data.Size()-1;
 | 
|---|
 | 504 |  if(n2>=NBline) n2 = NBline-1;
 | 
|---|
 | 505 | 
 | 
|---|
 | 506 |  sa_size_t nread = n2-n1+1;
 | 
|---|
 | 507 |  if(data.Size()<nread) data.SetSize(nread);
 | 
|---|
 | 508 | 
 | 
|---|
 | 509 |  int sta=0;
 | 
|---|
 | 510 |  fits_read_col(FitsPtr,TLONGLONG,ColNum+1,n1+1,1,nread,NULL,data.Data(),NULL,&sta);
 | 
|---|
 | 511 |  if(sta) {
 | 
|---|
 | 512 |    printerror(sta);
 | 
|---|
| [2170] | 513 |    throw NotAvailableOperation("FitsABTColRead::Read_TVector<int_8>: Error Reading Fits file\n");
 | 
|---|
| [2169] | 514 |  }
 | 
|---|
 | 515 | 
 | 
|---|
 | 516 |  return nread;
 | 
|---|
 | 517 | #else
 | 
|---|
 | 518 |   throw PException("FitsABTColRead::Read(..,TVector<int_8>&) Not in that cfitsio version");
 | 
|---|
 | 519 | #endif
 | 
|---|
 | 520 | }
 | 
|---|
 | 521 | 
 | 
|---|
| [1654] | 522 | /////////////////////////////////////////////////
 | 
|---|
| [1659] | 523 | /*!
 | 
|---|
 | 524 |   Return the number of the first row where "val1"<=val<="val2" starting at row "rowstart"
 | 
|---|
 | 525 |   \verbatim
 | 
|---|
 | 526 |   - The search is performed from "rowstart" to the end
 | 
|---|
 | 527 |       in ascending order (from "rowstart" to nrows).
 | 
|---|
 | 528 |   - Warning: "rowstart<0" means "rowstart==0" (search all the table column)
 | 
|---|
 | 529 |              That is the default
 | 
|---|
 | 530 |   \endverbatim
 | 
|---|
 | 531 |   \return <0 means not found
 | 
|---|
 | 532 | */
 | 
|---|
 | 533 | long FitsABTColRead::FirstRow(double val1,double val2,long rowstart)
 | 
|---|
 | 534 | {
 | 
|---|
 | 535 |  long row = -1;
 | 
|---|
 | 536 |  if(NBline==0) return row;
 | 
|---|
 | 537 |  // Change buffer for efficiency
 | 
|---|
 | 538 |  long bsens=BuffSens; bool bchange=false;
 | 
|---|
 | 539 |  if(bsens<=0) {ChangeBuffer(BuffLen,1); bchange=true;}
 | 
|---|
 | 540 |  if(rowstart<0) rowstart = 0;
 | 
|---|
 | 541 |  if(rowstart>=NBline) rowstart = NBline-1;
 | 
|---|
 | 542 |  for(long i=rowstart;i<NBline;i++) {
 | 
|---|
 | 543 |    double val = Read(i);
 | 
|---|
 | 544 |    if(val<val1 || val>val2) continue;
 | 
|---|
 | 545 |    row = i;
 | 
|---|
 | 546 |    break;
 | 
|---|
 | 547 |  }
 | 
|---|
 | 548 |  if(bchange) ChangeBuffer(BuffLen,bsens);
 | 
|---|
 | 549 |  return row;
 | 
|---|
 | 550 | }
 | 
|---|
 | 551 | 
 | 
|---|
 | 552 | /*!
 | 
|---|
 | 553 |   Return the number of the first row where val1<=val<=val2 starting at row rowstart
 | 
|---|
 | 554 |   \return <0 means not found
 | 
|---|
 | 555 |   \verbatim
 | 
|---|
 | 556 |   - The search is performed from "rowstart" to the beginning
 | 
|---|
 | 557 |       in descending order (from "rowstart" to 0).
 | 
|---|
 | 558 |   - Warning: "rowstart<0" means "rowstart==nrows-1" (search all the table column)
 | 
|---|
 | 559 |              That is the default
 | 
|---|
 | 560 |   \endverbatim
 | 
|---|
 | 561 | */
 | 
|---|
 | 562 | long FitsABTColRead::LastRow(double val1,double val2,long rowstart)
 | 
|---|
 | 563 | {
 | 
|---|
 | 564 |  long row = -1;
 | 
|---|
 | 565 |  if(NBline==0) return row;
 | 
|---|
 | 566 |  // Change buffer for efficiency
 | 
|---|
 | 567 |  long bsens=BuffSens; bool bchange=false;
 | 
|---|
 | 568 |  if(bsens>=0) {ChangeBuffer(BuffLen,-1); bchange=true;}
 | 
|---|
 | 569 |  if(rowstart<0 || rowstart>=NBline) rowstart = NBline-1;
 | 
|---|
 | 570 |  for(long i=rowstart;i>=0;i--) {
 | 
|---|
 | 571 |    double val = Read(i);
 | 
|---|
 | 572 |    if(val<val1 || val>val2) continue;
 | 
|---|
 | 573 |    row = i;
 | 
|---|
 | 574 |    break;
 | 
|---|
 | 575 |  }
 | 
|---|
 | 576 |  if(bchange) ChangeBuffer(BuffLen,bsens);
 | 
|---|
 | 577 |  return row;
 | 
|---|
 | 578 | }
 | 
|---|
 | 579 | 
 | 
|---|
 | 580 | /////////////////////////////////////////////////
 | 
|---|
| [1654] | 581 | void FitsABTColRead::printerror(int sta) const
 | 
|---|
 | 582 | {
 | 
|---|
 | 583 |  int stat = sta;
 | 
|---|
 | 584 |  fits_report_error(stdout,stat);
 | 
|---|
 | 585 |  fflush(stdout);
 | 
|---|
 | 586 |  return;
 | 
|---|
 | 587 | }
 | 
|---|
 | 588 | 
 | 
|---|
 | 589 | /*! Print on stream os */
 | 
|---|
 | 590 | void FitsABTColRead::Print(ostream& os,int lp) const
 | 
|---|
 | 591 | {
 | 
|---|
 | 592 |  os<<"FitsABTColRead:Print ("<<BuffLen<<","<<BuffSens<<","<<NulVal<<")"
 | 
|---|
 | 593 |    <<" ncols="<<NBcol<<" nrows="<<NBline;
 | 
|---|
 | 594 |  if(lp>0) os<<" NRead="<<NFitsRead;
 | 
|---|
 | 595 |  os<<"\n... "<<FitsFN<<"["<<IHdu<<"/"<<NHdu<<"]"
 | 
|---|
 | 596 |    <<"\n... Label["<<ColNum<<"]="<<ColLabel
 | 
|---|
 | 597 |    <<" TypeCode="<<ColTypeCode
 | 
|---|
 | 598 |    <<" TUnit="<<ColTUnit<<" TForm="<<ColTForm
 | 
|---|
 | 599 |    <<endl;
 | 
|---|
 | 600 | }
 | 
|---|