source: trunk/src/Detection/columns.cc @ 944

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

A large swathe of changes aimed at improving warning/error/exception handling. Now make use of macros and streams. Also, there is now a distinction between DUCHAMPERROR and DUCHAMPTHROW.

File size: 25.7 KB
RevLine 
[300]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// -----------------------------------------------------------------------
[144]28#include <iostream>
29#include <sstream>
30
[155]31#include <math.h>
[393]32#include <duchamp/duchamp.hh>
33#include <duchamp/fitsHeader.hh>
[93]34#include <vector>
35#include <string>
[393]36#include <duchamp/Detection/detection.hh>
37#include <duchamp/Detection/columns.hh>
[93]38
[378]39namespace duchamp
[232]40{
[221]41
[378]42  namespace Column
[272]43  {
[221]44
[439]45
[378]46    Col::Col()
47    {
[528]48      /// @brief Set the default values for the parameters.
[378]49      this->width=1;
50      this->precision=0;
51      this->name=" ";
52      this->units=" ";
[440]53      this->type=UNKNOWN;
[419]54    }
[232]55
[378]56    Col::~Col(){}
[365]57
[378]58    Col::Col(const Col& c)
59    {
60      operator=(c);
61    }
[365]62
[378]63    Col& Col::operator=(const Col& c)
64    {
65      if(this==&c) return *this;
66      this->width = c.width;
67      this->precision = c.precision;
68      this->name = c.name;
69      this->units = c.units;
[440]70      this->type = c.type;
[378]71      return *this;
[232]72    }
[378]73
[438]74    Col::Col(int num, int prec)
[378]75    {
[528]76      /// A specialised constructor that defines one of the default
77      ///  columns, as defined in the Column namespace
78      /// \param num The number of the column to be constructed.
79      ///            Corresponds to the order of the columns in the const
80      ///            arrays in the Column namespace.
81      /// \param prec The precision to use, if not the default. A value
82      /// <0 or no value given results in the default being used.
83
[378]84      if((num>=0)&&(num<numColumns)){
85        this->width     = defaultWidth[num];
[438]86        if(prec<0) this->precision = defaultPrec[num];
87        else this->precision = prec;
[378]88        this->name      = defaultName[num];
89        this->units     = defaultUnits[num];
[440]90        this->type = COLNAME(num);
[378]91      }
92      else{
[913]93        DUCHAMPERROR("Column constructor", "Incorrect value for Col(num) --> num="<<num << ", should be between 0 and " << numColumns-1);
[378]94        this->width = 1;
95        this->precision = 0;
96        this->name = " ";
97        this->units = " ";
[440]98        this->type=UNKNOWN;
[378]99      }
[232]100    }
[438]101
[540]102    Col::Col(std::string name, std::string units, int width, int prec)
103    {
104      /// A generic constructor designed to make a Column other than
105      /// the predefined ones listed in the Column namespace
106      /// \param name The title of the column
107      /// \param units What units the column takes
108      /// \param width The starting width
109      /// \param prec The starting precision
110
111      this->width = width;
112      this->precision = prec;
113      this->name = name;
114      this->units = units;
115      this->type = UNKNOWN;
116    }
117
[378]118    //------------------------------------------------------------
[540]119
120    void Col::changePrec(int p)
121    {
122      /// A direct way to alter the precision without having to use
123      /// Col::upPrec(). If the precision increases, the width will
124      /// increase by the same amount. If it decreases, no change is
125      /// made to the width.
126      /// \param p The new precision value.
127
128      if(p > this->precision) this->width += (p-this->precision);
129      this->precision = p;
130
131    }
132   
133    //------------------------------------------------------------
[378]134    void Col::printTitle(std::ostream &stream)
135    {
136      stream << std::setw(this->width)
137             << std::setfill(' ')
138             << this->name;
139    }
[93]140
[378]141    void Col::printUnits(std::ostream &stream)
142    {
143      stream << std::setw(this->width)
144             << std::setfill(' ')
145             << this->units;
146    }
[272]147 
[378]148    void Col::printDash (std::ostream &stream)
149    {
150      stream << std::setw(this->width)
151             << std::setfill('-')
152             << ""
153             << std::setfill(' ');
154    }
[232]155
[378]156    void Col::printBlank(std::ostream &stream)
157    {
158      stream << std::setw(this->width)
159             << std::setfill(' ')
160             << "";
161    }
[272]162 
[378]163    template <class T> void Col::printEntry(std::ostream &stream, T value)
164    {
[528]165      ///  \param stream Where the printing is done.
166      ///  \param value  The value to be printed.
167
[378]168      stream << std::setprecision(this->precision)
169             << std::setw(this->width)
170             << std::setfill(' ')
171             << value;
172    }
173    template void Col::printEntry<int>(std::ostream &stream, int value);
174    template void Col::printEntry<long>(std::ostream &stream, long value);
[623]175    template void Col::printEntry<unsigned int>(std::ostream &stream, unsigned int value);
[688]176    template void Col::printEntry<unsigned long>(std::ostream &stream, unsigned long value);
[378]177    template void Col::printEntry<float>(std::ostream &stream, float value);
178    template void Col::printEntry<double>(std::ostream &stream, double value);
179    template void Col::printEntry<std::string>(std::ostream &stream, std::string value);
[272]180
[440]181 
182    bool Col::doCol(std::string tableType, bool flagFint)
183    {
[528]184      ///  @details Uses the info in the isFile etc arrays to
185      ///  determine whether a given column, referenced by the
186      ///  enumeration COLNAME, is used for a given table type.
187      /// \param tableType The type of table: one of file, screen, log, votable.
188      /// \param flagFint Whether to use FINT (true) or FTOT
189      /// (false). This defaults to true, so need not be given. It only
190      /// applies to the screen and votable cases -- both are written for the
191      /// results file case.
192      /// \return True if column is used for given table type. False
193      /// otherwise. False if tableType not one of four listed.
[440]194     
195      if(tableType == "file") return isFile[this->type];
196      else if(tableType == "screen"){
197        if(flagFint && this->type==FTOT) return false;
198        if(!flagFint && this->type==FINT) return false;
199        return isScreen[this->type];
200      }
201      else if(tableType == "log") return isLog[this->type];
202      else if(tableType == "votable"){
203        if(flagFint && this->type==FTOT) return false;
204        if(!flagFint && this->type==FINT) return false;
205        return isVOTable[this->type];
206      }
207      else return false;
208    }
209
[378]210 
[221]211
[378]212    std::vector<Col> getFullColSet(std::vector<Detection> &objectList,
213                                   FitsHeader &head)
214    {
[528]215      ///  @details A function that returns a std::vector of Col
216      ///  objects containing information on the columns necessary for
217      ///  output to the results file:
218      ///    Obj#,NAME,X,Y,Z,RA,DEC,VEL,w_RA,w_DEC,w_VEL,F_tot,F_int,F_peak,
219      ///                X1,X2,Y1,Y2,Z1,Z2,Npix,Flag,
220      ///                XAV,YAV,ZAV,XCENT,YCENT,ZCENT,XPEAK,YPEAK,ZPEAK
221      ///
222      ///   Each object in the provided objectList is checked to see if it
223      ///   requires any column to be widened, or for that column to have
224      ///   its precision increased.
225      ///
226      ///   Both Ftot and Fint are provided -- it is up to the calling
227      ///   function to determine which to use.
228      ///
229      /// \param objectList A std::vector list of Detection objects that the
230      /// columns need to fit.
231      /// \param head The FitsHeader object defining the World Coordinate
232      /// System.
233      /// \return A std::vector list of Col definitions.
[93]234
[378]235      std::vector<Col> newset;
[93]236
[438]237      // desired precisions for fluxes, velocities and SNR value
[461]238      int precVel,precFlux,precSNR;
239      if(objectList.size()>0){
240        precVel=objectList[0].getVelPrec();
241        precFlux=objectList[0].getFpeakPrec(); // same as FintPrec at this point.
[438]242        precSNR=objectList[0].getSNRPrec();
[461]243      }
244      else {
245        precVel = prVEL;
246        precFlux = prFLUX;
247        precSNR = prSNR;
248      }
[438]249
[378]250      // set up the default columns
251      newset.push_back( Col(NUM) );
252      newset.push_back( Col(NAME) );
253      newset.push_back( Col(X) );
254      newset.push_back( Col(Y) );
255      newset.push_back( Col(Z) );
256      newset.push_back( Col(RA) );
257      newset.push_back( Col(DEC) );
[439]258      newset.push_back( Col(RAJD) );
259      newset.push_back( Col(DECJD) );
[438]260      newset.push_back( Col(VEL, precVel) );
[378]261      newset.push_back( Col(WRA) );
262      newset.push_back( Col(WDEC) );
[463]263      newset.push_back( Col(W50, precVel) );
264      newset.push_back( Col(W20, precVel) );
[438]265      newset.push_back( Col(WVEL, precVel) );
266      newset.push_back( Col(FINT, precFlux) );
267      newset.push_back( Col(FTOT, precFlux) );
268      newset.push_back( Col(FPEAK, precFlux) );
269      newset.push_back( Col(SNRPEAK, precSNR) );
[378]270      newset.push_back( Col(X1) );
271      newset.push_back( Col(X2) );
272      newset.push_back( Col(Y1) );
273      newset.push_back( Col(Y2) );
274      newset.push_back( Col(Z1) );
275      newset.push_back( Col(Z2) );
276      newset.push_back( Col(NPIX) );
277      newset.push_back( Col(FLAG) );
278      newset.push_back( Col(XAV) );
279      newset.push_back( Col(YAV) );
280      newset.push_back( Col(ZAV) );
281      newset.push_back( Col(XCENT) );
282      newset.push_back( Col(YCENT) );
283      newset.push_back( Col(ZCENT) );
284      newset.push_back( Col(XPEAK) );
285      newset.push_back( Col(YPEAK) );
286      newset.push_back( Col(ZPEAK) );
[688]287      newset.push_back( Col(NUMCH) );
288      newset.push_back( Col(SPATSIZE) );
[93]289
[438]290
[378]291      // Now test each object against each new column
[623]292      std::vector<Detection>::iterator obj;
293      for(obj = objectList.begin(); obj < objectList.end(); obj++){
[378]294        std::string tempstr;
295        int tempwidth;
296        float val,minval;
[93]297
[378]298        // Obj#
[623]299        tempwidth = int( log10(obj->getID()) + 1) + 1;
[378]300        for(int i=newset[NUM].getWidth();i<tempwidth;i++) newset[NUM].widen();
[93]301
[378]302        // Name
[623]303        tempwidth = obj->getName().size() + 1;
[378]304        for(int i=newset[NAME].getWidth();i<tempwidth;i++) newset[NAME].widen();
[93]305
[378]306        // X position
[623]307        val = obj->getXcentre() + obj->getXOffset();
[378]308        if((val<1.)&&(val>0.)){
309          minval = pow(10, -1. * (newset[X].getPrecision()+1));
310          if(val < minval) newset[X].upPrec();
311        }
312        tempwidth = int( log10(val) + 1) + newset[X].getPrecision() + 2;
313        for(int i=newset[X].getWidth();i<tempwidth;i++) newset[X].widen();
314        // Y position
[623]315        val = obj->getYcentre() + obj->getYOffset();
[378]316        if((val<1.)&&(val>0.)){
317          minval = pow(10, -1. * (newset[Y].getPrecision()+1));
318          if(val < minval) newset[Y].upPrec();
319        }
320        tempwidth = int( log10(val) + 1) + newset[Y].getPrecision() + 2;
321        for(int i=newset[Y].getWidth();i<tempwidth;i++) newset[Y].widen();
322        // Z position
[623]323        val = obj->getZcentre() + obj->getZOffset();
[378]324        if((val<1.)&&(val>0.)){
325          minval = pow(10, -1. * (newset[Z].getPrecision()+1));
326          if((val>0.)&&(val < minval)) newset[Z].upPrec();
327        }
328        tempwidth = int( log10(val) + 1) + newset[Z].getPrecision() + 2;
329        for(int i=newset[Z].getWidth();i<tempwidth;i++) newset[Z].widen();
[93]330
[378]331        if(head.isWCS()){ 
332          // RA -- assign correct title. Check width but should be ok by definition
333          tempstr = head.WCS().lngtyp;
334          newset[RA].setName(tempstr);
[623]335          tempwidth = obj->getRAs().size() + 1;
[378]336          for(int i=newset[RA].getWidth();i<tempwidth;i++) newset[RA].widen();
[144]337     
[378]338          // Dec -- assign correct title. Check width, should be ok by definition
339          tempstr = head.WCS().lattyp;
340          newset[DEC].setName(tempstr);
[623]341          tempwidth = obj->getDecs().size() + 1;
[378]342          for(int i=newset[DEC].getWidth();i<tempwidth;i++) newset[DEC].widen();
[93]343
[439]344          // RA decimal degrees -- assign correct title. Check width but should be OK
345          tempstr = head.WCS().lngtyp;
346          newset[RAJD].setName(tempstr);
[623]347          val = obj->getRA();
[439]348          tempwidth = int( log10(fabs(val)) + 1) + newset[RAJD].getPrecision() + 2;
349          for(int i=newset[RAJD].getWidth();i<tempwidth;i++) newset[RAJD].widen();
350     
351          // Dec decimal degrees -- assign correct title. Check width but should be OK
352          tempstr = head.WCS().lattyp;
353          newset[DECJD].setName(tempstr);
[623]354          val = obj->getDec();
[439]355          tempwidth = int( log10(fabs(val)) + 1) + newset[DECJD].getPrecision() + 2;
356          for(int i=newset[DECJD].getWidth();i<tempwidth;i++) newset[DECJD].widen();
357
[378]358          // Vel -- check width, title and units.
359          //if(head.isSpecOK()){
360          if(head.canUseThirdAxis()){
[479]361            if(head.WCS().spec < 0)  // if it's not a spectral axis
362              newset[VEL].setName( head.WCS().ctype[2] );
[491]363//          else if(head.WCS().restfrq == 0) // using frequency, not velocity
364            else if(head.getSpectralDescription()==duchamp::duchampSpectralDescription[FREQUENCY]) // using frequency, not velocity
[378]365              newset[VEL].setName("FREQ");
366            if(head.getSpectralUnits().size()>0)
367              newset[VEL].setUnits("[" + head.getSpectralUnits() + "]");
368            tempwidth = newset[VEL].getUnits().size() + 1;
369            for(int i=newset[VEL].getWidth();i<tempwidth;i++) newset[VEL].widen();
[271]370       
[623]371            val = obj->getVel();
[378]372            if((fabs(val) < 1.)&&(val>0.)){
373              minval = pow(10, -1. * (newset[VEL].getPrecision()+1));
374              if(val < minval) newset[VEL].upPrec();
375            }
376            tempwidth = int(log10(fabs(val)) + 1) + newset[VEL].getPrecision() + 2;
377            if(val<0) tempwidth++;
378            for(int i=newset[VEL].getWidth();i<tempwidth;i++) newset[VEL].widen();
379          }
[93]380
[378]381          // w_RA -- check width & title. leave units for the moment.
382          tempwidth = newset[RA].getUnits().size() + 1;
383          for(int i=newset[RA].getWidth();i<tempwidth;i++) newset[RA].widen();
[623]384          val = obj->getRAWidth();
[378]385          if((fabs(val) < 1.)&&(val>0.)){
386            minval = pow(10, -1. * (newset[WRA].getPrecision()+1));
387            if(val < minval) newset[WRA].upPrec();
388          }
389          tempwidth = int( log10(fabs(val)) + 1) + newset[WRA].getPrecision() + 2;
390          if(val<0) tempwidth++;
391          for(int i=newset[WRA].getWidth();i<tempwidth;i++) newset[WRA].widen();
[136]392
[378]393          // w_DEC -- check width & title. leave units for the moment.
394          tempwidth = newset[DEC].getUnits().size() + 1;
395          for(int i=newset[DEC].getWidth();i<tempwidth;i++) newset[DEC].widen();
[623]396          val = obj->getDecWidth();
[378]397          if((fabs(val) < 1.)&&(val>0.)){
398            minval = pow(10, -1. * (newset[WDEC].getPrecision()+1));
399            if(val < minval) newset[WDEC].upPrec();
400          }
401          tempwidth = int( log10(fabs(val)) + 1) + newset[WDEC].getPrecision() + 2;
402          if(val<0) tempwidth++;
403          for(int i=newset[WDEC].getWidth();i<tempwidth;i++) newset[WDEC].widen();
[136]404
[463]405          // w_50 -- check width, title and units.
406          if(head.canUseThirdAxis()){
407            if(head.getSpectralUnits().size()>0)
408              newset[W50].setUnits("[" + head.getSpectralUnits() + "]");
409            tempwidth = newset[W50].getUnits().size() + 1;
[465]410            for(int i=newset[W50].getWidth();i<tempwidth;i++) newset[W50].widen();
[623]411            val = obj->getW50();
[463]412            if((fabs(val) < 1.)&&(val>0.)){
413              minval = pow(10, -1. * (newset[W50].getPrecision()+1));
414              if(val < minval) newset[W50].upPrec();
415            }
416            tempwidth = int( log10(fabs(val)) + 1) + newset[W50].getPrecision() + 2;
417            if(val<0) tempwidth++;
418            for(int i=newset[W50].getWidth();i<tempwidth;i++) newset[W50].widen();
419          }
420
421          // w_20 -- check width, title and units.
422          if(head.canUseThirdAxis()){
423            if(head.getSpectralUnits().size()>0)
424              newset[W20].setUnits("[" + head.getSpectralUnits() + "]");
425            tempwidth = newset[W20].getUnits().size() + 1;
426            for(int i=newset[W20].getWidth();i<tempwidth;i++)newset[W20].widen();
[623]427            val = obj->getW20();
[463]428            if((fabs(val) < 1.)&&(val>0.)){
429              minval = pow(10, -1. * (newset[W20].getPrecision()+1));
430              if(val < minval) newset[W20].upPrec();
431            }
432            tempwidth = int( log10(fabs(val)) + 1) + newset[W20].getPrecision() + 2;
433            if(val<0) tempwidth++;
434            for(int i=newset[W20].getWidth();i<tempwidth;i++) newset[W20].widen();
435          }
436
[378]437          // w_Vel -- check width, title and units.
438          if(head.canUseThirdAxis()){
[479]439            if(head.WCS().spec < 0) // if it's not a spectral axis
440              newset[WVEL].setName( std::string("w_") + head.WCS().ctype[2] );
[491]441//          else if(head.WCS().restfrq == 0) // using frequency, not velocity
442            else if(head.getSpectralDescription()==duchamp::duchampSpectralDescription[FREQUENCY]) // using frequency, not velocity
[378]443              newset[WVEL].setName("w_FREQ");
444            if(head.getSpectralUnits().size()>0)
445              newset[WVEL].setUnits("[" + head.getSpectralUnits() + "]");
446            tempwidth = newset[WVEL].getUnits().size() + 1;
447            for(int i=newset[WVEL].getWidth();i<tempwidth;i++)newset[WVEL].widen();
[479]448            tempwidth = newset[WVEL].getName().size() + 1;
449            for(int i=newset[WVEL].getWidth();i<tempwidth;i++) newset[WVEL].widen();
[623]450            val = obj->getVelWidth();
[378]451            if((fabs(val) < 1.)&&(val>0.)){
452              minval = pow(10, -1. * (newset[WVEL].getPrecision()+1));
453              if(val < minval) newset[WVEL].upPrec();
454            }
455            tempwidth = int( log10(fabs(val)) + 1) + newset[WVEL].getPrecision() + 2;
456            if(val<0) tempwidth++;
457            for(int i=newset[WVEL].getWidth();i<tempwidth;i++) newset[WVEL].widen();
458          }
[136]459
[378]460          // F_int -- check width & units
461          if(head.getIntFluxUnits().size()>0)
462            newset[FINT].setUnits("[" + head.getIntFluxUnits() + "]");
463          tempwidth = newset[FINT].getUnits().size() + 1;
464          for(int i=newset[FINT].getWidth();i<tempwidth;i++) newset[FINT].widen();
[623]465          val = obj->getIntegFlux();
[378]466          if((fabs(val) < 1.)// &&(val>0.)
467             ){
468            int minprec = int(fabs(log10(fabs(val))))+2;
469            for(int i=newset[FINT].getPrecision();i<minprec;i++) newset[FINT].upPrec();
470          }
471          tempwidth = int( log10(fabs(val)) + 1) + newset[FINT].getPrecision() + 2;
472          if(val<0) tempwidth++;
473          for(int i=newset[FINT].getWidth();i<tempwidth;i++) newset[FINT].widen();
[365]474     
[378]475        }
[136]476
[378]477        // F_tot
478        newset[FTOT].setUnits("[" + head.getFluxUnits() + "]");
479        tempwidth = newset[FTOT].getUnits().size() + 1;
480        for(int i=newset[FTOT].getWidth();i<tempwidth;i++) newset[FTOT].widen();
[623]481        val = obj->getTotalFlux();
[378]482        //     std::cerr << val << "\n";
483        if((fabs(val) < 1.)// &&(val>0.)
484           ){
485          int minprec = int(fabs(log10(fabs(val))))+2;
486          for(int i=newset[FTOT].getPrecision();i<minprec;i++) newset[FTOT].upPrec();
487        }
488        tempwidth = int( log10(fabs(val)) + 1) + newset[FTOT].getPrecision() + 2;
489        if(val<0) tempwidth++;
490        for(int i=newset[FTOT].getWidth();i<tempwidth;i++) newset[FTOT].widen();
[136]491
[378]492        // F_peak
493        newset[FPEAK].setUnits("[" + head.getFluxUnits() + "]");
494        tempwidth = newset[FPEAK].getUnits().size() + 1;
495        for(int i=newset[FPEAK].getWidth();i<tempwidth;i++) newset[FPEAK].widen();
[623]496        val = obj->getPeakFlux();
[378]497        if((fabs(val) < 1.)// &&(val>0.)
498           ){
499          int minprec = int(fabs(log10(fabs(val))))+2;
500          for(int i=newset[FPEAK].getPrecision();i<minprec;i++) newset[FPEAK].upPrec();
501        }
502        tempwidth = int( log10(fabs(val)) + 1) + newset[FPEAK].getPrecision() + 2;
503        if(val<0) tempwidth++;
504        for(int i=newset[FPEAK].getWidth();i<tempwidth;i++) newset[FPEAK].widen();
[136]505
[378]506        // S/N_peak
[623]507        val = obj->getPeakSNR();
[378]508        if((fabs(val) < 1.)&&(val>0.)){
509          minval = pow(10, -1. * (newset[SNRPEAK].getPrecision()+1));
510          if(val < minval) newset[SNRPEAK].upPrec();
511        }
512        tempwidth = int( log10(fabs(val)) + 1) + newset[SNRPEAK].getPrecision() +2;
513        if(val<0) tempwidth++;
514        for(int i=newset[SNRPEAK].getWidth();i<tempwidth;i++) newset[SNRPEAK].widen();
[191]515
[378]516        // X1 position
[623]517        val = obj->getXmin() + obj->getXOffset();
[378]518        tempwidth = int( log10(val) + 1) + newset[X1].getPrecision() + 1;
519        for(int i=newset[X1].getWidth();i<tempwidth;i++) newset[X1].widen();
520        // X2 position
[623]521        val = obj->getXmax() + obj->getXOffset();
[378]522        tempwidth = int( log10(val) + 1) + newset[X2].getPrecision() + 1;
523        for(int i=newset[X2].getWidth();i<tempwidth;i++) newset[X2].widen();
524        // Y1 position
[623]525        val = obj->getYmin() + obj->getYOffset();
[378]526        tempwidth = int( log10(val) + 1) + newset[Y1].getPrecision() + 1;
527        for(int i=newset[Y1].getWidth();i<tempwidth;i++) newset[Y1].widen();
528        // Y2 position
[623]529        val = obj->getYmax() + obj->getYOffset();
[378]530        tempwidth = int( log10(val) + 1) + newset[Y2].getPrecision() + 1;
531        for(int i=newset[Y2].getWidth();i<tempwidth;i++) newset[Y2].widen();
532        // Z1 position
[623]533        val = obj->getZmin() + obj->getZOffset();
[378]534        tempwidth = int( log10(val) + 1) + newset[Z1].getPrecision() + 1;
535        for(int i=newset[Z1].getWidth();i<tempwidth;i++) newset[Z1].widen();
536        // Z2 position
[623]537        val = obj->getZmax() + obj->getZOffset();
[378]538        tempwidth = int( log10(val) + 1) + newset[Z2].getPrecision() + 1;
539        for(int i=newset[Z2].getWidth();i<tempwidth;i++) newset[Z2].widen();
[136]540
[378]541        // Npix
[623]542        tempwidth = int( log10(obj->getSize()) + 1) +
[378]543          newset[NPIX].getPrecision() + 1;
544        for(int i=newset[NPIX].getWidth();i<tempwidth;i++) newset[NPIX].widen();
[144]545   
[378]546        // average X position
[623]547//      val = obj->getXAverage() + obj->getXOffset();
548        val = obj->getXaverage() + obj->getXOffset();
[378]549        if((val<1.)&&(val>0.)){
550          minval = pow(10, -1. * (newset[XAV].getPrecision()+1));
551          if(val < minval) newset[XAV].upPrec();
552        }
553        tempwidth = int( log10(val) + 1) + newset[XAV].getPrecision() + 2;
554        for(int i=newset[XAV].getWidth();i<tempwidth;i++) newset[XAV].widen();
555        // average Y position
[623]556//      val = obj->getYAverage() + obj->getYOffset();
557        val = obj->getYaverage() + obj->getYOffset();
[378]558        if((val<1.)&&(val>0.)){
559          minval = pow(10, -1. * (newset[YAV].getPrecision()+1));
560          if(val < minval) newset[YAV].upPrec();
561        }
562        tempwidth = int( log10(val) + 1) + newset[YAV].getPrecision() + 2;
563        for(int i=newset[YAV].getWidth();i<tempwidth;i++) newset[YAV].widen();
564        // average Z position
[623]565//      val = obj->getZAverage() + obj->getZOffset();
566        val = obj->getZaverage() + obj->getZOffset();
[378]567        if((val<1.)&&(val>0.)){
568          minval = pow(10, -1. * (newset[ZAV].getPrecision()+1));
569          if((val>0.)&&(val < minval)) newset[ZAV].upPrec();
570        }
571        tempwidth = int( log10(val) + 1) + newset[ZAV].getPrecision() + 2;
572        for(int i=newset[ZAV].getWidth();i<tempwidth;i++) newset[ZAV].widen();
[265]573   
[378]574        // X position of centroid
[623]575        val = obj->getXCentroid() + obj->getXOffset();
[378]576        if((val<1.)&&(val>0.)){
577          minval = pow(10, -1. * (newset[XCENT].getPrecision()+1));
578          if(val < minval) newset[XCENT].upPrec();
579        }
580        tempwidth = int( log10(val) + 1) + newset[XCENT].getPrecision() + 2;
581        for(int i=newset[XCENT].getWidth();i<tempwidth;i++) newset[XCENT].widen();
582        // Y position of centroid
[623]583        val = obj->getYCentroid() + obj->getYOffset();
[378]584        if((val<1.)&&(val>0.)){
585          minval = pow(10, -1. * (newset[YCENT].getPrecision()+1));
586          if(val < minval) newset[YCENT].upPrec();
587        }
588        tempwidth = int( log10(val) + 1) + newset[YCENT].getPrecision() + 2;
589        for(int i=newset[YCENT].getWidth();i<tempwidth;i++) newset[YCENT].widen();
590        // Z position of centroid
[623]591        val = obj->getZCentroid() + obj->getZOffset();
[378]592        if((val<1.)&&(val>0.)){
593          minval = pow(10, -1. * (newset[ZCENT].getPrecision()+1));
594          if((val>0.)&&(val < minval)) newset[ZCENT].upPrec();
595        }
596        tempwidth = int( log10(val) + 1) + newset[ZCENT].getPrecision() + 2;
597        for(int i=newset[ZCENT].getWidth();i<tempwidth;i++) newset[ZCENT].widen();
[265]598   
[378]599        // X position of peak flux
[623]600        val = obj->getXPeak() + obj->getXOffset();
[378]601        if((val<1.)&&(val>0.)){
602          minval = pow(10, -1. * (newset[XPEAK].getPrecision()+1));
603          if(val < minval) newset[XPEAK].upPrec();
604        }
605        tempwidth = int( log10(val) + 1) + newset[XPEAK].getPrecision() + 2;
606        for(int i=newset[XPEAK].getWidth();i<tempwidth;i++) newset[XPEAK].widen();
607        // Y position of peak flux
[623]608        val = obj->getYPeak() + obj->getYOffset();
[378]609        if((val<1.)&&(val>0.)){
610          minval = pow(10, -1. * (newset[YPEAK].getPrecision()+1));
611          if(val < minval) newset[YPEAK].upPrec();
612        }
613        tempwidth = int( log10(val) + 1) + newset[YPEAK].getPrecision() + 2;
614        for(int i=newset[YPEAK].getWidth();i<tempwidth;i++) newset[YPEAK].widen();
615        // Z position of peak flux
[623]616        val = obj->getZPeak() + obj->getZOffset();
[378]617        if((val<1.)&&(val>0.)){
618          minval = pow(10, -1. * (newset[ZPEAK].getPrecision()+1));
619          if((val>0.)&&(val < minval)) newset[ZPEAK].upPrec();
620        }
621        tempwidth = int( log10(val) + 1) + newset[ZPEAK].getPrecision() + 2;
622        for(int i=newset[ZPEAK].getWidth();i<tempwidth;i++) newset[ZPEAK].widen();
[688]623
624        //Number of contiguous channels
625        tempwidth = int( log10(obj->getMaxAdjacentChannels()) + 1) +
626          newset[NUMCH].getPrecision() + 1;
627        for(int i=newset[NUMCH].getWidth();i<tempwidth;i++) newset[NUMCH].widen();
628        //Spatial size
629        tempwidth = int( log10(obj->getSpatialSize()) + 1) +
630          newset[SPATSIZE].getPrecision() + 1;
631        for(int i=newset[SPATSIZE].getWidth();i<tempwidth;i++) newset[SPATSIZE].widen();
632       
[378]633      }
[688]634     
[378]635      return newset;
[136]636
[378]637    }
[136]638
[378]639    std::vector<Col> getLogColSet(std::vector<Detection> &objectList,
640                                  FitsHeader &head)
641    {
[528]642      ///  @details A function that returns a std::vector of Col
643      ///    objects containing information on the columns necessary
644      ///    for logfile output:
645      ///    Obj#,X,Y,Z,F_tot,F_peak,X1,X2,Y1,Y2,Z1,Z2,Npix
646      ///
647      ///   Each object in the provided objectList is checked to see if
648      ///    it requires any column to be widened, or for that column to
649      ///    have its precision increased.
650      ///
651      /// \param objectList A std::vector list of Detection objects that the columns need to fit.
652      /// \param head The FitsHeader object defining the World Coordinate System.
653      /// \return A std::vector list of Col definitions.
[136]654
[378]655      std::vector<Col> newset,tempset;
[136]656 
[378]657      // set up the default columns:
658      //  get from FullColSet, and select only the ones we want.
659      tempset = getFullColSet(objectList,head);
[136]660
[378]661      newset.push_back( tempset[NUM] );
662      newset.push_back( tempset[X] );
663      newset.push_back( tempset[Y] );
664      newset.push_back( tempset[Z] );
665      newset.push_back( tempset[FTOT] );
666      newset.push_back( tempset[FPEAK] );
667      newset.push_back( tempset[SNRPEAK] );
668      newset.push_back( tempset[X1] );
669      newset.push_back( tempset[X2] );
670      newset.push_back( tempset[Y1] );
671      newset.push_back( tempset[Y2] );
672      newset.push_back( tempset[Z1] );
673      newset.push_back( tempset[Z2] );
674      newset.push_back( tempset[NPIX] );
[688]675      newset.push_back( tempset[NUMCH] );
676      newset.push_back( tempset[SPATSIZE] );
[136]677
[378]678      return newset;
[93]679
[378]680    }
681
682  }
683
[93]684}
Note: See TracBrowser for help on using the repository browser.