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

Last change on this file since 1391 was 393, checked in by MatthewWhiting, 17 years ago

Fixed up headers for trunk as well.

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