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

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

First lot of changes addressing the spectral WCS issue #146. This removes the large bit of code in wcsIO that tries to analyse the spectral type and convert to standard
forms, and instead just makes use of what is in the FITS file. There are a few additions to both FitsHeader? and Detection to keep track of the spectral type (for the
purposes of writing out the results), and to how the spectral columns are named (this now makes use of the four-letter ctype code, or "S-type" code).

File size: 26.0 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/Detection/columns.hh>
38
39namespace duchamp
40{
41
42  namespace Column
43  {
44
45
46    Col::Col()
47    {
48      /// @brief Set the default values for the parameters.
49      this->width=1;
50      this->precision=0;
51      this->name=" ";
52      this->units=" ";
53      this->type=UNKNOWN;
54    }
55
56    Col::~Col(){}
57
58    Col::Col(const Col& c)
59    {
60      operator=(c);
61    }
62
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;
70      this->type = c.type;
71      return *this;
72    }
73
74    Col::Col(int num, int prec)
75    {
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
84      if((num>=0)&&(num<numColumns)){
85        this->width     = defaultWidth[num];
86        if(prec<0) this->precision = defaultPrec[num];
87        else this->precision = prec;
88        this->name      = defaultName[num];
89        this->units     = defaultUnits[num];
90        this->type = COLNAME(num);
91      }
92      else{
93        DUCHAMPERROR("Column constructor", "Incorrect value for Col(num) --> num="<<num << ", should be between 0 and " << numColumns-1);
94        this->width = 1;
95        this->precision = 0;
96        this->name = " ";
97        this->units = " ";
98        this->type=UNKNOWN;
99      }
100    }
101
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
118    //------------------------------------------------------------
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    //------------------------------------------------------------
134    void Col::printTitle(std::ostream &stream)
135    {
136      stream << std::setw(this->width)
137             << std::setfill(' ')
138             << this->name;
139    }
140
141    void Col::printUnits(std::ostream &stream)
142    {
143      stream << std::setw(this->width)
144             << std::setfill(' ')
145             << this->units;
146    }
147 
148    void Col::printDash (std::ostream &stream)
149    {
150      stream << std::setw(this->width)
151             << std::setfill('-')
152             << ""
153             << std::setfill(' ');
154    }
155
156    void Col::printBlank(std::ostream &stream)
157    {
158      stream << std::setw(this->width)
159             << std::setfill(' ')
160             << "";
161    }
162 
163    template <class T> void Col::printEntry(std::ostream &stream, T value)
164    {
165      ///  \param stream Where the printing is done.
166      ///  \param value  The value to be printed.
167
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);
175    template void Col::printEntry<unsigned int>(std::ostream &stream, unsigned int value);
176    template void Col::printEntry<unsigned long>(std::ostream &stream, unsigned long value);
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);
180
181 
182    bool Col::doCol(std::string tableType, bool flagFint)
183    {
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.
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
210 
211
212    std::vector<Col> getFullColSet(std::vector<Detection> &objectList,
213                                   FitsHeader &head)
214    {
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.
234
235      std::vector<Col> newset;
236
237      // desired precisions for fluxes, velocities and SNR value
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.
242        precSNR=objectList[0].getSNRPrec();
243      }
244      else {
245        precVel = prVEL;
246        precFlux = prFLUX;
247        precSNR = prSNR;
248      }
249
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) );
258      newset.push_back( Col(RAJD) );
259      newset.push_back( Col(DECJD) );
260      newset.push_back( Col(VEL, precVel) );
261      newset.push_back( Col(WRA) );
262      newset.push_back( Col(WDEC) );
263      newset.push_back( Col(W50, precVel) );
264      newset.push_back( Col(W20, precVel) );
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) );
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) );
287      newset.push_back( Col(NUMCH) );
288      newset.push_back( Col(SPATSIZE) );
289
290
291      // Now test each object against each new column
292      std::vector<Detection>::iterator obj;
293      for(obj = objectList.begin(); obj < objectList.end(); obj++){
294        std::string tempstr;
295        int tempwidth;
296        float val,minval;
297
298        // Obj#
299        tempwidth = int( log10(obj->getID()) + 1) + 1;
300        for(int i=newset[NUM].getWidth();i<tempwidth;i++) newset[NUM].widen();
301
302        // Name
303        tempwidth = obj->getName().size() + 1;
304        for(int i=newset[NAME].getWidth();i<tempwidth;i++) newset[NAME].widen();
305
306        // X position
307        val = obj->getXcentre() + obj->getXOffset();
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
315        val = obj->getYcentre() + obj->getYOffset();
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
323        val = obj->getZcentre() + obj->getZOffset();
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();
330
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);
335          tempwidth = obj->getRAs().size() + 1;
336          for(int i=newset[RA].getWidth();i<tempwidth;i++) newset[RA].widen();
337     
338          // Dec -- assign correct title. Check width, should be ok by definition
339          tempstr = head.WCS().lattyp;
340          newset[DEC].setName(tempstr);
341          tempwidth = obj->getDecs().size() + 1;
342          for(int i=newset[DEC].getWidth();i<tempwidth;i++) newset[DEC].widen();
343
344          // RA decimal degrees -- assign correct title. Check width but should be OK
345          tempstr = head.WCS().lngtyp;
346          newset[RAJD].setName(tempstr);
347          val = obj->getRA();
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);
354          val = obj->getDec();
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
358          // Vel -- check width, title and units.
359          //if(head.isSpecOK()){
360          if(head.canUseThirdAxis()){
361            if(head.WCS().spec < 0)  // if it's not a spectral axis
362              newset[VEL].setName( head.WCS().ctype[2] );
363//          else if(head.WCS().restfrq == 0) // using frequency, not velocity
364//          else if(head.getSpectralDescription()==duchamp::duchampSpectralDescription[FREQUENCY]) // using frequency, not velocity
365//            newset[VEL].setName("FREQ");
366            else
367              newset[VEL].setName(head.getSpectralType());
368            tempwidth = newset[VEL].getName().size() + 1;
369            for(int i=newset[VEL].getWidth();i<tempwidth;i++) newset[VEL].widen();
370            if(head.getSpectralUnits().size()>0)
371              newset[VEL].setUnits("[" + head.getSpectralUnits() + "]");
372            tempwidth = newset[VEL].getUnits().size() + 1;
373            for(int i=newset[VEL].getWidth();i<tempwidth;i++) newset[VEL].widen();
374       
375            val = obj->getVel();
376            if((fabs(val) < 1.)&&(val>0.)){
377              minval = pow(10, -1. * (newset[VEL].getPrecision()+1));
378              if(val < minval) newset[VEL].upPrec();
379            }
380            tempwidth = int(log10(fabs(val)) + 1) + newset[VEL].getPrecision() + 2;
381            if(val<0) tempwidth++;
382            for(int i=newset[VEL].getWidth();i<tempwidth;i++) newset[VEL].widen();
383          }
384
385          // w_RA -- check width & title. leave units for the moment.
386          tempwidth = newset[RA].getUnits().size() + 1;
387          for(int i=newset[RA].getWidth();i<tempwidth;i++) newset[RA].widen();
388          val = obj->getRAWidth();
389          if((fabs(val) < 1.)&&(val>0.)){
390            minval = pow(10, -1. * (newset[WRA].getPrecision()+1));
391            if(val < minval) newset[WRA].upPrec();
392          }
393          tempwidth = int( log10(fabs(val)) + 1) + newset[WRA].getPrecision() + 2;
394          if(val<0) tempwidth++;
395          for(int i=newset[WRA].getWidth();i<tempwidth;i++) newset[WRA].widen();
396
397          // w_DEC -- check width & title. leave units for the moment.
398          tempwidth = newset[DEC].getUnits().size() + 1;
399          for(int i=newset[DEC].getWidth();i<tempwidth;i++) newset[DEC].widen();
400          val = obj->getDecWidth();
401          if((fabs(val) < 1.)&&(val>0.)){
402            minval = pow(10, -1. * (newset[WDEC].getPrecision()+1));
403            if(val < minval) newset[WDEC].upPrec();
404          }
405          tempwidth = int( log10(fabs(val)) + 1) + newset[WDEC].getPrecision() + 2;
406          if(val<0) tempwidth++;
407          for(int i=newset[WDEC].getWidth();i<tempwidth;i++) newset[WDEC].widen();
408
409          // w_50 -- check width, title and units.
410          if(head.canUseThirdAxis()){
411            if(head.getSpectralUnits().size()>0)
412              newset[W50].setUnits("[" + head.getSpectralUnits() + "]");
413            tempwidth = newset[W50].getUnits().size() + 1;
414            for(int i=newset[W50].getWidth();i<tempwidth;i++) newset[W50].widen();
415            val = obj->getW50();
416            if((fabs(val) < 1.)&&(val>0.)){
417              minval = pow(10, -1. * (newset[W50].getPrecision()+1));
418              if(val < minval) newset[W50].upPrec();
419            }
420            tempwidth = int( log10(fabs(val)) + 1) + newset[W50].getPrecision() + 2;
421            if(val<0) tempwidth++;
422            for(int i=newset[W50].getWidth();i<tempwidth;i++) newset[W50].widen();
423          }
424
425          // w_20 -- check width, title and units.
426          if(head.canUseThirdAxis()){
427            if(head.getSpectralUnits().size()>0)
428              newset[W20].setUnits("[" + head.getSpectralUnits() + "]");
429            tempwidth = newset[W20].getUnits().size() + 1;
430            for(int i=newset[W20].getWidth();i<tempwidth;i++)newset[W20].widen();
431            val = obj->getW20();
432            if((fabs(val) < 1.)&&(val>0.)){
433              minval = pow(10, -1. * (newset[W20].getPrecision()+1));
434              if(val < minval) newset[W20].upPrec();
435            }
436            tempwidth = int( log10(fabs(val)) + 1) + newset[W20].getPrecision() + 2;
437            if(val<0) tempwidth++;
438            for(int i=newset[W20].getWidth();i<tempwidth;i++) newset[W20].widen();
439          }
440
441          // w_Vel -- check width, title and units.
442          if(head.canUseThirdAxis()){
443            if(head.WCS().spec < 0) // if it's not a spectral axis
444              newset[WVEL].setName( std::string("w_") + head.WCS().ctype[2] );
445// //       else if(head.WCS().restfrq == 0) // using frequency, not velocity
446//          else if(head.getSpectralDescription()==duchamp::duchampSpectralDescription[FREQUENCY]) // using frequency, not velocity
447//            newset[WVEL].setName("w_FREQ");
448            else
449              newset[WVEL].setName(std::string("w_")+head.getSpectralType());
450            if(head.getSpectralUnits().size()>0)
451              newset[WVEL].setUnits("[" + head.getSpectralUnits() + "]");
452            tempwidth = newset[WVEL].getUnits().size() + 1;
453            for(int i=newset[WVEL].getWidth();i<tempwidth;i++)newset[WVEL].widen();
454            tempwidth = newset[WVEL].getName().size() + 1;
455            for(int i=newset[WVEL].getWidth();i<tempwidth;i++) newset[WVEL].widen();
456            val = obj->getVelWidth();
457            if((fabs(val) < 1.)&&(val>0.)){
458              minval = pow(10, -1. * (newset[WVEL].getPrecision()+1));
459              if(val < minval) newset[WVEL].upPrec();
460            }
461            tempwidth = int( log10(fabs(val)) + 1) + newset[WVEL].getPrecision() + 2;
462            if(val<0) tempwidth++;
463            for(int i=newset[WVEL].getWidth();i<tempwidth;i++) newset[WVEL].widen();
464          }
465
466          // F_int -- check width & units
467          if(head.getIntFluxUnits().size()>0)
468            newset[FINT].setUnits("[" + head.getIntFluxUnits() + "]");
469          tempwidth = newset[FINT].getUnits().size() + 1;
470          for(int i=newset[FINT].getWidth();i<tempwidth;i++) newset[FINT].widen();
471          val = obj->getIntegFlux();
472          if((fabs(val) < 1.)// &&(val>0.)
473             ){
474            int minprec = int(fabs(log10(fabs(val))))+2;
475            for(int i=newset[FINT].getPrecision();i<minprec;i++) newset[FINT].upPrec();
476          }
477          tempwidth = int( log10(fabs(val)) + 1) + newset[FINT].getPrecision() + 2;
478          if(val<0) tempwidth++;
479          for(int i=newset[FINT].getWidth();i<tempwidth;i++) newset[FINT].widen();
480     
481        }
482
483        // F_tot
484        newset[FTOT].setUnits("[" + head.getFluxUnits() + "]");
485        tempwidth = newset[FTOT].getUnits().size() + 1;
486        for(int i=newset[FTOT].getWidth();i<tempwidth;i++) newset[FTOT].widen();
487        val = obj->getTotalFlux();
488        //     std::cerr << val << "\n";
489        if((fabs(val) < 1.)// &&(val>0.)
490           ){
491          int minprec = int(fabs(log10(fabs(val))))+2;
492          for(int i=newset[FTOT].getPrecision();i<minprec;i++) newset[FTOT].upPrec();
493        }
494        tempwidth = int( log10(fabs(val)) + 1) + newset[FTOT].getPrecision() + 2;
495        if(val<0) tempwidth++;
496        for(int i=newset[FTOT].getWidth();i<tempwidth;i++) newset[FTOT].widen();
497
498        // F_peak
499        newset[FPEAK].setUnits("[" + head.getFluxUnits() + "]");
500        tempwidth = newset[FPEAK].getUnits().size() + 1;
501        for(int i=newset[FPEAK].getWidth();i<tempwidth;i++) newset[FPEAK].widen();
502        val = obj->getPeakFlux();
503        if((fabs(val) < 1.)// &&(val>0.)
504           ){
505          int minprec = int(fabs(log10(fabs(val))))+2;
506          for(int i=newset[FPEAK].getPrecision();i<minprec;i++) newset[FPEAK].upPrec();
507        }
508        tempwidth = int( log10(fabs(val)) + 1) + newset[FPEAK].getPrecision() + 2;
509        if(val<0) tempwidth++;
510        for(int i=newset[FPEAK].getWidth();i<tempwidth;i++) newset[FPEAK].widen();
511
512        // S/N_peak
513        val = obj->getPeakSNR();
514        if((fabs(val) < 1.)&&(val>0.)){
515          minval = pow(10, -1. * (newset[SNRPEAK].getPrecision()+1));
516          if(val < minval) newset[SNRPEAK].upPrec();
517        }
518        tempwidth = int( log10(fabs(val)) + 1) + newset[SNRPEAK].getPrecision() +2;
519        if(val<0) tempwidth++;
520        for(int i=newset[SNRPEAK].getWidth();i<tempwidth;i++) newset[SNRPEAK].widen();
521
522        // X1 position
523        val = obj->getXmin() + obj->getXOffset();
524        tempwidth = int( log10(val) + 1) + newset[X1].getPrecision() + 1;
525        for(int i=newset[X1].getWidth();i<tempwidth;i++) newset[X1].widen();
526        // X2 position
527        val = obj->getXmax() + obj->getXOffset();
528        tempwidth = int( log10(val) + 1) + newset[X2].getPrecision() + 1;
529        for(int i=newset[X2].getWidth();i<tempwidth;i++) newset[X2].widen();
530        // Y1 position
531        val = obj->getYmin() + obj->getYOffset();
532        tempwidth = int( log10(val) + 1) + newset[Y1].getPrecision() + 1;
533        for(int i=newset[Y1].getWidth();i<tempwidth;i++) newset[Y1].widen();
534        // Y2 position
535        val = obj->getYmax() + obj->getYOffset();
536        tempwidth = int( log10(val) + 1) + newset[Y2].getPrecision() + 1;
537        for(int i=newset[Y2].getWidth();i<tempwidth;i++) newset[Y2].widen();
538        // Z1 position
539        val = obj->getZmin() + obj->getZOffset();
540        tempwidth = int( log10(val) + 1) + newset[Z1].getPrecision() + 1;
541        for(int i=newset[Z1].getWidth();i<tempwidth;i++) newset[Z1].widen();
542        // Z2 position
543        val = obj->getZmax() + obj->getZOffset();
544        tempwidth = int( log10(val) + 1) + newset[Z2].getPrecision() + 1;
545        for(int i=newset[Z2].getWidth();i<tempwidth;i++) newset[Z2].widen();
546
547        // Npix
548        tempwidth = int( log10(obj->getSize()) + 1) +
549          newset[NPIX].getPrecision() + 1;
550        for(int i=newset[NPIX].getWidth();i<tempwidth;i++) newset[NPIX].widen();
551   
552        // average X position
553//      val = obj->getXAverage() + obj->getXOffset();
554        val = obj->getXaverage() + obj->getXOffset();
555        if((val<1.)&&(val>0.)){
556          minval = pow(10, -1. * (newset[XAV].getPrecision()+1));
557          if(val < minval) newset[XAV].upPrec();
558        }
559        tempwidth = int( log10(val) + 1) + newset[XAV].getPrecision() + 2;
560        for(int i=newset[XAV].getWidth();i<tempwidth;i++) newset[XAV].widen();
561        // average Y position
562//      val = obj->getYAverage() + obj->getYOffset();
563        val = obj->getYaverage() + obj->getYOffset();
564        if((val<1.)&&(val>0.)){
565          minval = pow(10, -1. * (newset[YAV].getPrecision()+1));
566          if(val < minval) newset[YAV].upPrec();
567        }
568        tempwidth = int( log10(val) + 1) + newset[YAV].getPrecision() + 2;
569        for(int i=newset[YAV].getWidth();i<tempwidth;i++) newset[YAV].widen();
570        // average Z position
571//      val = obj->getZAverage() + obj->getZOffset();
572        val = obj->getZaverage() + obj->getZOffset();
573        if((val<1.)&&(val>0.)){
574          minval = pow(10, -1. * (newset[ZAV].getPrecision()+1));
575          if((val>0.)&&(val < minval)) newset[ZAV].upPrec();
576        }
577        tempwidth = int( log10(val) + 1) + newset[ZAV].getPrecision() + 2;
578        for(int i=newset[ZAV].getWidth();i<tempwidth;i++) newset[ZAV].widen();
579   
580        // X position of centroid
581        val = obj->getXCentroid() + obj->getXOffset();
582        if((val<1.)&&(val>0.)){
583          minval = pow(10, -1. * (newset[XCENT].getPrecision()+1));
584          if(val < minval) newset[XCENT].upPrec();
585        }
586        tempwidth = int( log10(val) + 1) + newset[XCENT].getPrecision() + 2;
587        for(int i=newset[XCENT].getWidth();i<tempwidth;i++) newset[XCENT].widen();
588        // Y position of centroid
589        val = obj->getYCentroid() + obj->getYOffset();
590        if((val<1.)&&(val>0.)){
591          minval = pow(10, -1. * (newset[YCENT].getPrecision()+1));
592          if(val < minval) newset[YCENT].upPrec();
593        }
594        tempwidth = int( log10(val) + 1) + newset[YCENT].getPrecision() + 2;
595        for(int i=newset[YCENT].getWidth();i<tempwidth;i++) newset[YCENT].widen();
596        // Z position of centroid
597        val = obj->getZCentroid() + obj->getZOffset();
598        if((val<1.)&&(val>0.)){
599          minval = pow(10, -1. * (newset[ZCENT].getPrecision()+1));
600          if((val>0.)&&(val < minval)) newset[ZCENT].upPrec();
601        }
602        tempwidth = int( log10(val) + 1) + newset[ZCENT].getPrecision() + 2;
603        for(int i=newset[ZCENT].getWidth();i<tempwidth;i++) newset[ZCENT].widen();
604   
605        // X position of peak flux
606        val = obj->getXPeak() + obj->getXOffset();
607        if((val<1.)&&(val>0.)){
608          minval = pow(10, -1. * (newset[XPEAK].getPrecision()+1));
609          if(val < minval) newset[XPEAK].upPrec();
610        }
611        tempwidth = int( log10(val) + 1) + newset[XPEAK].getPrecision() + 2;
612        for(int i=newset[XPEAK].getWidth();i<tempwidth;i++) newset[XPEAK].widen();
613        // Y position of peak flux
614        val = obj->getYPeak() + obj->getYOffset();
615        if((val<1.)&&(val>0.)){
616          minval = pow(10, -1. * (newset[YPEAK].getPrecision()+1));
617          if(val < minval) newset[YPEAK].upPrec();
618        }
619        tempwidth = int( log10(val) + 1) + newset[YPEAK].getPrecision() + 2;
620        for(int i=newset[YPEAK].getWidth();i<tempwidth;i++) newset[YPEAK].widen();
621        // Z position of peak flux
622        val = obj->getZPeak() + obj->getZOffset();
623        if((val<1.)&&(val>0.)){
624          minval = pow(10, -1. * (newset[ZPEAK].getPrecision()+1));
625          if((val>0.)&&(val < minval)) newset[ZPEAK].upPrec();
626        }
627        tempwidth = int( log10(val) + 1) + newset[ZPEAK].getPrecision() + 2;
628        for(int i=newset[ZPEAK].getWidth();i<tempwidth;i++) newset[ZPEAK].widen();
629
630        //Number of contiguous channels
631        tempwidth = int( log10(obj->getMaxAdjacentChannels()) + 1) +
632          newset[NUMCH].getPrecision() + 1;
633        for(int i=newset[NUMCH].getWidth();i<tempwidth;i++) newset[NUMCH].widen();
634        //Spatial size
635        tempwidth = int( log10(obj->getSpatialSize()) + 1) +
636          newset[SPATSIZE].getPrecision() + 1;
637        for(int i=newset[SPATSIZE].getWidth();i<tempwidth;i++) newset[SPATSIZE].widen();
638       
639      }
640     
641      return newset;
642
643    }
644
645    std::vector<Col> getLogColSet(std::vector<Detection> &objectList,
646                                  FitsHeader &head)
647    {
648      ///  @details A function that returns a std::vector of Col
649      ///    objects containing information on the columns necessary
650      ///    for logfile output:
651      ///    Obj#,X,Y,Z,F_tot,F_peak,X1,X2,Y1,Y2,Z1,Z2,Npix
652      ///
653      ///   Each object in the provided objectList is checked to see if
654      ///    it requires any column to be widened, or for that column to
655      ///    have its precision increased.
656      ///
657      /// \param objectList A std::vector list of Detection objects that the columns need to fit.
658      /// \param head The FitsHeader object defining the World Coordinate System.
659      /// \return A std::vector list of Col definitions.
660
661      std::vector<Col> newset,tempset;
662 
663      // set up the default columns:
664      //  get from FullColSet, and select only the ones we want.
665      tempset = getFullColSet(objectList,head);
666
667      newset.push_back( tempset[NUM] );
668      newset.push_back( tempset[X] );
669      newset.push_back( tempset[Y] );
670      newset.push_back( tempset[Z] );
671      newset.push_back( tempset[FTOT] );
672      newset.push_back( tempset[FPEAK] );
673      newset.push_back( tempset[SNRPEAK] );
674      newset.push_back( tempset[X1] );
675      newset.push_back( tempset[X2] );
676      newset.push_back( tempset[Y1] );
677      newset.push_back( tempset[Y2] );
678      newset.push_back( tempset[Z1] );
679      newset.push_back( tempset[Z2] );
680      newset.push_back( tempset[NPIX] );
681      newset.push_back( tempset[NUMCH] );
682      newset.push_back( tempset[SPATSIZE] );
683
684      return newset;
685
686    }
687
688  }
689
690}
Note: See TracBrowser for help on using the repository browser.