source: trunk/src/Outputs/columns.cc @ 1061

Last change on this file since 1061 was 1061, checked in by MatthewWhiting, 12 years ago

Ticket #162 - A large refactoring of the Column-related code. Columns have moved to Outputs, and in a new namespace Catalogues. The interface has changed, using strings to record the type rather
than the enum. Also included is a new class CatalogueSpecification?, that is designed to hold a collection of Columns. This is not yet implemented - everything still uses the full & log column
vectors, and the code still passes the verification script.

File size: 33.2 KB
Line 
1// -----------------------------------------------------------------------
2// columns.cc: Define a set of columns for Duchamp output.
3// -----------------------------------------------------------------------
4// Copyright (C) 2006, Matthew Whiting, ATNF
5//
6// This program is free software; you can redistribute it and/or modify it
7// under the terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 2 of the License, or (at your
9// option) any later version.
10//
11// Duchamp is distributed in the hope that it will be useful, but WITHOUT
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14// for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with Duchamp; if not, write to the Free Software Foundation,
18// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
19//
20// Correspondence concerning Duchamp may be directed to:
21//    Internet email: Matthew.Whiting [at] atnf.csiro.au
22//    Postal address: Dr. Matthew Whiting
23//                    Australia Telescope National Facility, CSIRO
24//                    PO Box 76
25//                    Epping NSW 1710
26//                    AUSTRALIA
27// -----------------------------------------------------------------------
28#include <iostream>
29#include <sstream>
30
31#include <math.h>
32#include <duchamp/duchamp.hh>
33#include <duchamp/fitsHeader.hh>
34#include <vector>
35#include <string>
36#include <duchamp/Detection/detection.hh>
37#include <duchamp/Outputs/columns.hh>
38
39namespace duchamp
40{
41
42  namespace Catalogues
43  {
44
45
46    Column::Column()
47    {
48      /// @brief Set the default values for the parameters.
49      this->itsWidth=1;
50      this->itsPrecision=0;
51      this->itsName=" ";
52      this->itsUnits=" ";
53      this->itsType="";
54      this->itsUCD = "";
55      this->itsDatatype = "";
56      this->itsExtraInfo="";
57      this->itsColID="";
58    }
59
60    Column::Column(std::string type)
61    {
62      operator=(defaultColumn(type));
63    }
64
65    Column::Column(const Column& c)
66    {
67      operator=(c);
68    }
69
70    Column& Column::operator=(const Column& c)
71    {
72      if(this==&c) return *this;
73      this->itsWidth = c.itsWidth;
74      this->itsPrecision = c.itsPrecision;
75      this->itsName = c.itsName;
76      this->itsUnits = c.itsUnits;
77      this->itsUCD = c.itsUCD;
78      this->itsDatatype = c.itsDatatype;
79      this->itsExtraInfo = c.itsExtraInfo;
80      this->itsColID = c.itsColID;
81      this->itsType = c.itsType;
82      return *this;
83    }
84
85    // Col::Col(int num, int prec)
86    // {
87    //   /// A specialised constructor that defines one of the default
88    //   ///  columns, as defined in the Column namespace
89    //   /// \param num The number of the column to be constructed.
90    //   ///            Corresponds to the order of the columns in the const
91    //   ///            arrays in the Column namespace.
92    //   /// \param prec The precision to use, if not the default. A value
93    //   /// <0 or no value given results in the default being used.
94
95    //   if((num>=0)&&(num<numColumns)){
96    //  this->width     = defaultWidth[num];
97    //  if(prec<0) this->precision = defaultPrec[num];
98    //  else this->precision = prec;
99    //  this->name      = defaultName[num];
100    //  this->units     = defaultUnits[num];
101    //  this->type = COLNAME(num);
102    //  this->UCD = defaultUCDs[num];
103    //  this->datatype = defaultDatatype[num];
104    //  this->extraInfo = defaultExtraInfo[num];
105    //  this->colID = defaultColID[num];
106    //   }
107    //   else{
108    //  DUCHAMPERROR("Column constructor", "Incorrect value for Col(num) --> num="<<num << ", should be between 0 and " << numColumns-1);
109    //  this->width = 1;
110    //  this->precision = 0;
111    //  this->name = " ";
112    //  this->units = " ";
113    //  this->type=UNKNOWN;
114    //  this->UCD="";
115    //  this->datatype="";
116    //  this->extraInfo="";
117    //  this->colID="";
118    //   }
119    // }
120
121    // Col::Col(std::string name, std::string units, int width, int prec, std::string ucd, std::string datatype, std::string extraInfo):
122    //   width(width), precision(prec), name(name), units(units), UCD(ucd), datatype(datatype), extraInfo(extraInfo)
123    // {
124    //   /// A generic constructor designed to make a Column other than
125    //   /// the predefined ones listed in the Column namespace
126    //   /// \param name The title of the column
127    //   /// \param units What units the column takes
128    //   /// \param width The starting width
129    //   /// \param prec The starting precision
130
131    //   // this->width = width;
132    //   // this->precision = prec;
133    //   // this->name = name;
134    //   // this->units = units;
135    //   this->type = UNKNOWN;
136    // }
137
138    Column::Column(std::string type, std::string name, std::string units, int width, int prec, std::string ucd, std::string datatype, std::string extraInfo):
139      itsType(type),itsWidth(width), itsPrecision(prec), itsName(name), itsUnits(units), itsUCD(ucd), itsDatatype(datatype), itsExtraInfo(extraInfo)
140    {
141      /// A generic constructor designed to make a Column other than
142      /// the predefined ones listed in the Column namespace
143      /// \param name The title of the column
144      /// \param units What units the column takes
145      /// \param width The starting width
146      /// \param prec The starting precision
147   }
148
149    //------------------------------------------------------------
150
151    void Column::changePrec(int p)
152    {
153      /// A direct way to alter the precision without having to use
154      /// Column::upPrec(). If the precision increases, the width will
155      /// increase by the same amount. If it decreases, no change is
156      /// made to the width.
157      /// \param p The new precision value.
158
159      if(p > this->itsPrecision) this->itsWidth += (p-this->itsPrecision);
160      this->itsPrecision = p;
161
162    }
163   
164    //------------------------------------------------------------
165    void Column::printTitle(std::ostream &stream)
166    {
167      stream << std::setw(this->itsWidth)
168             << std::setfill(' ')
169             << this->itsName;
170    }
171
172    void Column::printUnits(std::ostream &stream)
173    {
174      // if(this->itsUnits == ""){
175      stream << std::setw(this->itsWidth)
176             << std::setfill(' ')
177             << this->itsUnits;
178      // }
179      // else {
180      //        stream << std::setw(this->itsWidth)
181      //               << std::setfill(' ')
182      //               << "["<<this->itsUnits<<"]";
183      // }
184    }
185 
186    void Column::printDash (std::ostream &stream)
187    {
188      stream << std::setw(this->itsWidth)
189             << std::setfill('-')
190             << ""
191             << std::setfill(' ');
192    }
193
194    void Column::printBlank(std::ostream &stream)
195    {
196      stream << std::setw(this->itsWidth)
197             << std::setfill(' ')
198             << "";
199    }
200 
201    template <class T> void Column::printEntry(std::ostream &stream, T value)
202    {
203      ///  \param stream Where the printing is done.
204      ///  \param value  The value to be printed.
205
206      stream << std::setprecision(this->itsPrecision)
207             << std::setw(this->itsWidth)
208             << std::setfill(' ')
209             << value;
210    }
211    template void Column::printEntry<int>(std::ostream &stream, int value);
212    template void Column::printEntry<long>(std::ostream &stream, long value);
213    template void Column::printEntry<unsigned int>(std::ostream &stream, unsigned int value);
214    template void Column::printEntry<unsigned long>(std::ostream &stream, unsigned long value);
215    template void Column::printEntry<float>(std::ostream &stream, float value);
216    template void Column::printEntry<double>(std::ostream &stream, double value);
217    template void Column::printEntry<std::string>(std::ostream &stream, std::string value);
218
219 
220    bool Column::doCol(DESTINATION tableType, bool flagFint)
221    {
222      ///  @details Uses the info in the isFile etc arrays to
223      ///  determine whether a given column, referenced by the
224      ///  enumeration COLNAME, is used for a given table type.
225      /// \param tableType The type of table: one of FILE, SCREEN, LOG, VOTABLE.
226      /// \param flagFint Whether to use FINT (true) or FTOT
227      /// (false). This defaults to true, so need not be given. It only
228      /// applies to the screen and votable cases -- both are written for the
229      /// results file case.
230      /// \return True if column is used for given table type. False
231      /// otherwise. False if tableType not one of four listed.
232     
233      // if(tableType == FILE) return isFile[this->itsType];
234      // else if(tableType == SCREEN){
235      //        if(flagFint && this->itsType==FTOT) return false;
236      //        if(!flagFint && this->itsType==FINT) return false;
237      //        return isScreen[this->itsType];
238      // }
239      // else if(tableType == LOG) return isLog[this->itsType];
240      // else if(tableType == VOTABLE){
241      //        if(flagFint && this->itsType==FTOT) return false;
242      //        if(!flagFint && this->itsType==FINT) return false;
243      //        return isVOTable[this->itsType];
244      // }
245      // else return false;
246     
247      std::string FileList[34]={"NUM","NAME","X","Y","Z","RA","DEC","VEL","WRA","WSEC",
248                                "W50","W20","WVEL","FINT","FTOT","FPEAK","SNRPEAK",
249                                "X1","X2","Y1","Y2","Z1","Z2","NPIX","FLAG","XAV","YAV",
250                                "ZAV","XCENT","YCENT","ZCENT","XPEAK","YPEAK","ZPEAK"};
251      std::string ScreenList[21]={"NUM","NAME","X","Y","Z","RA","DEC","VEL","WRA","WSEC",
252                                  "W50","FPEAK","SNRPEAK","X1","X2","Y1",
253                                  "Y2","Z1","Z2","NPIX","FLAG"};
254      std::string LogList[16]={"NUM","X","Y","Z","FTOT","FPEAK","SNRPEAK",
255                               "X1","X2","Y1","Y2","Z1","Z2","NPIX","NUMCH","SPATSIZE"};
256      std::string VOList[22]={"NUM","NAME","RAJD","DECJD","VEL","WRA","WSEC",
257                            "W50","W20","WVEL","FPEAK","SNRPEAK","FLAG","XAV","YAV",
258                            "ZAV","XCENT","YCENT","ZCENT","XPEAK","YPEAK","ZPEAK"};
259
260      bool doIt=false;
261      if(tableType == FILE){
262        for(int i=0;i<34 && !doIt;i++) doIt = doIt || (this->itsType==FileList[i]);
263      }
264      else if(tableType == SCREEN){
265        if(this->itsType=="FTOT") doIt = !flagFint;
266        else if(this->itsType == "FINT") doIt = flagFint;
267        else for(int i=0;i<21 && !doIt;i++) doIt = doIt || (this->itsType==ScreenList[i]);
268      }
269      else if(tableType == LOG){
270        for(int i=0;i<16 && !doIt;i++) doIt = doIt || (this->itsType==LogList[i]);
271      }
272      else if(tableType == VOTABLE){
273        if(this->itsType=="FTOT") doIt = !flagFint;
274        else if(this->itsType == "FINT") doIt = flagFint;
275        else for(int i=0;i<21 && !doIt;i++) doIt = doIt || (this->itsType==VOList[i]);
276      }
277      return doIt;
278       
279    }
280
281    Column defaultColumn(std::string type)
282    {
283      // type|name|units|width|prec|ucd|datatype|extraInfo
284      if (type == "NUM") return Column(type,"Obj#","",5,0,"meta.id","int","");
285      else if(type=="NAME") return Column(type,"Name","",8,0,"meta.id;meta.main","char","");
286      else if(type=="X") return Column(type,"X","",6,prXYZ,"pos.cartesian.x","float","");
287      else if(type=="Y") return Column(type,"Y","",6,prXYZ,"pos.cartesian.y","float","");
288      else if(type=="Z") return Column(type,"Z","",6,prXYZ,"pos.cartesian.z","float","");
289      else if(type=="RA") return Column(type,"RA","",11,0,"","char",coordRef);
290      else if(type=="DEC") return Column(type,"DEC","",10,0,"","char",coordRef);
291      else if(type=="RAJD") return Column(type,"RAJD","[deg]",11,prPOS,"","float",coordRef);
292      else if(type=="DECJD") return Column(type,"DECJD","[deg]",11,prPOS,"","float",coordRef);
293      else if(type=="VEL") return Column(type,"VEL","",7,prVEL,"","float","");
294      else if(type=="WRA") return Column(type,"w_RA","[arcmin]",9,prWPOS,"","float",coordRef);
295      else if(type=="WDEC") return Column(type,"w_DEC","[arcmin]",9,prWPOS,"","float",coordRef);
296      else if(type=="W50") return Column(type,"w_50","",7,prVEL,"","float","");
297      else if(type=="W20") return Column(type,"w_20","",7,prVEL,"","float","");
298      else if(type=="WVEL") return Column(type,"w_VEL","",7,prVEL,"","float","");
299      else if(type=="FINT") return Column(type,"F_int","",10,prFLUX,"phot.flux;spect.line.intensity","float","");
300      else if(type=="FTOT") return Column(type,"F_tot","",10,prFLUX,"phot.flux;spect.line.intensity","float","");
301      else if(type=="FPEAK") return Column(type,"F_peak","",9,prFLUX,"phot.flux;spect.line.intensity","float","");
302      else if(type=="SNRPEAK") return Column(type,"S/Nmax","",7,prSNR,"phot.flux;stat.snr","float","");
303      else if(type=="X1") return Column(type,"X1","",4,0,"pos.cartesian.x;stat.min","int","");
304      else if(type=="Y1") return Column(type,"Y1","",4,0,"pos.cartesian.y;stat.min","int","");
305      else if(type=="Z1") return Column(type,"Z1","",4,0,"pos.cartesian.z;stat.min","int","");
306      else if(type=="X2") return Column(type,"X2","",4,0,"pos.cartesian.x;stat.max","int","");
307      else if(type=="Y2") return Column(type,"Y2","",4,0,"pos.cartesian.y;stat.max","int","");
308      else if(type=="Z2") return Column(type,"Z2","",4,0,"pos.cartesian.z;stat.max","int","");
309      else if(type=="NPIX") return Column(type,"Npix","[pix]",6,0,"","int","");
310      else if(type=="FLAG") return Column(type,"Flag","",5,0,"meta.code.qual","char","");
311      else if(type=="XAV") return Column(type,"X_av","",6,prXYZ,"pos.cartesian.x","float","");
312      else if(type=="YAV") return Column(type,"X_av","",6,prXYZ,"pos.cartesian.y","float","");
313      else if(type=="ZAV") return Column(type,"X_av","",6,prXYZ,"pos.cartesian.z","float","");
314      else if(type=="XCENT") return Column(type,"X_cent","",7,prXYZ,"pos.cartesian.x","float","");
315      else if(type=="YCENT") return Column(type,"X_cent","",7,prXYZ,"pos.cartesian.y","float","");
316      else if(type=="ZCENT") return Column(type,"X_cent","",7,prXYZ,"pos.cartesian.z","float","");
317      else if(type=="XPEAK") return Column(type,"X_peak","",7,prXYZ,"pos.cartesian.x","int","");
318      else if(type=="YPEAK") return Column(type,"X_peak","",7,prXYZ,"pos.cartesian.y","int","");
319      else if(type=="ZPEAK") return Column(type,"X_peak","",7,prXYZ,"pos.cartesian.z","int","");
320      else if(type=="NUMCH") return Column(type,"Nch","",6,0,"","int","");
321      else if(type=="SPATSIZE") return Column(type,"Sp_size","",8,0,"","int","");
322      else {
323        Column col;
324        col.setType(type);
325        return col;
326      }
327
328    }
329
330
331    std::vector<Column> getFullColSet(std::vector<Detection> &objectList,
332                                      FitsHeader &head)
333    {
334      ///  @details A function that returns a std::vector of Col
335      ///  objects containing information on the columns necessary for
336      ///  output to the results file:
337      ///    Obj#,NAME,X,Y,Z,RA,DEC,VEL,w_RA,w_DEC,w_VEL,F_tot,F_int,F_peak,
338      ///                X1,X2,Y1,Y2,Z1,Z2,Npix,Flag,
339      ///                XAV,YAV,ZAV,XCENT,YCENT,ZCENT,XPEAK,YPEAK,ZPEAK
340      ///
341      ///   Each object in the provided objectList is checked to see if it
342      ///   requires any column to be widened, or for that column to have
343      ///   its precision increased.
344      ///
345      ///   Both Ftot and Fint are provided -- it is up to the calling
346      ///   function to determine which to use.
347      ///
348      /// \param objectList A std::vector list of Detection objects that the
349      /// columns need to fit.
350      /// \param head The FitsHeader object defining the World Coordinate
351      /// System.
352      /// \return A std::vector list of Col definitions.
353
354      std::vector<Column> newset;
355
356      // desired precisions for fluxes, velocities and SNR value
357      int precVel,precFlux,precSNR;
358      if(objectList.size()>0){
359        precVel=objectList[0].getVelPrec();
360        precFlux=objectList[0].getFpeakPrec(); // same as FintPrec at this point.
361        precSNR=objectList[0].getSNRPrec();
362      }
363      else {
364        precVel = prVEL;
365        precFlux = prFLUX;
366        precSNR = prSNR;
367      }
368
369      // set up the default columns
370      newset.push_back( Column("NUM") );
371      newset.push_back( Column("NAME") );
372      newset.push_back( Column("X") );
373      newset.push_back( Column("Y") );
374      newset.push_back( Column("Z") );
375      newset.push_back( Column("RA") );
376      newset.push_back( Column("DEC") );
377      newset.push_back( Column("RAJD") );
378      newset.push_back( Column("DECJD") );
379      newset.push_back( Column("VEL") );
380      newset.push_back( Column("WRA") );
381      newset.push_back( Column("WDEC") );
382      newset.push_back( Column("W50") );
383      newset.push_back( Column("W20") );
384      newset.push_back( Column("WVEL") );
385      newset.push_back( Column("FINT") );
386      newset.push_back( Column("FTOT") );
387      newset.push_back( Column("FPEAK") );
388      newset.push_back( Column("SNRPEAK") );
389      newset.push_back( Column("X1") );
390      newset.push_back( Column("X2") );
391      newset.push_back( Column("Y1") );
392      newset.push_back( Column("Y2") );
393      newset.push_back( Column("Z1") );
394      newset.push_back( Column("Z2") );
395      newset.push_back( Column("NPIX") );
396      newset.push_back( Column("FLAG") );
397      newset.push_back( Column("XAV") );
398      newset.push_back( Column("YAV") );
399      newset.push_back( Column("ZAV") );
400      newset.push_back( Column("XCENT") );
401      newset.push_back( Column("YCENT") );
402      newset.push_back( Column("ZCENT") );
403      newset.push_back( Column("XPEAK") );
404      newset.push_back( Column("YPEAK") );
405      newset.push_back( Column("ZPEAK") );
406      newset.push_back( Column("NUMCH") );
407      newset.push_back( Column("SPATSIZE") );
408
409
410      // Now test each object against each new column
411      std::vector<Detection>::iterator obj;
412      for(obj = objectList.begin(); obj < objectList.end(); obj++){
413        std::string tempstr;
414        int tempwidth;
415        float val,minval;
416        double valD,minvalD;
417
418        // Obj#
419        tempwidth = int( log10(obj->getID()) + 1) + 1;
420        for(int i=newset[NUM].getWidth();i<tempwidth;i++) newset[NUM].widen();
421
422        // Name
423        tempwidth = obj->getName().size() + 1;
424        for(int i=newset[NAME].getWidth();i<tempwidth;i++) newset[NAME].widen();
425
426        // X position
427        val = obj->getXcentre() + obj->getXOffset();
428        if((val<1.)&&(val>0.)){
429          minval = pow(10, -1. * (newset[X].getPrecision()+1));
430          if(val < minval) newset[X].upPrec();
431        }
432        tempwidth = int( log10(val) + 1) + newset[X].getPrecision() + 2;
433        for(int i=newset[X].getWidth();i<tempwidth;i++) newset[X].widen();
434        // Y position
435        val = obj->getYcentre() + obj->getYOffset();
436        if((val<1.)&&(val>0.)){
437          minval = pow(10, -1. * (newset[Y].getPrecision()+1));
438          if(val < minval) newset[Y].upPrec();
439        }
440        tempwidth = int( log10(val) + 1) + newset[Y].getPrecision() + 2;
441        for(int i=newset[Y].getWidth();i<tempwidth;i++) newset[Y].widen();
442        // Z position
443        val = obj->getZcentre() + obj->getZOffset();
444        if((val<1.)&&(val>0.)){
445          minval = pow(10, -1. * (newset[Z].getPrecision()+1));
446          if((val>0.)&&(val < minval)) newset[Z].upPrec();
447        }
448        tempwidth = int( log10(val) + 1) + newset[Z].getPrecision() + 2;
449        for(int i=newset[Z].getWidth();i<tempwidth;i++) newset[Z].widen();
450
451        if(head.isWCS()){ 
452          // RA -- assign correct title. Check width but should be ok by definition
453          tempstr = head.lngtype();
454          newset[RA].setName(tempstr);
455          tempwidth = obj->getRAs().size() + 1;
456          for(int i=newset[RA].getWidth();i<tempwidth;i++) newset[RA].widen();
457     
458          // Dec -- assign correct title. Check width, should be ok by definition
459          tempstr = head.lattype();
460          newset[DEC].setName(tempstr);
461          tempwidth = obj->getDecs().size() + 1;
462          for(int i=newset[DEC].getWidth();i<tempwidth;i++) newset[DEC].widen();
463
464          // RA decimal degrees -- assign correct title. Check width but should be OK
465          tempstr = head.lngtype();
466          newset[RAJD].setName(tempstr);
467          valD = obj->getRA();
468          tempwidth = int( log10(fabs(valD)) + 1) + newset[RAJD].getPrecision() + 2;
469          for(int i=newset[RAJD].getWidth();i<tempwidth;i++) newset[RAJD].widen();
470     
471          // Dec decimal degrees -- assign correct title. Check width but should be OK
472          tempstr = head.lattype();
473          newset[DECJD].setName(tempstr);
474          valD = obj->getDec();
475          tempwidth = int( log10(fabs(valD)) + 1) + newset[DECJD].getPrecision() + 2;
476          for(int i=newset[DECJD].getWidth();i<tempwidth;i++) newset[DECJD].widen();
477
478          // Vel -- check width, title and units.
479          //if(head.isSpecOK()){
480          if(head.canUseThirdAxis()){
481            if(head.WCS().spec < 0)  // if it's not a spectral axis
482              newset[VEL].setName( head.WCS().ctype[2] );
483            else
484              newset[VEL].setName(head.getSpectralType());
485            tempwidth = newset[VEL].getName().size() + 1;
486            for(int i=newset[VEL].getWidth();i<tempwidth;i++) newset[VEL].widen();
487            if(head.getSpectralUnits().size()>0)
488              newset[VEL].setUnits("[" + head.getSpectralUnits() + "]");
489            tempwidth = newset[VEL].getUnits().size() + 1;
490            for(int i=newset[VEL].getWidth();i<tempwidth;i++) newset[VEL].widen();
491       
492            valD = obj->getVel();
493            if((fabs(valD) < 1.)&&(valD>0.)){
494              minvalD = pow(10, -1. * (newset[VEL].getPrecision()+1));
495              if(valD < minvalD) newset[VEL].upPrec();
496            }
497            tempwidth = int(log10(fabs(valD)) + 1) + newset[VEL].getPrecision() + 2;
498            if(valD<0) tempwidth++;
499            for(int i=newset[VEL].getWidth();i<tempwidth;i++) newset[VEL].widen();
500          }
501
502          // w_RA -- check width & title. leave units for the moment.
503          tempstr = "w_" + head.lngtype();
504          newset[WRA].setName(tempstr);
505          tempwidth = newset[RA].getUnits().size() + 1;
506          for(int i=newset[WRA].getWidth();i<tempwidth;i++) newset[WRA].widen();
507          valD = obj->getRAWidth();
508          if((fabs(valD) < 1.)&&(valD>0.)){
509            minvalD = pow(10, -1. * (newset[WRA].getPrecision()+1));
510            if(valD < minvalD) newset[WRA].upPrec();
511          }
512          tempwidth = int( log10(fabs(valD)) + 1) + newset[WRA].getPrecision() + 2;
513          if(valD<0) tempwidth++;
514          for(int i=newset[WRA].getWidth();i<tempwidth;i++) newset[WRA].widen();
515
516          // w_DEC -- check width & title. leave units for the moment.
517          tempstr = "w_" + head.lattype();
518          newset[WDEC].setName(tempstr);
519          tempwidth = newset[DEC].getUnits().size() + 1;
520          for(int i=newset[WDEC].getWidth();i<tempwidth;i++) newset[WDEC].widen();
521          valD = obj->getDecWidth();
522          if((fabs(valD) < 1.)&&(valD>0.)){
523            minvalD = pow(10, -1. * (newset[WDEC].getPrecision()+1));
524            if(valD < minvalD) newset[WDEC].upPrec();
525          }
526          tempwidth = int( log10(fabs(valD)) + 1) + newset[WDEC].getPrecision() + 2;
527          if(valD<0) tempwidth++;
528          for(int i=newset[WDEC].getWidth();i<tempwidth;i++) newset[WDEC].widen();
529
530          // w_50 -- check width, title and units.
531          if(head.canUseThirdAxis()){
532            if(head.getSpectralUnits().size()>0)
533              newset[W50].setUnits("[" + head.getSpectralUnits() + "]");
534            tempwidth = newset[W50].getUnits().size() + 1;
535            for(int i=newset[W50].getWidth();i<tempwidth;i++) newset[W50].widen();
536            valD = obj->getW50();
537            if((fabs(valD) < 1.)&&(valD>0.)){
538              minvalD = pow(10, -1. * (newset[W50].getPrecision()+1));
539              if(valD < minvalD) newset[W50].upPrec();
540            }
541            tempwidth = int( log10(fabs(valD)) + 1) + newset[W50].getPrecision() + 2;
542            if(valD<0) tempwidth++;
543            for(int i=newset[W50].getWidth();i<tempwidth;i++) newset[W50].widen();
544          }
545
546          // w_20 -- check width, title and units.
547          if(head.canUseThirdAxis()){
548            if(head.getSpectralUnits().size()>0)
549              newset[W20].setUnits("[" + head.getSpectralUnits() + "]");
550            tempwidth = newset[W20].getUnits().size() + 1;
551            for(int i=newset[W20].getWidth();i<tempwidth;i++)newset[W20].widen();
552            valD = obj->getW20();
553            if((fabs(valD) < 1.)&&(valD>0.)){
554              minvalD = pow(10, -1. * (newset[W20].getPrecision()+1));
555              if(valD < minvalD) newset[W20].upPrec();
556            }
557            tempwidth = int( log10(fabs(valD)) + 1) + newset[W20].getPrecision() + 2;
558            if(valD<0) tempwidth++;
559            for(int i=newset[W20].getWidth();i<tempwidth;i++) newset[W20].widen();
560          }
561
562          // w_Vel -- check width, title and units.
563          if(head.canUseThirdAxis()){
564            if(head.WCS().spec < 0) // if it's not a spectral axis
565              newset[WVEL].setName( std::string("w_") + head.WCS().ctype[2] );
566// //       else if(head.WCS().restfrq == 0) // using frequency, not velocity
567//          else if(head.getSpectralDescription()==duchamp::duchampSpectralDescription[FREQUENCY]) // using frequency, not velocity
568//            newset[WVEL].setName("w_FREQ");
569            else
570              newset[WVEL].setName(std::string("w_")+head.getSpectralType());
571            if(head.getSpectralUnits().size()>0)
572              newset[WVEL].setUnits("[" + head.getSpectralUnits() + "]");
573            tempwidth = newset[WVEL].getUnits().size() + 1;
574            for(int i=newset[WVEL].getWidth();i<tempwidth;i++)newset[WVEL].widen();
575            tempwidth = newset[WVEL].getName().size() + 1;
576            for(int i=newset[WVEL].getWidth();i<tempwidth;i++) newset[WVEL].widen();
577            valD = obj->getVelWidth();
578            if((fabs(valD) < 1.)&&(valD>0.)){
579              minvalD = pow(10, -1. * (newset[WVEL].getPrecision()+1));
580              if(valD < minvalD) newset[WVEL].upPrec();
581            }
582            tempwidth = int( log10(fabs(valD)) + 1) + newset[WVEL].getPrecision() + 2;
583            if(valD<0) tempwidth++;
584            for(int i=newset[WVEL].getWidth();i<tempwidth;i++) newset[WVEL].widen();
585          }
586
587          // F_int -- check width & units
588          if(head.getIntFluxUnits().size()>0)
589            newset[FINT].setUnits("[" + head.getIntFluxUnits() + "]");
590          tempwidth = newset[FINT].getUnits().size() + 1;
591          for(int i=newset[FINT].getWidth();i<tempwidth;i++) newset[FINT].widen();
592          valD = obj->getIntegFlux();
593          if((fabs(valD) < 1.)// &&(valD>0.)
594             ){
595            int minprec = int(fabs(log10(fabs(valD))))+2;
596            for(int i=newset[FINT].getPrecision();i<minprec;i++) newset[FINT].upPrec();
597          }
598          tempwidth = int( log10(fabs(valD)) + 1) + newset[FINT].getPrecision() + 2;
599          if(valD<0) tempwidth++;
600          for(int i=newset[FINT].getWidth();i<tempwidth;i++) newset[FINT].widen();
601     
602        }
603
604        // F_tot
605        newset[FTOT].setUnits("[" + head.getFluxUnits() + "]");
606        tempwidth = newset[FTOT].getUnits().size() + 1;
607        for(int i=newset[FTOT].getWidth();i<tempwidth;i++) newset[FTOT].widen();
608        val = obj->getTotalFlux();
609        //     std::cerr << val << "\n";
610        if((fabs(val) < 1.)// &&(val>0.)
611           ){
612          int minprec = int(fabs(log10(fabs(val))))+2;
613          for(int i=newset[FTOT].getPrecision();i<minprec;i++) newset[FTOT].upPrec();
614        }
615        tempwidth = int( log10(fabs(val)) + 1) + newset[FTOT].getPrecision() + 2;
616        if(val<0) tempwidth++;
617        for(int i=newset[FTOT].getWidth();i<tempwidth;i++) newset[FTOT].widen();
618
619        // F_peak
620        newset[FPEAK].setUnits("[" + head.getFluxUnits() + "]");
621        tempwidth = newset[FPEAK].getUnits().size() + 1;
622        for(int i=newset[FPEAK].getWidth();i<tempwidth;i++) newset[FPEAK].widen();
623        val = obj->getPeakFlux();
624        if((fabs(val) < 1.)// &&(val>0.)
625           ){
626          int minprec = int(fabs(log10(fabs(val))))+2;
627          for(int i=newset[FPEAK].getPrecision();i<minprec;i++) newset[FPEAK].upPrec();
628        }
629        tempwidth = int( log10(fabs(val)) + 1) + newset[FPEAK].getPrecision() + 2;
630        if(val<0) tempwidth++;
631        for(int i=newset[FPEAK].getWidth();i<tempwidth;i++) newset[FPEAK].widen();
632
633        // S/N_peak
634        val = obj->getPeakSNR();
635        if((fabs(val) < 1.)&&(val>0.)){
636          minval = pow(10, -1. * (newset[SNRPEAK].getPrecision()+1));
637          if(val < minval) newset[SNRPEAK].upPrec();
638        }
639        tempwidth = int( log10(fabs(val)) + 1) + newset[SNRPEAK].getPrecision() +2;
640        if(val<0) tempwidth++;
641        for(int i=newset[SNRPEAK].getWidth();i<tempwidth;i++) newset[SNRPEAK].widen();
642
643        // X1 position
644        val = obj->getXmin() + obj->getXOffset();
645        tempwidth = int( log10(val) + 1) + newset[X1].getPrecision() + 1;
646        for(int i=newset[X1].getWidth();i<tempwidth;i++) newset[X1].widen();
647        // X2 position
648        val = obj->getXmax() + obj->getXOffset();
649        tempwidth = int( log10(val) + 1) + newset[X2].getPrecision() + 1;
650        for(int i=newset[X2].getWidth();i<tempwidth;i++) newset[X2].widen();
651        // Y1 position
652        val = obj->getYmin() + obj->getYOffset();
653        tempwidth = int( log10(val) + 1) + newset[Y1].getPrecision() + 1;
654        for(int i=newset[Y1].getWidth();i<tempwidth;i++) newset[Y1].widen();
655        // Y2 position
656        val = obj->getYmax() + obj->getYOffset();
657        tempwidth = int( log10(val) + 1) + newset[Y2].getPrecision() + 1;
658        for(int i=newset[Y2].getWidth();i<tempwidth;i++) newset[Y2].widen();
659        // Z1 position
660        val = obj->getZmin() + obj->getZOffset();
661        tempwidth = int( log10(val) + 1) + newset[Z1].getPrecision() + 1;
662        for(int i=newset[Z1].getWidth();i<tempwidth;i++) newset[Z1].widen();
663        // Z2 position
664        val = obj->getZmax() + obj->getZOffset();
665        tempwidth = int( log10(val) + 1) + newset[Z2].getPrecision() + 1;
666        for(int i=newset[Z2].getWidth();i<tempwidth;i++) newset[Z2].widen();
667
668        // Npix
669        tempwidth = int( log10(obj->getSize()) + 1) +
670          newset[NPIX].getPrecision() + 1;
671        for(int i=newset[NPIX].getWidth();i<tempwidth;i++) newset[NPIX].widen();
672   
673        // average X position
674//      val = obj->getXAverage() + obj->getXOffset();
675        val = obj->getXaverage() + obj->getXOffset();
676        if((val<1.)&&(val>0.)){
677          minval = pow(10, -1. * (newset[XAV].getPrecision()+1));
678          if(val < minval) newset[XAV].upPrec();
679        }
680        tempwidth = int( log10(val) + 1) + newset[XAV].getPrecision() + 2;
681        for(int i=newset[XAV].getWidth();i<tempwidth;i++) newset[XAV].widen();
682        // average Y position
683//      val = obj->getYAverage() + obj->getYOffset();
684        val = obj->getYaverage() + obj->getYOffset();
685        if((val<1.)&&(val>0.)){
686          minval = pow(10, -1. * (newset[YAV].getPrecision()+1));
687          if(val < minval) newset[YAV].upPrec();
688        }
689        tempwidth = int( log10(val) + 1) + newset[YAV].getPrecision() + 2;
690        for(int i=newset[YAV].getWidth();i<tempwidth;i++) newset[YAV].widen();
691        // average Z position
692//      val = obj->getZAverage() + obj->getZOffset();
693        val = obj->getZaverage() + obj->getZOffset();
694        if((val<1.)&&(val>0.)){
695          minval = pow(10, -1. * (newset[ZAV].getPrecision()+1));
696          if((val>0.)&&(val < minval)) newset[ZAV].upPrec();
697        }
698        tempwidth = int( log10(val) + 1) + newset[ZAV].getPrecision() + 2;
699        for(int i=newset[ZAV].getWidth();i<tempwidth;i++) newset[ZAV].widen();
700   
701        // X position of centroid
702        val = obj->getXCentroid() + obj->getXOffset();
703        if((val<1.)&&(val>0.)){
704          minval = pow(10, -1. * (newset[XCENT].getPrecision()+1));
705          if(val < minval) newset[XCENT].upPrec();
706        }
707        tempwidth = int( log10(val) + 1) + newset[XCENT].getPrecision() + 2;
708        for(int i=newset[XCENT].getWidth();i<tempwidth;i++) newset[XCENT].widen();
709        // Y position of centroid
710        val = obj->getYCentroid() + obj->getYOffset();
711        if((val<1.)&&(val>0.)){
712          minval = pow(10, -1. * (newset[YCENT].getPrecision()+1));
713          if(val < minval) newset[YCENT].upPrec();
714        }
715        tempwidth = int( log10(val) + 1) + newset[YCENT].getPrecision() + 2;
716        for(int i=newset[YCENT].getWidth();i<tempwidth;i++) newset[YCENT].widen();
717        // Z position of centroid
718        val = obj->getZCentroid() + obj->getZOffset();
719        if((val<1.)&&(val>0.)){
720          minval = pow(10, -1. * (newset[ZCENT].getPrecision()+1));
721          if((val>0.)&&(val < minval)) newset[ZCENT].upPrec();
722        }
723        tempwidth = int( log10(val) + 1) + newset[ZCENT].getPrecision() + 2;
724        for(int i=newset[ZCENT].getWidth();i<tempwidth;i++) newset[ZCENT].widen();
725   
726        // X position of peak flux
727        val = obj->getXPeak() + obj->getXOffset();
728        if((val<1.)&&(val>0.)){
729          minval = pow(10, -1. * (newset[XPEAK].getPrecision()+1));
730          if(val < minval) newset[XPEAK].upPrec();
731        }
732        tempwidth = int( log10(val) + 1) + newset[XPEAK].getPrecision() + 2;
733        for(int i=newset[XPEAK].getWidth();i<tempwidth;i++) newset[XPEAK].widen();
734        // Y position of peak flux
735        val = obj->getYPeak() + obj->getYOffset();
736        if((val<1.)&&(val>0.)){
737          minval = pow(10, -1. * (newset[YPEAK].getPrecision()+1));
738          if(val < minval) newset[YPEAK].upPrec();
739        }
740        tempwidth = int( log10(val) + 1) + newset[YPEAK].getPrecision() + 2;
741        for(int i=newset[YPEAK].getWidth();i<tempwidth;i++) newset[YPEAK].widen();
742        // Z position of peak flux
743        val = obj->getZPeak() + obj->getZOffset();
744        if((val<1.)&&(val>0.)){
745          minval = pow(10, -1. * (newset[ZPEAK].getPrecision()+1));
746          if((val>0.)&&(val < minval)) newset[ZPEAK].upPrec();
747        }
748        tempwidth = int( log10(val) + 1) + newset[ZPEAK].getPrecision() + 2;
749        for(int i=newset[ZPEAK].getWidth();i<tempwidth;i++) newset[ZPEAK].widen();
750
751        //Number of contiguous channels
752        tempwidth = int( log10(obj->getMaxAdjacentChannels()) + 1) +
753          newset[NUMCH].getPrecision() + 1;
754        for(int i=newset[NUMCH].getWidth();i<tempwidth;i++) newset[NUMCH].widen();
755        //Spatial size
756        tempwidth = int( log10(obj->getSpatialSize()) + 1) +
757          newset[SPATSIZE].getPrecision() + 1;
758        for(int i=newset[SPATSIZE].getWidth();i<tempwidth;i++) newset[SPATSIZE].widen();
759       
760      }
761     
762      return newset;
763
764    }
765
766    std::vector<Column> getLogColSet(std::vector<Detection> &objectList,
767                                  FitsHeader &head)
768    {
769      ///  @details A function that returns a std::vector of Col
770      ///    objects containing information on the columns necessary
771      ///    for logfile output:
772      ///    Obj#,X,Y,Z,F_tot,F_peak,X1,X2,Y1,Y2,Z1,Z2,Npix
773      ///
774      ///   Each object in the provided objectList is checked to see if
775      ///    it requires any column to be widened, or for that column to
776      ///    have its precision increased.
777      ///
778      /// \param objectList A std::vector list of Detection objects that the columns need to fit.
779      /// \param head The FitsHeader object defining the World Coordinate System.
780      /// \return A std::vector list of Col definitions.
781
782      std::vector<Column> newset,tempset;
783 
784      // set up the default columns:
785      //  get from FullColSet, and select only the ones we want.
786      tempset = getFullColSet(objectList,head);
787
788      newset.push_back( tempset[NUM] );
789      newset.push_back( tempset[X] );
790      newset.push_back( tempset[Y] );
791      newset.push_back( tempset[Z] );
792      newset.push_back( tempset[FTOT] );
793      newset.push_back( tempset[FPEAK] );
794      newset.push_back( tempset[SNRPEAK] );
795      newset.push_back( tempset[X1] );
796      newset.push_back( tempset[X2] );
797      newset.push_back( tempset[Y1] );
798      newset.push_back( tempset[Y2] );
799      newset.push_back( tempset[Z1] );
800      newset.push_back( tempset[Z2] );
801      newset.push_back( tempset[NPIX] );
802      newset.push_back( tempset[NUMCH] );
803      newset.push_back( tempset[SPATSIZE] );
804
805      return newset;
806
807    }
808
809  }
810
811}
Note: See TracBrowser for help on using the repository browser.