source: tags/release-1.1/src/Detection/columns.cc @ 1391

Last change on this file since 1391 was 300, checked in by Matthew Whiting, 17 years ago
  • Fixed a bug that was incorrectly evaluating the integrated flux. It wasn't getting multiplied by the number of spatial pixels, so the values were way off.
  • Also fixed wcsIO.cc so that when a 2D section of a cube is given, the number of axes stored in the fitsHeader class is 2.
  • Changed the full results printing so that the FTOT column is printed as well. The results written to the screen are the same.
  • Some distribution text at the start of files.
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>
112  void Col::printEntry(std::ostream &stream, T value)
113  {
114    /**
115     *  \param stream Where the printing is done.
116     *  \param value  The value to be printed.
117     */
118    stream << std::setprecision(this->precision)
119           << std::setw(this->width)
120           << std::setfill(' ')
121           << value;
122  }
123  template void Col::printEntry<int>(std::ostream &stream, int value);
124  template void Col::printEntry<long>(std::ostream &stream, long value);
125  template void Col::printEntry<unsigned>(std::ostream &stream, unsigned value);
126  template void Col::printEntry<float>(std::ostream &stream, float value);
127  template void Col::printEntry<double>(std::ostream &stream, double value);
128  template void Col::printEntry<std::string>(std::ostream &stream, std::string value);
129
130}
131
132std::vector<Col> getFullColSet(std::vector<Detection> &objectList,
133                               FitsHeader &head)
134{
135  /**
136   *  A function that returns a std::vector of Col objects containing
137   *  information on the columns necessary for output to the results
138   *  file:
139   *    Obj#,NAME,X,Y,Z,RA,DEC,VEL,w_RA,w_DEC,w_VEL,F_tot,F_int,F_peak,
140   *                X1,X2,Y1,Y2,Z1,Z2,Npix,Flag
141   *
142   *   Each object in the provided objectList is checked to see if it
143   *   requires any column to be widened, or for that column to have
144   *   its precision increased.
145   *
146   *   Both Ftot and Fint are provided -- it is up to the calling
147   *   function to determine which to use.
148   *
149   * \param objectList A std::vector list of Detection objects that the
150   * columns need to fit.
151   * \param head The FitsHeader object defining the World Coordinate
152   * System.
153   * \return A std::vector list of Col definitions.
154   */
155
156  std::vector<Col> newset;
157
158  // set up the default columns
159
160  newset.push_back( Col(NUM) );
161  newset.push_back( Col(NAME) );
162  newset.push_back( Col(X) );
163  newset.push_back( Col(Y) );
164  newset.push_back( Col(Z) );
165  newset.push_back( Col(RA) );
166  newset.push_back( Col(DEC) );
167  newset.push_back( Col(VEL) );
168  newset.push_back( Col(WRA) );
169  newset.push_back( Col(WDEC) );
170  newset.push_back( Col(WVEL) );
171  newset.push_back( Col(FINT) );
172  newset.push_back( Col(FTOT) );
173  newset.push_back( Col(FPEAK) );
174  newset.push_back( Col(SNRPEAK) );
175  newset.push_back( Col(X1) );
176  newset.push_back( Col(X2) );
177  newset.push_back( Col(Y1) );
178  newset.push_back( Col(Y2) );
179  newset.push_back( Col(Z1) );
180  newset.push_back( Col(Z2) );
181  newset.push_back( Col(NPIX) );
182  newset.push_back( Col(FLAG) );
183  newset.push_back( Col(XAV) );
184  newset.push_back( Col(YAV) );
185  newset.push_back( Col(ZAV) );
186  newset.push_back( Col(XCENT) );
187  newset.push_back( Col(YCENT) );
188  newset.push_back( Col(ZCENT) );
189  newset.push_back( Col(XPEAK) );
190  newset.push_back( Col(YPEAK) );
191  newset.push_back( Col(ZPEAK) );
192
193  // Now test each object against each new column
194  for( int obj = 0; obj < objectList.size(); obj++){
195    std::string tempstr;
196    int tempwidth;
197    float val,minval;
198
199    // Obj#
200    tempwidth = int( log10(objectList[obj].getID()) + 1) +
201      newset[NUM].getPrecision() + 1;
202    for(int i=newset[NUM].getWidth();i<tempwidth;i++) newset[NUM].widen();
203
204    // Name
205    tempwidth = objectList[obj].getName().size() + 1;
206    for(int i=newset[NAME].getWidth();i<tempwidth;i++) newset[NAME].widen();
207
208    // X position
209    val = objectList[obj].getXcentre();
210    tempwidth = int( log10(val) + 1) + newset[X].getPrecision() + 2;
211    for(int i=newset[X].getWidth();i<tempwidth;i++) newset[X].widen();
212    if((val<1.)&&(val>0.)){
213      minval = pow(10, -1. * newset[X].getPrecision()+1);
214      if(val < minval) newset[X].upPrec();
215    }
216    // Y position
217    val = objectList[obj].getYcentre();
218    tempwidth = int( log10(val) + 1) + newset[Y].getPrecision() + 2;
219    for(int i=newset[Y].getWidth();i<tempwidth;i++) newset[Y].widen();
220    if((val<1.)&&(val>0.)){
221      minval = pow(10, -1. * newset[Y].getPrecision()+1);
222      if(val < minval) newset[Y].upPrec();
223    }
224    // Z position
225    val = objectList[obj].getZcentre();
226    tempwidth = int( log10(val) + 1) + newset[Z].getPrecision() + 2;
227    for(int i=newset[Z].getWidth();i<tempwidth;i++) newset[Z].widen();
228    if((val<1.)&&(val>0.)){
229      minval = pow(10, -1. * newset[Z].getPrecision()+1);
230      if((val>0.)&&(val < minval)) newset[Z].upPrec();
231    }
232
233    if(head.isWCS()){ 
234      // RA -- assign correct title. Check width but should be ok by definition
235      tempstr = head.WCS().lngtyp;
236      newset[RA].setName(tempstr);
237      tempwidth = objectList[obj].getRAs().size() + 1;
238      for(int i=newset[RA].getWidth();i<tempwidth;i++) newset[RA].widen();
239     
240      // Dec -- assign correct title. Check width, should be ok by definition
241      tempstr = head.WCS().lattyp;
242      newset[DEC].setName(tempstr);
243      tempwidth = objectList[obj].getDecs().size() + 1;
244      for(int i=newset[DEC].getWidth();i<tempwidth;i++) newset[DEC].widen();
245
246      // Vel -- check width, title and units.
247//       if(head.getNumAxes() > 2){
248        if(head.WCS().restfrq == 0) // using frequency, not velocity
249          newset[VEL].setName("FREQ");
250        if(head.getSpectralUnits().size()>0)
251          newset[VEL].setUnits("[" + head.getSpectralUnits() + "]");
252        tempwidth = newset[VEL].getUnits().size() + 1;
253        for(int i=newset[VEL].getWidth();i<tempwidth;i++) newset[VEL].widen();
254       
255        val = objectList[obj].getVel();
256        tempwidth = int(log10(fabs(val)) + 1) + newset[VEL].getPrecision() + 2;
257        if(val<0) tempwidth++;
258        for(int i=newset[VEL].getWidth();i<tempwidth;i++) newset[VEL].widen();
259        if((fabs(val) < 1.)&&(val>0.)){
260          minval = pow(10, -1. * newset[VEL].getPrecision()+1);
261          if(val < minval) newset[VEL].upPrec();
262        }
263//       }
264
265      // w_RA -- check width & title. leave units for the moment.
266      tempwidth = newset[RA].getUnits().size() + 1;
267      for(int i=newset[RA].getWidth();i<tempwidth;i++) newset[RA].widen();
268      val = objectList[obj].getRAWidth();
269      tempwidth = int( log10(fabs(val)) + 1) + newset[WRA].getPrecision() + 2;
270      if(val<0) tempwidth++;
271      for(int i=newset[WRA].getWidth();i<tempwidth;i++) newset[WRA].widen();
272      if((fabs(val) < 1.)&&(val>0.)){
273        minval = pow(10, -1. * newset[WRA].getPrecision()+1);
274        if(val < minval) newset[WRA].upPrec();
275      }
276
277      // w_DEC -- check width & title. leave units for the moment.
278      tempwidth = newset[DEC].getUnits().size() + 1;
279      for(int i=newset[DEC].getWidth();i<tempwidth;i++) newset[DEC].widen();
280      val = objectList[obj].getDecWidth();
281      tempwidth = int( log10(fabs(val)) + 1) + newset[WDEC].getPrecision() + 2;
282      if(val<0) tempwidth++;
283      for(int i=newset[WDEC].getWidth();i<tempwidth;i++) newset[WDEC].widen();
284      if((fabs(val) < 1.)&&(val>0.)){
285        minval = pow(10, -1. * newset[WDEC].getPrecision()+1);
286        if(val < minval) newset[WDEC].upPrec();
287      }
288
289      // w_Vel -- check width, title and units.
290//       if(head.getNumAxes() > 2){
291        if(head.WCS().restfrq == 0) // using frequency, not velocity
292          newset[WVEL].setName("w_FREQ");
293        if(head.getSpectralUnits().size()>0)
294          newset[WVEL].setUnits("[" + head.getSpectralUnits() + "]");
295        tempwidth = newset[WVEL].getUnits().size() + 1;
296        for(int i=newset[WVEL].getWidth();i<tempwidth;i++)newset[WVEL].widen();
297        val = objectList[obj].getVel();
298        tempwidth = int( log10(fabs(val)) + 1) + newset[WVEL].getPrecision() + 2;
299        if(val<0) tempwidth++;
300        for(int i=newset[WVEL].getWidth();i<tempwidth;i++) newset[WVEL].widen();
301        if((fabs(val) < 1.)&&(val>0.)){
302          minval = pow(10, -1. * newset[WVEL].getPrecision()+1);
303          if(val < minval) newset[WVEL].upPrec();
304        }
305
306        // F_int -- check width & units
307        newset[FINT].setUnits("[" + head.getIntFluxUnits() + "]");
308        tempwidth = newset[FINT].getUnits().size() + 1;
309        for(int i=newset[FINT].getWidth();i<tempwidth;i++) newset[FINT].widen();
310        val = objectList[obj].getIntegFlux();
311        tempwidth = int( log10(fabs(val)) + 1) + newset[FINT].getPrecision() + 2;
312        if(val<0) tempwidth++;
313        for(int i=newset[FINT].getWidth();i<tempwidth;i++) newset[FINT].widen();
314        if((fabs(val) < 1.)&&(val>0.)){
315          minval = pow(10, -1. * newset[FINT].getPrecision()+1);
316          if(val < minval) newset[FINT].upPrec();
317        }
318//       }
319    }
320
321    // F_tot
322    newset[FTOT].setUnits("[" + head.getFluxUnits() + "]");
323    tempwidth = newset[FTOT].getUnits().size() + 1;
324    for(int i=newset[FTOT].getWidth();i<tempwidth;i++) newset[FTOT].widen();
325    val = objectList[obj].getTotalFlux();
326    tempwidth = int( log10(fabs(val)) + 1) + newset[FTOT].getPrecision() + 2;
327    if(val<0) tempwidth++;
328    for(int i=newset[FTOT].getWidth();i<tempwidth;i++) newset[FTOT].widen();
329    if((fabs(val) < 1.)&&(val>0.)){
330      minval = pow(10, -1. * newset[FTOT].getPrecision()+1);
331      if(val < minval) newset[FTOT].upPrec();
332    }
333
334    // F_peak
335    newset[FPEAK].setUnits("[" + head.getFluxUnits() + "]");
336    tempwidth = newset[FPEAK].getUnits().size() + 1;
337    for(int i=newset[FPEAK].getWidth();i<tempwidth;i++) newset[FPEAK].widen();
338    val = objectList[obj].getPeakFlux();
339    tempwidth = int( log10(fabs(val)) + 1) + newset[FPEAK].getPrecision() + 2;
340    if(val<0) tempwidth++;
341    for(int i=newset[FPEAK].getWidth();i<tempwidth;i++) newset[FPEAK].widen();
342    if((fabs(val) < 1.)&&(val>0.)){
343      minval = pow(10, -1. * newset[FPEAK].getPrecision()+1);
344      if(val < minval) newset[FPEAK].upPrec();
345    }
346
347    // S/N_peak
348    val = objectList[obj].getPeakSNR();
349    tempwidth = int( log10(fabs(val)) + 1) + newset[SNRPEAK].getPrecision() +2;
350    if(val<0) tempwidth++;
351    for(int i=newset[SNRPEAK].getWidth();i<tempwidth;i++)
352      newset[SNRPEAK].widen();
353    if((fabs(val) < 1.)&&(val>0.)){
354      minval = pow(10, -1. * newset[SNRPEAK].getPrecision()+1);
355      if(val < minval) newset[SNRPEAK].upPrec();
356    }
357
358    // X1 position
359    tempwidth = int( log10(objectList[obj].getXmin()) + 1) +
360      newset[X1].getPrecision() + 1;
361    for(int i=newset[X1].getWidth();i<tempwidth;i++) newset[X1].widen();
362    // X2 position
363    tempwidth = int( log10(objectList[obj].getXmax()) + 1) +
364      newset[X2].getPrecision() + 1;
365    for(int i=newset[X2].getWidth();i<tempwidth;i++) newset[X2].widen();
366    // Y1 position
367    tempwidth = int( log10(objectList[obj].getYmin()) + 1) +
368      newset[Y1].getPrecision() + 1;
369    for(int i=newset[Y1].getWidth();i<tempwidth;i++) newset[Y1].widen();
370    // Y2 position
371    tempwidth = int( log10(objectList[obj].getYmax()) + 1) +
372      newset[Y2].getPrecision() + 1;
373    for(int i=newset[Y2].getWidth();i<tempwidth;i++) newset[Y2].widen();
374    // Z1 position
375    tempwidth = int( log10(objectList[obj].getZmin()) + 1) +
376      newset[Z1].getPrecision() + 1;
377    for(int i=newset[Z1].getWidth();i<tempwidth;i++) newset[Z1].widen();
378    // Z2 position
379    tempwidth = int( log10(objectList[obj].getZmax()) + 1) +
380      newset[Z2].getPrecision() + 1;
381    for(int i=newset[Z2].getWidth();i<tempwidth;i++) newset[Z2].widen();
382
383    // Npix
384    tempwidth = int( log10(objectList[obj].getSize()) + 1) +
385      newset[NPIX].getPrecision() + 1;
386    for(int i=newset[NPIX].getWidth();i<tempwidth;i++) newset[NPIX].widen();
387   
388    // average X position
389    val = objectList[obj].getXAverage();
390    tempwidth = int( log10(val) + 1) + newset[XAV].getPrecision() + 2;
391    for(int i=newset[XAV].getWidth();i<tempwidth;i++) newset[XAV].widen();
392    if((val<1.)&&(val>0.)){
393      minval = pow(10, -1. * newset[XAV].getPrecision()+1);
394      if(val < minval) newset[XAV].upPrec();
395    }
396    // average Y position
397    val = objectList[obj].getYAverage();
398    tempwidth = int( log10(val) + 1) + newset[YAV].getPrecision() + 2;
399    for(int i=newset[YAV].getWidth();i<tempwidth;i++) newset[YAV].widen();
400    if((val<1.)&&(val>0.)){
401      minval = pow(10, -1. * newset[YAV].getPrecision()+1);
402      if(val < minval) newset[YAV].upPrec();
403    }
404    // average Z position
405    val = objectList[obj].getZAverage();
406    tempwidth = int( log10(val) + 1) + newset[ZAV].getPrecision() + 2;
407    for(int i=newset[ZAV].getWidth();i<tempwidth;i++) newset[ZAV].widen();
408    if((val<1.)&&(val>0.)){
409      minval = pow(10, -1. * newset[ZAV].getPrecision()+1);
410      if((val>0.)&&(val < minval)) newset[ZAV].upPrec();
411    }
412   
413    // X position of centroid
414    val = objectList[obj].getXCentroid();
415    tempwidth = int( log10(val) + 1) + newset[XCENT].getPrecision() + 2;
416    for(int i=newset[XCENT].getWidth();i<tempwidth;i++) newset[XCENT].widen();
417    if((val<1.)&&(val>0.)){
418      minval = pow(10, -1. * newset[XCENT].getPrecision()+1);
419      if(val < minval) newset[XCENT].upPrec();
420    }
421    // Y position of centroid
422    val = objectList[obj].getYCentroid();
423    tempwidth = int( log10(val) + 1) + newset[YCENT].getPrecision() + 2;
424    for(int i=newset[YCENT].getWidth();i<tempwidth;i++) newset[YCENT].widen();
425    if((val<1.)&&(val>0.)){
426      minval = pow(10, -1. * newset[YCENT].getPrecision()+1);
427      if(val < minval) newset[YCENT].upPrec();
428    }
429    // Z position of centroid
430    val = objectList[obj].getZCentroid();
431    tempwidth = int( log10(val) + 1) + newset[ZCENT].getPrecision() + 2;
432    for(int i=newset[ZCENT].getWidth();i<tempwidth;i++) newset[ZCENT].widen();
433    if((val<1.)&&(val>0.)){
434      minval = pow(10, -1. * newset[ZCENT].getPrecision()+1);
435      if((val>0.)&&(val < minval)) newset[ZCENT].upPrec();
436    }
437   
438    // X position of peak flux
439    val = objectList[obj].getXPeak();
440    tempwidth = int( log10(val) + 1) + newset[XPEAK].getPrecision() + 2;
441    for(int i=newset[XPEAK].getWidth();i<tempwidth;i++) newset[XPEAK].widen();
442    if((val<1.)&&(val>0.)){
443      minval = pow(10, -1. * newset[XPEAK].getPrecision()+1);
444      if(val < minval) newset[XPEAK].upPrec();
445    }
446    // Y position of peak flux
447    val = objectList[obj].getYPeak();
448    tempwidth = int( log10(val) + 1) + newset[YPEAK].getPrecision() + 2;
449    for(int i=newset[YPEAK].getWidth();i<tempwidth;i++) newset[YPEAK].widen();
450    if((val<1.)&&(val>0.)){
451      minval = pow(10, -1. * newset[YPEAK].getPrecision()+1);
452      if(val < minval) newset[YPEAK].upPrec();
453    }
454    // Z position of peak flux
455    val = objectList[obj].getZPeak();
456    tempwidth = int( log10(val) + 1) + newset[ZPEAK].getPrecision() + 2;
457    for(int i=newset[ZPEAK].getWidth();i<tempwidth;i++) newset[ZPEAK].widen();
458    if((val<1.)&&(val>0.)){
459      minval = pow(10, -1. * newset[ZPEAK].getPrecision()+1);
460      if((val>0.)&&(val < minval)) newset[ZPEAK].upPrec();
461    }
462  }
463
464  return newset;
465
466}
467
468std::vector<Col> getLogColSet(std::vector<Detection> &objectList,
469                              FitsHeader &head)
470{
471  /**
472   *  A function that returns a std::vector of Col objects containing
473   *    information on the columns necessary for logfile output:
474   *    Obj#,X,Y,Z,F_tot,F_peak,X1,X2,Y1,Y2,Z1,Z2,Npix
475   *
476   *   Each object in the provided objectList is checked to see if
477   *    it requires any column to be widened, or for that column to
478   *    have its precision increased.
479   *
480   * \param objectList A std::vector list of Detection objects that the columns need to fit.
481   * \param head The FitsHeader object defining the World Coordinate System.
482   * \return A std::vector list of Col definitions.
483   */
484
485  std::vector<Col> newset,tempset;
486 
487  // set up the default columns:
488  //  get from FullColSet, and select only the ones we want.
489  tempset = getFullColSet(objectList,head);
490
491  newset.push_back( tempset[NUM] );
492  newset.push_back( tempset[X] );
493  newset.push_back( tempset[Y] );
494  newset.push_back( tempset[Z] );
495  newset.push_back( tempset[FTOT] );
496  newset.push_back( tempset[FPEAK] );
497  newset.push_back( tempset[SNRPEAK] );
498  newset.push_back( tempset[X1] );
499  newset.push_back( tempset[X2] );
500  newset.push_back( tempset[Y1] );
501  newset.push_back( tempset[Y2] );
502  newset.push_back( tempset[Z1] );
503  newset.push_back( tempset[Z2] );
504  newset.push_back( tempset[NPIX] );
505
506  return newset;
507
508}
Note: See TracBrowser for help on using the repository browser.