source: tags/release-1.1.1/src/Detection/columns.cc @ 1213

Last change on this file since 1213 was 326, checked in by MatthewWhiting, 17 years ago

Updated doxygen file, and minor fix to columns.cc

File size: 18.6 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.hh>
33#include <fitsHeader.hh>
34#include <vector>
35#include <string>
36#include <Detection/detection.hh>
37#include <Detection/columns.hh>
38
39using namespace Column;
40
41namespace Column
42{
43
44  Col::Col()
45  {
46    /** Set the default values for the parameters. */
47    width=1;
48    precision=0;
49    name=" ";
50    units=" ";
51  };
52
53  Col::~Col(){}
54
55  Col::Col(int num)
56  {
57    /**
58     * A specialised constructor that defines one of the default
59     *  columns, as defined in the Column namespace
60     * \param num The number of the column to be constructed.
61     *            Corresponds to the order of the columns in the const
62     *            arrays in the Column namespace.
63     */
64    if((num>=0)&&(num<numColumns)){
65      this->width     = defaultWidth[num];
66      this->precision = defaultPrec[num];
67      this->name      = defaultName[num];
68      this->units     = defaultUnits[num];
69    }
70    else{
71      std::stringstream errmsg;
72      errmsg << "Incorrect value for Col(num) --> num="<<num
73             << ", should be between 0 and " << numColumns-1 << ".\n";
74      duchampError("Column constructor", errmsg.str());
75      this->width = 1;
76      this->precision = 0;
77      this->name = " ";
78      this->units = " ";
79    }
80  }
81  //------------------------------------------------------------
82  void Col::printTitle(std::ostream &stream)
83  {
84    stream << std::setw(this->width)
85           << std::setfill(' ')
86           << this->name;
87  }
88
89  void Col::printUnits(std::ostream &stream)
90  {
91    stream << std::setw(this->width)
92           << std::setfill(' ')
93           << this->units;
94  }
95 
96  void Col::printDash (std::ostream &stream)
97  {
98    stream << std::setw(this->width)
99           << std::setfill('-')
100           << ""
101           << std::setfill(' ');
102  }
103
104  void Col::printBlank(std::ostream &stream)
105  {
106    stream << std::setw(this->width)
107           << std::setfill(' ')
108           << "";
109  }
110 
111  template <class T> void Col::printEntry(std::ostream &stream, T value)
112  {
113    /**
114     *  \param stream Where the printing is done.
115     *  \param value  The value to be printed.
116     */
117    stream << std::setprecision(this->precision)
118           << std::setw(this->width)
119           << std::setfill(' ')
120           << value;
121  }
122  template void Col::printEntry<int>(std::ostream &stream, int value);
123  template void Col::printEntry<long>(std::ostream &stream, long value);
124  template void Col::printEntry<unsigned>(std::ostream &stream, unsigned value);
125  template void Col::printEntry<float>(std::ostream &stream, float value);
126  template void Col::printEntry<double>(std::ostream &stream, double value);
127  template void Col::printEntry<std::string>(std::ostream &stream, std::string value);
128
129}
130
131std::vector<Col> getFullColSet(std::vector<Detection> &objectList,
132                               FitsHeader &head)
133{
134  /**
135   *  A function that returns a std::vector of Col objects containing
136   *  information on the columns necessary for output to the results
137   *  file:
138   *    Obj#,NAME,X,Y,Z,RA,DEC,VEL,w_RA,w_DEC,w_VEL,F_tot,F_int,F_peak,
139   *                X1,X2,Y1,Y2,Z1,Z2,Npix,Flag
140   *
141   *   Each object in the provided objectList is checked to see if it
142   *   requires any column to be widened, or for that column to have
143   *   its precision increased.
144   *
145   *   Both Ftot and Fint are provided -- it is up to the calling
146   *   function to determine which to use.
147   *
148   * \param objectList A std::vector list of Detection objects that the
149   * columns need to fit.
150   * \param head The FitsHeader object defining the World Coordinate
151   * System.
152   * \return A std::vector list of Col definitions.
153   */
154
155  std::vector<Col> newset;
156
157  // set up the default columns
158
159  newset.push_back( Col(NUM) );
160  newset.push_back( Col(NAME) );
161  newset.push_back( Col(X) );
162  newset.push_back( Col(Y) );
163  newset.push_back( Col(Z) );
164  newset.push_back( Col(RA) );
165  newset.push_back( Col(DEC) );
166  newset.push_back( Col(VEL) );
167  newset.push_back( Col(WRA) );
168  newset.push_back( Col(WDEC) );
169  newset.push_back( Col(WVEL) );
170  newset.push_back( Col(FINT) );
171  newset.push_back( Col(FTOT) );
172  newset.push_back( Col(FPEAK) );
173  newset.push_back( Col(SNRPEAK) );
174  newset.push_back( Col(X1) );
175  newset.push_back( Col(X2) );
176  newset.push_back( Col(Y1) );
177  newset.push_back( Col(Y2) );
178  newset.push_back( Col(Z1) );
179  newset.push_back( Col(Z2) );
180  newset.push_back( Col(NPIX) );
181  newset.push_back( Col(FLAG) );
182  newset.push_back( Col(XAV) );
183  newset.push_back( Col(YAV) );
184  newset.push_back( Col(ZAV) );
185  newset.push_back( Col(XCENT) );
186  newset.push_back( Col(YCENT) );
187  newset.push_back( Col(ZCENT) );
188  newset.push_back( Col(XPEAK) );
189  newset.push_back( Col(YPEAK) );
190  newset.push_back( Col(ZPEAK) );
191
192  // Now test each object against each new column
193  for( int obj = 0; obj < objectList.size(); obj++){
194    std::string tempstr;
195    int tempwidth;
196    float val,minval;
197
198    // Obj#
199    tempwidth = int( log10(objectList[obj].getID()) + 1) +
200      newset[NUM].getPrecision() + 1;
201    for(int i=newset[NUM].getWidth();i<tempwidth;i++) newset[NUM].widen();
202
203    // Name
204    tempwidth = objectList[obj].getName().size() + 1;
205    for(int i=newset[NAME].getWidth();i<tempwidth;i++) newset[NAME].widen();
206
207    // X position
208    val = objectList[obj].getXcentre();
209    tempwidth = int( log10(val) + 1) + newset[X].getPrecision() + 2;
210    for(int i=newset[X].getWidth();i<tempwidth;i++) newset[X].widen();
211    if((val<1.)&&(val>0.)){
212      minval = pow(10, -1. * newset[X].getPrecision()+1);
213      if(val < minval) newset[X].upPrec();
214    }
215    // Y position
216    val = objectList[obj].getYcentre();
217    tempwidth = int( log10(val) + 1) + newset[Y].getPrecision() + 2;
218    for(int i=newset[Y].getWidth();i<tempwidth;i++) newset[Y].widen();
219    if((val<1.)&&(val>0.)){
220      minval = pow(10, -1. * newset[Y].getPrecision()+1);
221      if(val < minval) newset[Y].upPrec();
222    }
223    // Z position
224    val = objectList[obj].getZcentre();
225    tempwidth = int( log10(val) + 1) + newset[Z].getPrecision() + 2;
226    for(int i=newset[Z].getWidth();i<tempwidth;i++) newset[Z].widen();
227    if((val<1.)&&(val>0.)){
228      minval = pow(10, -1. * newset[Z].getPrecision()+1);
229      if((val>0.)&&(val < minval)) newset[Z].upPrec();
230    }
231
232    if(head.isWCS()){ 
233      // RA -- assign correct title. Check width but should be ok by definition
234      tempstr = head.WCS().lngtyp;
235      newset[RA].setName(tempstr);
236      tempwidth = objectList[obj].getRAs().size() + 1;
237      for(int i=newset[RA].getWidth();i<tempwidth;i++) newset[RA].widen();
238     
239      // Dec -- assign correct title. Check width, should be ok by definition
240      tempstr = head.WCS().lattyp;
241      newset[DEC].setName(tempstr);
242      tempwidth = objectList[obj].getDecs().size() + 1;
243      for(int i=newset[DEC].getWidth();i<tempwidth;i++) newset[DEC].widen();
244
245      // Vel -- check width, title and units.
246//       if(head.getNumAxes() > 2){
247        if(head.WCS().restfrq == 0) // using frequency, not velocity
248          newset[VEL].setName("FREQ");
249        if(head.getSpectralUnits().size()>0)
250          newset[VEL].setUnits("[" + head.getSpectralUnits() + "]");
251        tempwidth = newset[VEL].getUnits().size() + 1;
252        for(int i=newset[VEL].getWidth();i<tempwidth;i++) newset[VEL].widen();
253       
254        val = objectList[obj].getVel();
255        tempwidth = int(log10(fabs(val)) + 1) + newset[VEL].getPrecision() + 2;
256        if(val<0) tempwidth++;
257        for(int i=newset[VEL].getWidth();i<tempwidth;i++) newset[VEL].widen();
258        if((fabs(val) < 1.)&&(val>0.)){
259          minval = pow(10, -1. * newset[VEL].getPrecision()+1);
260          if(val < minval) newset[VEL].upPrec();
261        }
262//       }
263
264      // w_RA -- check width & title. leave units for the moment.
265      tempwidth = newset[RA].getUnits().size() + 1;
266      for(int i=newset[RA].getWidth();i<tempwidth;i++) newset[RA].widen();
267      val = objectList[obj].getRAWidth();
268      tempwidth = int( log10(fabs(val)) + 1) + newset[WRA].getPrecision() + 2;
269      if(val<0) tempwidth++;
270      for(int i=newset[WRA].getWidth();i<tempwidth;i++) newset[WRA].widen();
271      if((fabs(val) < 1.)&&(val>0.)){
272        minval = pow(10, -1. * newset[WRA].getPrecision()+1);
273        if(val < minval) newset[WRA].upPrec();
274      }
275
276      // w_DEC -- check width & title. leave units for the moment.
277      tempwidth = newset[DEC].getUnits().size() + 1;
278      for(int i=newset[DEC].getWidth();i<tempwidth;i++) newset[DEC].widen();
279      val = objectList[obj].getDecWidth();
280      tempwidth = int( log10(fabs(val)) + 1) + newset[WDEC].getPrecision() + 2;
281      if(val<0) tempwidth++;
282      for(int i=newset[WDEC].getWidth();i<tempwidth;i++) newset[WDEC].widen();
283      if((fabs(val) < 1.)&&(val>0.)){
284        minval = pow(10, -1. * newset[WDEC].getPrecision()+1);
285        if(val < minval) newset[WDEC].upPrec();
286      }
287
288      // w_Vel -- check width, title and units.
289//       if(head.getNumAxes() > 2){
290        if(head.WCS().restfrq == 0) // using frequency, not velocity
291          newset[WVEL].setName("w_FREQ");
292        if(head.getSpectralUnits().size()>0)
293          newset[WVEL].setUnits("[" + head.getSpectralUnits() + "]");
294        tempwidth = newset[WVEL].getUnits().size() + 1;
295        for(int i=newset[WVEL].getWidth();i<tempwidth;i++)newset[WVEL].widen();
296        val = objectList[obj].getVel();
297        tempwidth = int( log10(fabs(val)) + 1) + newset[WVEL].getPrecision() + 2;
298        if(val<0) tempwidth++;
299        for(int i=newset[WVEL].getWidth();i<tempwidth;i++) newset[WVEL].widen();
300        if((fabs(val) < 1.)&&(val>0.)){
301          minval = pow(10, -1. * newset[WVEL].getPrecision()+1);
302          if(val < minval) newset[WVEL].upPrec();
303        }
304
305        // F_int -- check width & units
306        newset[FINT].setUnits("[" + head.getIntFluxUnits() + "]");
307        tempwidth = newset[FINT].getUnits().size() + 1;
308        for(int i=newset[FINT].getWidth();i<tempwidth;i++) newset[FINT].widen();
309        val = objectList[obj].getIntegFlux();
310        tempwidth = int( log10(fabs(val)) + 1) + newset[FINT].getPrecision() + 2;
311        if(val<0) tempwidth++;
312        for(int i=newset[FINT].getWidth();i<tempwidth;i++) newset[FINT].widen();
313        if((fabs(val) < 1.)&&(val>0.)){
314          minval = pow(10, -1. * newset[FINT].getPrecision()+1);
315          if(val < minval) newset[FINT].upPrec();
316        }
317//       }
318    }
319
320    // F_tot
321    newset[FTOT].setUnits("[" + head.getFluxUnits() + "]");
322    tempwidth = newset[FTOT].getUnits().size() + 1;
323    for(int i=newset[FTOT].getWidth();i<tempwidth;i++) newset[FTOT].widen();
324    val = objectList[obj].getTotalFlux();
325    tempwidth = int( log10(fabs(val)) + 1) + newset[FTOT].getPrecision() + 2;
326    if(val<0) tempwidth++;
327    for(int i=newset[FTOT].getWidth();i<tempwidth;i++) newset[FTOT].widen();
328    if((fabs(val) < 1.)&&(val>0.)){
329      minval = pow(10, -1. * newset[FTOT].getPrecision()+1);
330      if(val < minval) newset[FTOT].upPrec();
331    }
332
333    // F_peak
334    newset[FPEAK].setUnits("[" + head.getFluxUnits() + "]");
335    tempwidth = newset[FPEAK].getUnits().size() + 1;
336    for(int i=newset[FPEAK].getWidth();i<tempwidth;i++) newset[FPEAK].widen();
337    val = objectList[obj].getPeakFlux();
338    tempwidth = int( log10(fabs(val)) + 1) + newset[FPEAK].getPrecision() + 2;
339    if(val<0) tempwidth++;
340    for(int i=newset[FPEAK].getWidth();i<tempwidth;i++) newset[FPEAK].widen();
341    if((fabs(val) < 1.)&&(val>0.)){
342      minval = pow(10, -1. * newset[FPEAK].getPrecision()+1);
343      if(val < minval) newset[FPEAK].upPrec();
344    }
345
346    // S/N_peak
347    val = objectList[obj].getPeakSNR();
348    tempwidth = int( log10(fabs(val)) + 1) + newset[SNRPEAK].getPrecision() +2;
349    if(val<0) tempwidth++;
350    for(int i=newset[SNRPEAK].getWidth();i<tempwidth;i++)
351      newset[SNRPEAK].widen();
352    if((fabs(val) < 1.)&&(val>0.)){
353      minval = pow(10, -1. * newset[SNRPEAK].getPrecision()+1);
354      if(val < minval) newset[SNRPEAK].upPrec();
355    }
356
357    // X1 position
358    tempwidth = int( log10(objectList[obj].getXmin()) + 1) +
359      newset[X1].getPrecision() + 1;
360    for(int i=newset[X1].getWidth();i<tempwidth;i++) newset[X1].widen();
361    // X2 position
362    tempwidth = int( log10(objectList[obj].getXmax()) + 1) +
363      newset[X2].getPrecision() + 1;
364    for(int i=newset[X2].getWidth();i<tempwidth;i++) newset[X2].widen();
365    // Y1 position
366    tempwidth = int( log10(objectList[obj].getYmin()) + 1) +
367      newset[Y1].getPrecision() + 1;
368    for(int i=newset[Y1].getWidth();i<tempwidth;i++) newset[Y1].widen();
369    // Y2 position
370    tempwidth = int( log10(objectList[obj].getYmax()) + 1) +
371      newset[Y2].getPrecision() + 1;
372    for(int i=newset[Y2].getWidth();i<tempwidth;i++) newset[Y2].widen();
373    // Z1 position
374    tempwidth = int( log10(objectList[obj].getZmin()) + 1) +
375      newset[Z1].getPrecision() + 1;
376    for(int i=newset[Z1].getWidth();i<tempwidth;i++) newset[Z1].widen();
377    // Z2 position
378    tempwidth = int( log10(objectList[obj].getZmax()) + 1) +
379      newset[Z2].getPrecision() + 1;
380    for(int i=newset[Z2].getWidth();i<tempwidth;i++) newset[Z2].widen();
381
382    // Npix
383    tempwidth = int( log10(objectList[obj].getSize()) + 1) +
384      newset[NPIX].getPrecision() + 1;
385    for(int i=newset[NPIX].getWidth();i<tempwidth;i++) newset[NPIX].widen();
386   
387    // average X position
388    val = objectList[obj].getXAverage();
389    tempwidth = int( log10(val) + 1) + newset[XAV].getPrecision() + 2;
390    for(int i=newset[XAV].getWidth();i<tempwidth;i++) newset[XAV].widen();
391    if((val<1.)&&(val>0.)){
392      minval = pow(10, -1. * newset[XAV].getPrecision()+1);
393      if(val < minval) newset[XAV].upPrec();
394    }
395    // average Y position
396    val = objectList[obj].getYAverage();
397    tempwidth = int( log10(val) + 1) + newset[YAV].getPrecision() + 2;
398    for(int i=newset[YAV].getWidth();i<tempwidth;i++) newset[YAV].widen();
399    if((val<1.)&&(val>0.)){
400      minval = pow(10, -1. * newset[YAV].getPrecision()+1);
401      if(val < minval) newset[YAV].upPrec();
402    }
403    // average Z position
404    val = objectList[obj].getZAverage();
405    tempwidth = int( log10(val) + 1) + newset[ZAV].getPrecision() + 2;
406    for(int i=newset[ZAV].getWidth();i<tempwidth;i++) newset[ZAV].widen();
407    if((val<1.)&&(val>0.)){
408      minval = pow(10, -1. * newset[ZAV].getPrecision()+1);
409      if((val>0.)&&(val < minval)) newset[ZAV].upPrec();
410    }
411   
412    // X position of centroid
413    val = objectList[obj].getXCentroid();
414    tempwidth = int( log10(val) + 1) + newset[XCENT].getPrecision() + 2;
415    for(int i=newset[XCENT].getWidth();i<tempwidth;i++) newset[XCENT].widen();
416    if((val<1.)&&(val>0.)){
417      minval = pow(10, -1. * newset[XCENT].getPrecision()+1);
418      if(val < minval) newset[XCENT].upPrec();
419    }
420    // Y position of centroid
421    val = objectList[obj].getYCentroid();
422    tempwidth = int( log10(val) + 1) + newset[YCENT].getPrecision() + 2;
423    for(int i=newset[YCENT].getWidth();i<tempwidth;i++) newset[YCENT].widen();
424    if((val<1.)&&(val>0.)){
425      minval = pow(10, -1. * newset[YCENT].getPrecision()+1);
426      if(val < minval) newset[YCENT].upPrec();
427    }
428    // Z position of centroid
429    val = objectList[obj].getZCentroid();
430    tempwidth = int( log10(val) + 1) + newset[ZCENT].getPrecision() + 2;
431    for(int i=newset[ZCENT].getWidth();i<tempwidth;i++) newset[ZCENT].widen();
432    if((val<1.)&&(val>0.)){
433      minval = pow(10, -1. * newset[ZCENT].getPrecision()+1);
434      if((val>0.)&&(val < minval)) newset[ZCENT].upPrec();
435    }
436   
437    // X position of peak flux
438    val = objectList[obj].getXPeak();
439    tempwidth = int( log10(val) + 1) + newset[XPEAK].getPrecision() + 2;
440    for(int i=newset[XPEAK].getWidth();i<tempwidth;i++) newset[XPEAK].widen();
441    if((val<1.)&&(val>0.)){
442      minval = pow(10, -1. * newset[XPEAK].getPrecision()+1);
443      if(val < minval) newset[XPEAK].upPrec();
444    }
445    // Y position of peak flux
446    val = objectList[obj].getYPeak();
447    tempwidth = int( log10(val) + 1) + newset[YPEAK].getPrecision() + 2;
448    for(int i=newset[YPEAK].getWidth();i<tempwidth;i++) newset[YPEAK].widen();
449    if((val<1.)&&(val>0.)){
450      minval = pow(10, -1. * newset[YPEAK].getPrecision()+1);
451      if(val < minval) newset[YPEAK].upPrec();
452    }
453    // Z position of peak flux
454    val = objectList[obj].getZPeak();
455    tempwidth = int( log10(val) + 1) + newset[ZPEAK].getPrecision() + 2;
456    for(int i=newset[ZPEAK].getWidth();i<tempwidth;i++) newset[ZPEAK].widen();
457    if((val<1.)&&(val>0.)){
458      minval = pow(10, -1. * newset[ZPEAK].getPrecision()+1);
459      if((val>0.)&&(val < minval)) newset[ZPEAK].upPrec();
460    }
461  }
462
463  return newset;
464
465}
466
467std::vector<Col> getLogColSet(std::vector<Detection> &objectList,
468                              FitsHeader &head)
469{
470  /**
471   *  A function that returns a std::vector of Col objects containing
472   *    information on the columns necessary for logfile output:
473   *    Obj#,X,Y,Z,F_tot,F_peak,X1,X2,Y1,Y2,Z1,Z2,Npix
474   *
475   *   Each object in the provided objectList is checked to see if
476   *    it requires any column to be widened, or for that column to
477   *    have its precision increased.
478   *
479   * \param objectList A std::vector list of Detection objects that the columns need to fit.
480   * \param head The FitsHeader object defining the World Coordinate System.
481   * \return A std::vector list of Col definitions.
482   */
483
484  std::vector<Col> newset,tempset;
485 
486  // set up the default columns:
487  //  get from FullColSet, and select only the ones we want.
488  tempset = getFullColSet(objectList,head);
489
490  newset.push_back( tempset[NUM] );
491  newset.push_back( tempset[X] );
492  newset.push_back( tempset[Y] );
493  newset.push_back( tempset[Z] );
494  newset.push_back( tempset[FTOT] );
495  newset.push_back( tempset[FPEAK] );
496  newset.push_back( tempset[SNRPEAK] );
497  newset.push_back( tempset[X1] );
498  newset.push_back( tempset[X2] );
499  newset.push_back( tempset[Y1] );
500  newset.push_back( tempset[Y2] );
501  newset.push_back( tempset[Z1] );
502  newset.push_back( tempset[Z2] );
503  newset.push_back( tempset[NPIX] );
504
505  return newset;
506
507}
Note: See TracBrowser for help on using the repository browser.