source: tags/release-1.1.5/src/param.cc @ 1441

Last change on this file since 1441 was 446, checked in by MatthewWhiting, 16 years ago

Adding an annotationType parameter to be able to switch between different karma styles.

File size: 42.7 KB
Line 
1// -----------------------------------------------------------------------
2// param.cc: Dealing with the set of parameters for Duchamp.
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 <iomanip>
30#include <fstream>
31#include <sstream>
32#include <string>
33#include <stdlib.h>
34#include <ctype.h>
35#include <math.h>
36#include <unistd.h>
37#include <duchamp/param.hh>
38#include <duchamp/fitsHeader.hh>
39#include <duchamp/duchamp.hh>
40#include <duchamp/pgheader.hh>
41#include <duchamp/ATrous/filter.hh>
42#include <duchamp/Utils/utils.hh>
43#include <duchamp/Utils/Section.hh>
44#include <duchamp/Detection/columns.hh>
45
46namespace duchamp
47{
48
49  /****************************************************************/
50  ///////////////////////////////////////////////////
51  //// Accessor Functions for Parameter class:
52  ///////////////////////////////////////////////////
53  Param::~Param()
54  {
55    /**
56     * Deletes the offsets array if the sizeOffsets parameter is
57     * positive.
58     */
59    if(this->sizeOffsets>0) delete [] this->offsets;
60  }
61
62  Param::Param()
63  {
64    this->defaultValues();
65  }
66
67  void Param::defaultValues()
68  {
69    /**
70     * Provides default intial values for the parameters. Note that
71     * imageFile has no default value!
72     */
73    std::string baseSection = "[*,*,*]";
74    // Input files
75    this->imageFile         = "";
76    this->flagSubsection    = false;
77    this->pixelSec.setSection(baseSection);
78    this->flagReconExists   = false;
79    this->reconFile         = "";
80    this->flagSmoothExists  = false;
81    this->smoothFile        = "";
82    // Output files
83    this->flagLog           = false;
84    this->logFile           = "duchamp-Logfile.txt";
85    this->outFile           = "duchamp-Results.txt";
86    this->flagSeparateHeader= false;
87    this->headerFile        = "duchamp-Results.hdr";
88    this->spectraFile       = "duchamp-Spectra.ps";
89    this->flagTextSpectra   = false;
90    this->spectraTextFile   = "duchamp-Spectra.txt";
91    this->flagOutputMask    = false;
92    this->flagOutputSmooth  = false;
93    this->flagOutputRecon   = false;
94    this->flagOutputResid   = false;
95    this->flagVOT           = false;
96    this->votFile           = "duchamp-Results.xml";
97    this->flagKarma         = false;
98    this->karmaFile         = "duchamp-Results.ann";
99    this->annotationType    = "borders";
100    this->flagMaps          = true;
101    this->detectionMap      = "duchamp-DetectionMap.ps";
102    this->momentMap         = "duchamp-MomentMap.ps";
103    this->flagXOutput       = true;
104    this->precFlux          = Column::prFLUX;
105    this->precVel           = Column::prVEL;
106    this->precSNR           = Column::prSNR;
107    // Cube related parameters
108    this->flagBlankPix      = true;
109    this->blankPixValue     = -8.00061;
110    this->blankKeyword      = 1;
111    this->bscaleKeyword     = -8.00061;
112    this->bzeroKeyword      = 0.;
113    this->newFluxUnits      = "";
114    // Milky-Way parameters
115    this->flagMW            = false;
116    this->maxMW             = 112;
117    this->minMW             = 75;
118    this->numPixBeam        = 10.;
119    this->flagUsingBeam     = false;
120    // Trim-related         
121    this->flagTrim          = false;
122    this->hasBeenTrimmed    = false;
123    this->borderLeft        = 0;
124    this->borderRight       = 0;
125    this->borderBottom      = 0;
126    this->borderTop         = 0;
127    // Subsection offsets
128    this->sizeOffsets       = 0;
129    this->xSubOffset        = 0;
130    this->ySubOffset        = 0;
131    this->zSubOffset        = 0;
132    // Baseline related
133    this->flagBaseline      = false;
134    // Detection-related   
135    this->flagNegative      = false;
136    // Object growth       
137    this->flagGrowth        = false;
138    this->growthCut         = 2.;
139    // FDR analysis         
140    this->flagFDR           = false;
141    this->alphaFDR          = 0.01;
142    // Other detection     
143    this->flagStatSec       = false;
144    this->statSec.setSection(baseSection);
145    this->flagRobustStats   = true;
146    this->snrCut            = 3.;
147    this->threshold         = 0.;
148    this->flagUserThreshold = false;
149    // Smoothing
150    this->flagSmooth        = false;
151    this->smoothType        = "spectral";
152    this->hanningWidth      = 5;
153    this->kernMaj           = 3.;
154    this->kernMin           = -1.;
155    this->kernPA            = 0.;
156    // A trous reconstruction parameters
157    this->flagATrous        = false;
158    this->reconDim          = 1;
159    this->scaleMin          = 1;
160    this->scaleMax          = 0;
161    this->snrRecon          = 4.;
162    this->filterCode        = 1;
163    this->reconFilter.define(this->filterCode);
164    // Volume-merging parameters
165    this->flagAdjacent      = true;
166    this->threshSpatial     = 3.;
167    this->threshVelocity    = 7.;
168    this->minChannels       = 3;
169    this->minPix            = 2;
170    // Input-Output related
171    this->spectralMethod    = "peak";
172    this->spectralUnits     = "km/s";
173    this->pixelCentre       = "centroid";
174    this->borders           = true;
175    this->blankEdge         = true;
176    this->verbose           = true;
177  }
178
179  Param::Param (const Param& p)
180  {
181    operator=(p);
182  }
183
184  Param& Param::operator= (const Param& p)
185  {
186    if(this == &p) return *this;
187    this->imageFile         = p.imageFile;
188    this->flagSubsection    = p.flagSubsection;
189    this->pixelSec          = p.pixelSec;
190    this->flagReconExists   = p.flagReconExists;
191    this->reconFile         = p.reconFile;     
192    this->flagSmoothExists  = p.flagSmoothExists;
193    this->smoothFile        = p.smoothFile;     
194    this->flagLog           = p.flagLog;       
195    this->logFile           = p.logFile;       
196    this->outFile           = p.outFile;       
197    this->flagSeparateHeader= p.flagSeparateHeader;
198    this->headerFile        = p.headerFile;
199    this->spectraFile       = p.spectraFile;   
200    this->flagTextSpectra   = p.flagTextSpectra;   
201    this->spectraTextFile   = p.spectraTextFile;   
202    this->flagOutputMask    = p.flagOutputMask;
203    this->flagOutputSmooth  = p.flagOutputSmooth;
204    this->flagOutputRecon   = p.flagOutputRecon;
205    this->flagOutputResid   = p.flagOutputResid;
206    this->flagVOT           = p.flagVOT;         
207    this->votFile           = p.votFile;       
208    this->flagKarma         = p.flagKarma;     
209    this->karmaFile         = p.karmaFile;     
210    this->annotationType    = p.annotationType;
211    this->flagMaps          = p.flagMaps;       
212    this->detectionMap      = p.detectionMap;   
213    this->momentMap         = p.momentMap;     
214    this->flagXOutput       = p.flagXOutput;       
215    this->precFlux          = p.precFlux;
216    this->precVel           = p.precVel;
217    this->precSNR           = p.precSNR;
218    this->flagBlankPix      = p.flagBlankPix;   
219    this->blankPixValue     = p.blankPixValue; 
220    this->blankKeyword      = p.blankKeyword;   
221    this->bscaleKeyword     = p.bscaleKeyword; 
222    this->bzeroKeyword      = p.bzeroKeyword;   
223    this->newFluxUnits      = p.newFluxUnits;
224    this->flagMW            = p.flagMW;         
225    this->maxMW             = p.maxMW;         
226    this->minMW             = p.minMW;         
227    this->numPixBeam        = p.numPixBeam;     
228    this->flagTrim          = p.flagTrim;   
229    this->hasBeenTrimmed    = p.hasBeenTrimmed;   
230    this->borderLeft        = p.borderLeft;     
231    this->borderRight       = p.borderRight;   
232    this->borderBottom      = p.borderBottom;   
233    this->borderTop         = p.borderTop;     
234    if(this->sizeOffsets>0) delete [] this->offsets;
235    this->sizeOffsets       = p.sizeOffsets;
236    if(this->sizeOffsets>0){
237      this->offsets           = new long[this->sizeOffsets];
238      for(int i=0;i<this->sizeOffsets;i++) this->offsets[i] = p.offsets[i];
239    }
240    this->xSubOffset        = p.xSubOffset;     
241    this->ySubOffset        = p.ySubOffset;     
242    this->zSubOffset        = p.zSubOffset;
243    this->flagBaseline      = p.flagBaseline;
244    this->flagNegative      = p.flagNegative;
245    this->flagGrowth        = p.flagGrowth;
246    this->growthCut         = p.growthCut;
247    this->flagFDR           = p.flagFDR;
248    this->alphaFDR          = p.alphaFDR;
249    this->flagStatSec       = p.flagStatSec;
250    this->statSec           = p.statSec;
251    this->flagRobustStats   = p.flagRobustStats;
252    this->snrCut            = p.snrCut;
253    this->threshold         = p.threshold;
254    this->flagUserThreshold = p.flagUserThreshold;
255    this->flagSmooth        = p.flagSmooth;
256    this->smoothType        = p.smoothType;
257    this->hanningWidth      = p.hanningWidth;
258    this->kernMaj           = p.kernMaj;
259    this->kernMin           = p.kernMin;
260    this->kernPA            = p.kernPA;
261    this->flagATrous        = p.flagATrous;
262    this->reconDim          = p.reconDim;
263    this->scaleMin          = p.scaleMin;
264    this->scaleMax          = p.scaleMax;
265    this->snrRecon          = p.snrRecon;
266    this->filterCode        = p.filterCode;
267    this->reconFilter       = p.reconFilter;
268    this->flagAdjacent      = p.flagAdjacent;
269    this->threshSpatial     = p.threshSpatial;
270    this->threshVelocity    = p.threshVelocity;
271    this->minChannels       = p.minChannels;
272    this->minPix            = p.minPix;
273    this->spectralMethod    = p.spectralMethod;
274    this->spectralUnits     = p.spectralUnits;
275    this->pixelCentre       = p.pixelCentre;
276    this->borders           = p.borders;
277    this->verbose           = p.verbose;
278    return *this;
279  }
280  //--------------------------------------------------------------------
281
282  int Param::getopts(int argc, char ** argv)
283  {
284    /** 
285     *   A function that reads in the command-line options, in a manner
286     *    tailored for use with the main Duchamp program.
287     *
288     *   \param argc The number of command line arguments.
289     *   \param argv The array of command line arguments.
290     */
291
292    int returnValue = FAILURE;
293    if(argc==1){
294      std::cout << ERR_USAGE_MSG;
295      returnValue = FAILURE;
296    }
297    else {
298      std::string file;
299      bool changeX = false;
300      this->defaultValues();
301      char c;
302      while( ( c = getopt(argc,argv,"p:f:hvx") )!=-1){
303        switch(c) {
304        case 'p':
305          file = optarg;
306          if(this->readParams(file)==FAILURE){
307            std::stringstream errmsg;
308            errmsg << "Could not open parameter file " << file << ".\n";
309            duchampError("Duchamp",errmsg.str());
310          }
311          else returnValue = SUCCESS;
312          break;
313        case 'f':
314          file = optarg;
315          this->imageFile = file;
316          returnValue = SUCCESS;
317          break;
318        case 'v':
319          std::cout << PROGNAME << " version " << VERSION << std::endl;
320          break;
321        case 'x':
322          changeX = true;
323          break;
324        case 'h':
325        default :
326          std::cout << ERR_USAGE_MSG;
327          break;
328        }
329      }
330      if(changeX){
331        if(returnValue == SUCCESS) this->setFlagXOutput(false);
332        else {
333          duchampError("Duchamp",
334                       "You need to specify either a parameter file or FITS image.\n");
335          std::cout << "\n" << ERR_USAGE_MSG;
336        }
337      }
338    }
339    return returnValue;
340  }
341  //--------------------------------------------------------------------
342
343  bool Param::isBlank(float &value)
344  {
345    /**
346     *  Tests whether the value passed as the argument is BLANK or not.
347     *  \param value Pixel value to be tested.
348     *  \return False if flagBlankPix is false. Else, compare to the
349     *  relevant FITS keywords, using integer comparison.
350     */
351    return this->flagBlankPix &&
352      (this->blankKeyword == int((value-this->bzeroKeyword)/this->bscaleKeyword));
353  }
354
355  bool *Param::makeBlankMask(float *array, int size)
356  {
357    /**
358     *  This returns an array of bools, saying whether each pixel in the
359     *  given array is BLANK or not. If the pixel is BLANK, set mask to
360     *  false, else set to true. The array is allocated by the function.
361     */
362    bool *mask = new bool[size];
363    for(int i=0;i<size;i++) mask[i] = !this->isBlank(array[i]);
364    return mask;
365  }
366
367
368  bool Param::isInMW(int z)
369  {
370    /**
371     *  Tests whether we are flagging Milky Way channels, and if so
372     * whether the given channel number is in the Milky Way range. The
373     * channels are assumed to start at number 0. 
374     * \param z The channel number
375     * \return True if we are flagging Milky Way channels and z is in
376     *  the range.
377     */
378    return ( flagMW && (z>=minMW) && (z<=maxMW) );
379  }
380
381  bool Param::isStatOK(int x, int y, int z)
382  {
383    /**
384     * Test whether a given pixel position lies within the subsection
385     * given by the statSec parameter. Only tested if the flagSubsection
386     * parameter is true -- if it isn't, we just return true since all
387     * pixels are therefore available for statstical calculations.
388     * \param x X-value of pixel being tested.
389     * \param y Y-value of pixel being tested.
390     * \param z Z-value of pixel being tested.
391     * \return True if pixel is able to be used for statistical
392     * calculations. False otherwise.
393     */
394    int xval=x,yval=y,zval=z;
395    if(flagSubsection){
396      xval += pixelSec.getStart(0);
397      yval += pixelSec.getStart(1);
398      zval += pixelSec.getStart(2);
399    }
400    return !flagStatSec || statSec.isInside(xval,yval,zval);
401  }
402
403  /****************************************************************/
404  ///////////////////////////////////////////////////
405  //// Other Functions using the  Parameter class:
406  ///////////////////////////////////////////////////
407
408  std::string makelower( std::string s )
409  {
410    // "borrowed" from Matt Howlett's 'fred'
411    std::string out = "";
412    for( int i=0; i<s.size(); ++i ) {
413      out += tolower(s[i]);
414    }
415    return out;
416  }
417
418  inline std::string stringize(bool b)
419  {
420    /**
421     * Convert a bool variable to the textual equivalent.
422     * \return A std::string with the english equivalent of the bool.
423     */
424    std::string output;
425    if(b) output="true";
426    else output="false";
427    return output;
428  }
429
430  inline bool boolify( std::string s )
431  {
432    /**
433     *  Convert a std::string to a bool variable:
434     *  "1" and "true" get converted to true;
435     *  "0" and "false" (and anything else) get converted to false.
436     * \return The bool equivalent of the string.
437     */
438    if((s=="1") || (makelower(s)=="true")) return true;
439    else if((s=="0") || (makelower(s)=="false")) return false;
440    else return false;
441  }
442
443  inline std::string readSval(std::stringstream& ss)
444  {
445    std::string val; ss >> val; return val;
446  }
447
448  inline bool readFlag(std::stringstream& ss)
449  {
450    std::string val; ss >> val; return boolify(val);
451  }
452
453  inline float readFval(std::stringstream& ss)
454  {
455    float val; ss >> val; return val;
456  }
457
458  inline int readIval(std::stringstream& ss)
459  {
460    int val; ss >> val; return val;
461  }
462
463  int Param::readParams(std::string paramfile)
464  {
465    /**
466     * The parameters are read in from a disk file, on the assumption that each
467     *  line of the file has the format "parameter value" (eg. alphafdr 0.1)
468     *
469     * The case of the parameter name does not matter, nor does the
470     * formatting of the spaces (it can be any amount of whitespace or
471     * tabs).
472     *
473     * \param paramfile A std::string containing the parameter filename.
474     *
475     * \return FAILURE if the parameter file does not exist. SUCCESS if
476     * it is able to read it.
477     */
478    std::ifstream fin(paramfile.c_str());
479    if(!fin.is_open()) return FAILURE;
480    std::string line;
481    while( !std::getline(fin,line,'\n').eof()){
482
483      if(line[0]!='#'){
484        std::stringstream ss;
485        ss.str(line);
486        std::string arg;
487        ss >> arg;
488        arg = makelower(arg);
489        if(arg=="imagefile")       this->imageFile = readSval(ss);
490        if(arg=="flagsubsection")  this->flagSubsection = readFlag(ss);
491        if(arg=="subsection")      this->pixelSec.setSection(readSval(ss));
492        if(arg=="flagreconexists") this->flagReconExists = readFlag(ss);
493        if(arg=="reconfile")       this->reconFile = readSval(ss);
494        if(arg=="flagsmoothexists")this->flagSmoothExists = readFlag(ss);
495        if(arg=="smoothfile")      this->smoothFile = readSval(ss);
496        if(arg=="beamsize")        this->numPixBeam = readFval(ss);
497
498        if(arg=="flaglog")         this->flagLog = readFlag(ss);
499        if(arg=="logfile")         this->logFile = readSval(ss);
500        if(arg=="outfile")         this->outFile = readSval(ss);
501        if(arg=="flagseparateheader") this->flagSeparateHeader = readFlag(ss);
502        if(arg=="headerfile")      this->headerFile = readSval(ss);
503        if(arg=="spectrafile")     this->spectraFile = readSval(ss);
504        if(arg=="flagtextspectra") this->flagTextSpectra = readFlag(ss);
505        if(arg=="spectraTextfile") this->spectraTextFile = readSval(ss);
506        if(arg=="flagoutputmask")  this->flagOutputMask = readFlag(ss);
507        if(arg=="flagoutputsmooth")this->flagOutputSmooth = readFlag(ss);
508        if(arg=="flagoutputrecon") this->flagOutputRecon = readFlag(ss);
509        if(arg=="flagoutputresid") this->flagOutputResid = readFlag(ss);
510        if(arg=="flagvot")         this->flagVOT = readFlag(ss);
511        if(arg=="votfile")         this->votFile = readSval(ss);
512        if(arg=="flagkarma")       this->flagKarma = readFlag(ss);
513        if(arg=="karmafile")       this->karmaFile = readSval(ss);
514        if(arg=="annotationtype")  this->annotationType = readSval(ss);
515        if(arg=="flagmaps")        this->flagMaps = readFlag(ss);
516        if(arg=="detectionmap")    this->detectionMap = readSval(ss);
517        if(arg=="momentmap")       this->momentMap = readSval(ss);
518        if(arg=="flagxoutput")     this->flagXOutput = readFlag(ss);
519        if(arg=="newfluxunits")    this->newFluxUnits = readSval(ss);
520        if(arg=="precflux")        this->precFlux = readIval(ss);
521        if(arg=="precvel")         this->precVel = readIval(ss);
522        if(arg=="precsnr")         this->precSNR = readIval(ss);
523
524        if(arg=="flagtrim")        this->flagTrim = readFlag(ss);
525        if(arg=="flagmw")          this->flagMW = readFlag(ss);
526        if(arg=="maxmw")           this->maxMW = readIval(ss);
527        if(arg=="minmw")           this->minMW = readIval(ss);
528        if(arg=="flagbaseline")    this->flagBaseline = readFlag(ss);
529
530        if(arg=="flagnegative")    this->flagNegative = readFlag(ss);
531        if(arg=="minpix")          this->minPix = readIval(ss);
532        if(arg=="flaggrowth")      this->flagGrowth = readFlag(ss);
533        if(arg=="growthcut")       this->growthCut = readFval(ss);
534
535        if(arg=="flagfdr")         this->flagFDR = readFlag(ss);
536        if(arg=="alphafdr")        this->alphaFDR = readFval(ss);
537
538        if(arg=="flagstatsec")     this->flagStatSec = readFlag(ss);
539        if(arg=="statsec")         this->statSec.setSection(readSval(ss));
540        if(arg=="flagrobuststats") this->flagRobustStats = readFlag(ss);
541        if(arg=="snrcut")          this->snrCut = readFval(ss);
542        if(arg=="threshold"){
543          this->threshold = readFval(ss);
544          this->flagUserThreshold = true;
545        }
546     
547        if(arg=="flagsmooth")      this->flagSmooth = readFlag(ss);
548        if(arg=="smoothtype")      this->smoothType = readSval(ss);
549        if(arg=="hanningwidth")    this->hanningWidth = readIval(ss);
550        if(arg=="kernmaj")         this->kernMaj = readFval(ss);
551        if(arg=="kernmin")         this->kernMin = readFval(ss);
552        if(arg=="kernpa")          this->kernPA = readFval(ss);
553
554        if(arg=="flagatrous")      this->flagATrous = readFlag(ss);
555        if(arg=="recondim")        this->reconDim = readIval(ss);
556        if(arg=="scalemin")        this->scaleMin = readIval(ss);
557        if(arg=="scalemax")        this->scaleMax = readIval(ss);
558        if(arg=="snrrecon")        this->snrRecon = readFval(ss);
559        if(arg=="filtercode"){
560          this->filterCode = readIval(ss);
561          this->reconFilter.define(this->filterCode);
562        }
563
564        if(arg=="flagadjacent")    this->flagAdjacent = readFlag(ss);
565        if(arg=="threshspatial")   this->threshSpatial = readFval(ss);
566        if(arg=="threshvelocity")  this->threshVelocity = readFval(ss);
567        if(arg=="minchannels")     this->minChannels = readIval(ss);
568
569        if(arg=="spectralmethod")  this->spectralMethod=makelower(readSval(ss));
570        if(arg=="spectralunits")   this->spectralUnits = makelower(readSval(ss));
571        if(arg=="pixelcentre")     this->pixelCentre = makelower(readSval(ss));
572        if(arg=="drawborders")     this->borders = readFlag(ss);
573        if(arg=="drawblankedges")  this->blankEdge = readFlag(ss);
574        if(arg=="verbose")         this->verbose = readFlag(ss);
575
576        // Dealing with deprecated parameters.
577        if(arg=="flagblankpix"){
578          this->flagTrim = readFlag(ss);
579          std::stringstream errmsg;
580          errmsg <<"The parameter flagBlankPix is deprecated. "
581                 <<"Please use the flagTrim parameter in future.\n"
582                 <<"Setting flagTrim = " << stringize(this->flagTrim) << ".\n";
583          duchampWarning("Reading parameters",errmsg.str());
584        }
585        if(arg=="blankpixvalue"){
586          std::stringstream errmsg;
587          errmsg <<"The parameter blankPixValue is deprecated.\n"
588                 <<"This value is only taken from the FITS header.\n";
589          duchampWarning("Reading parameters",errmsg.str());
590        }
591
592      }
593    }
594
595    // If pgplot was not included in the compilation, need to set flagXOutput to false
596    if(!USE_PGPLOT) this->flagXOutput = false;
597
598    // Correcting bad precision values -- if negative, set to 0
599    if(this->precFlux<0) this->precFlux = 0;
600    if(this->precVel<0)  this->precVel = 0;
601    if(this->precSNR<0)  this->precSNR = 0;
602
603    // The wavelet reconstruction takes precendence over the smoothing.
604    if(this->flagATrous) this->flagSmooth = false;
605
606    // Make sure the annnotationType is an acceptable option -- default is "borders"
607    if((this->annotationType != "borders") && (this->annotationType!="circles")){
608      std::stringstream errmsg;
609      errmsg << "The requested value of the parameter annotationType, \""
610             << this->annotationType << "\" is invalid.\n"
611             << "Changing to \"borders\".\n";
612      duchampWarning("Reading parameters",errmsg.str());
613      this->annotationType = "borders";
614    }
615     
616    // Make sure smoothType is an acceptable type -- default is "spectral"
617    if((this->smoothType!="spectral")&&
618       (this->smoothType!="spatial")){
619      std::stringstream errmsg;
620      errmsg << "The requested value of the parameter smoothType, \""
621             << this->smoothType << "\" is invalid.\n"
622             << "Changing to \"spectral\".\n";
623      duchampWarning("Reading parameters",errmsg.str());
624      this->smoothType = "spectral";
625    }
626    // If kernMin has not been given, or is negative, make it equal to kernMaj
627    if(this->kernMin < 0) this->kernMin = this->kernMaj;
628
629    // Make sure spectralMethod is an acceptable type -- default is "peak"
630    if((this->spectralMethod!="peak")&&
631       (this->spectralMethod!="sum")){
632      std::stringstream errmsg;
633      errmsg << "The requested value of the parameter spectralMethod, \""
634             << this->spectralMethod << "\" is invalid.\n"
635             << "Changing to \"peak\".\n";
636      duchampWarning("Reading parameters",errmsg.str());
637      this->spectralMethod = "peak";
638    }
639
640    // Make sure pixelCentre is an acceptable type -- default is "peak"
641    if((this->pixelCentre!="centroid")&&
642       (this->pixelCentre!="average") &&
643       (this->pixelCentre!="peak")       ){
644      std::stringstream errmsg;
645      errmsg << "The requested value of the parameter pixelCentre, \""
646             << this->pixelCentre << "\" is invalid.\n"
647             << "Changing to \"centroid\".\n";
648      duchampWarning("Reading parameters",errmsg.str());
649      this->pixelCentre = "centroid";
650    }
651
652    return SUCCESS;
653  }
654
655
656  std::ostream& operator<< ( std::ostream& theStream, Param& par)
657  {
658    /**
659     * Print out the parameter set in a formatted, easy to read style.
660     * Lists the parameters, a description of them, and their value.
661     */
662
663    // Only show the [beamSize] bit if we are using the parameter
664    // otherwise we have read it from the FITS header.
665    std::string beamParam = "";
666    if(par.getFlagUsingBeam()) beamParam = "[beamSize]";
667
668    // BUG -- can get error: `boolalpha' is not a member of type `ios' -- old compilers: gcc 2.95.3?
669    //   theStream.setf(std::ios::boolalpha);
670    theStream.setf(std::ios::left);
671    theStream  <<"\n---- Parameters ----"<<std::endl;
672    theStream  << std::setfill('.');
673    const int widthText = 38;
674    const int widthPar  = 18;
675    if(par.getFlagSubsection())
676      theStream<<std::setw(widthText)<<"Image to be analysed"                 
677               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[imageFile]"
678               <<"  =  " <<resetiosflags(std::ios::right)
679               <<(par.getImageFile()+par.getSubsection()) <<std::endl;
680    else
681      theStream<<std::setw(widthText)<<"Image to be analysed"                 
682               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[imageFile]"
683               <<"  =  " <<resetiosflags(std::ios::right)
684               <<par.getImageFile()      <<std::endl;
685    if(par.getFlagReconExists() && par.getFlagATrous()){
686      theStream<<std::setw(widthText)<<"Reconstructed array exists?"         
687               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[reconExists]"
688               <<"  =  " <<resetiosflags(std::ios::right)
689               <<stringize(par.getFlagReconExists())<<std::endl;
690      theStream<<std::setw(widthText)<<"FITS file containing reconstruction" 
691               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[reconFile]"
692               <<"  =  " <<resetiosflags(std::ios::right)
693               <<par.getReconFile()      <<std::endl;
694    }
695    if(par.getFlagSmoothExists() && par.getFlagSmooth()){
696      theStream<<std::setw(widthText)<<"Smoothed array exists?"         
697               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[smoothExists]"
698               <<"  =  " <<resetiosflags(std::ios::right)
699               <<stringize(par.getFlagSmoothExists())<<std::endl;
700      theStream<<std::setw(widthText)<<"FITS file containing smoothed array" 
701               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[smoothFile]"
702               <<"  =  " <<resetiosflags(std::ios::right)
703               <<par.getSmoothFile()      <<std::endl;
704    }
705    theStream  <<std::setw(widthText)<<"Intermediate Logfile"
706               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[logFile]"
707               <<"  =  " <<resetiosflags(std::ios::right)
708               <<par.getLogFile()        <<std::endl;
709    theStream  <<std::setw(widthText)<<"Final Results file"                   
710               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[outFile]"
711               <<"  =  " <<resetiosflags(std::ios::right)
712               <<par.getOutFile()        <<std::endl;
713    if(par.getFlagSeparateHeader())
714      theStream <<std::setw(widthText)<<"Header for results file"
715                <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[headerFile]"
716                <<"  =  " <<resetiosflags(std::ios::right)
717                <<par.getHeaderFile()        <<std::endl;
718    theStream  <<std::setw(widthText)<<"Spectrum file"                       
719               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[spectraFile]"
720               <<"  =  " <<resetiosflags(std::ios::right)
721               <<par.getSpectraFile()    <<std::endl;
722    if(par.getFlagTextSpectra()){
723      theStream<<std::setw(widthText)<<"Text file with ascii spectral data"                         
724               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[spectraTextFile]"
725               <<"  =  " <<resetiosflags(std::ios::right)
726               <<par.getSpectraTextFile()<<std::endl;
727    }
728    if(par.getFlagVOT()){
729      theStream<<std::setw(widthText)<<"VOTable file"                         
730               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[votFile]"
731               <<"  =  " <<resetiosflags(std::ios::right)
732               <<par.getVOTFile()        <<std::endl;
733    }
734    if(par.getFlagKarma()){
735      theStream<<std::setw(widthText)<<"Karma annotation file"               
736               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[karmaFile]"
737               <<"  =  " <<resetiosflags(std::ios::right)
738             
739               <<par.getKarmaFile()      <<std::endl;
740    }
741    if(par.getFlagMaps()){
742      theStream<<std::setw(widthText)<<"0th Moment Map"                       
743               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[momentMap]"
744               <<"  =  " <<resetiosflags(std::ios::right)
745               <<par.getMomentMap()      <<std::endl;
746      theStream<<std::setw(widthText)<<"Detection Map"                       
747               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[detectionMap]"
748               <<"  =  " <<resetiosflags(std::ios::right)
749               <<par.getDetectionMap()   <<std::endl;
750    }
751    theStream  <<std::setw(widthText)<<"Display a map in a pgplot xwindow?"
752               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagXOutput]"
753               <<"  =  " <<resetiosflags(std::ios::right)
754               <<stringize(par.getFlagXOutput())     <<std::endl;
755    if(par.getFlagATrous()){                           
756      theStream<<std::setw(widthText)<<"Saving reconstructed cube?"           
757               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagOutputRecon]"
758               <<"  =  " <<resetiosflags(std::ios::right)
759               <<stringize(par.getFlagOutputRecon())<<std::endl;
760      theStream<<std::setw(widthText)<<"Saving residuals from reconstruction?"
761               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagOutputResid]"
762               <<"  =  " <<resetiosflags(std::ios::right)
763               <<stringize(par.getFlagOutputResid())<<std::endl;
764    }                                                 
765    if(par.getFlagSmooth()){                           
766      theStream<<std::setw(widthText)<<"Saving smoothed cube?"           
767               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagOutputSmooth]"
768               <<"  =  " <<resetiosflags(std::ios::right)
769               <<stringize(par.getFlagOutputSmooth())<<std::endl;
770    }                                                 
771    theStream<<std::setw(widthText)<<"Saving mask cube?"           
772             <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagOutputMask]"
773             <<"  =  " <<resetiosflags(std::ios::right)
774             <<stringize(par.getFlagOutputMask())<<std::endl;
775    theStream  <<"------"<<std::endl;
776    if(par.getFlagBlankPix()){
777      theStream<<std::setw(widthText)<<"Blank Pixel Value"                   
778               <<std::setw(widthPar)<<setiosflags(std::ios::right)<< ""
779               <<"  =  " <<resetiosflags(std::ios::right)
780               <<par.getBlankPixVal()    <<std::endl;
781    }
782    theStream  <<std::setw(widthText)<<"Trimming Blank Pixels?"                 
783               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagTrim]"
784               <<"  =  " <<resetiosflags(std::ios::right)
785               <<stringize(par.getFlagTrim())   <<std::endl;
786    theStream  <<std::setw(widthText)<<"Searching for Negative features?"     
787               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagNegative]"
788               <<"  =  " <<resetiosflags(std::ios::right)
789               <<stringize(par.getFlagNegative())   <<std::endl;
790    theStream  <<std::setw(widthText)<<"Removing Milky Way channels?"         
791               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagMW]"
792               <<"  =  " <<resetiosflags(std::ios::right)
793               <<stringize(par.getFlagMW())         <<std::endl;
794    if(par.getFlagMW()){
795      theStream<<std::setw(widthText)<<"Milky Way Channels"                   
796               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[minMW - maxMW]"
797               <<"  =  " <<resetiosflags(std::ios::right)
798               <<par.getMinMW()
799               <<"-" <<par.getMaxMW()          <<std::endl;
800    }
801    theStream  <<std::setw(widthText)<<"Beam Size (pixels)"                   
802               <<std::setw(widthPar)<<setiosflags(std::ios::right)<< beamParam
803               <<"  =  " <<resetiosflags(std::ios::right)
804               <<par.getBeamSize()       <<std::endl;
805    theStream  <<std::setw(widthText)<<"Removing baselines before search?"   
806               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagBaseline]"
807               <<"  =  " <<resetiosflags(std::ios::right)
808               <<stringize(par.getFlagBaseline())   <<std::endl;
809    theStream  <<std::setw(widthText)<<"Smoothing each spectrum first?"       
810               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagSmooth]"
811               <<"  =  " <<resetiosflags(std::ios::right)
812               <<stringize(par.getFlagSmooth())     <<std::endl;
813    if(par.getFlagSmooth()){           
814      theStream<<std::setw(widthText)<<"Type of smoothing"     
815               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[smoothType]"
816               <<"  =  " <<resetiosflags(std::ios::right)
817               <<par.getSmoothType()       <<std::endl;
818      if(par.getSmoothType()=="spectral")
819        theStream<<std::setw(widthText)<<"Width of hanning filter"     
820                 <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[hanningWidth]"
821                 <<"  =  " <<resetiosflags(std::ios::right)
822                 <<par.getHanningWidth()       <<std::endl;
823      else{
824        theStream<<std::setw(widthText)<<"Gaussian kernel semi-major axis [pix]"
825                 <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[kernMaj]"
826                 <<"  =  " <<resetiosflags(std::ios::right)
827                 <<par.getKernMaj() << std::endl;
828        theStream<<std::setw(widthText)<<"Gaussian kernel semi-minor axis [pix]"
829                 <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[kernMin]"
830                 <<"  =  " <<resetiosflags(std::ios::right)
831                 <<par.getKernMin() << std::endl;
832        theStream<<std::setw(widthText)<<"Gaussian kernel position angle [deg]"
833                 <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[kernPA]"
834                 <<"  =  " <<resetiosflags(std::ios::right)
835                 <<par.getKernPA() << std::endl;
836      }
837    }
838    theStream  <<std::setw(widthText)<<"Using A Trous reconstruction?"       
839               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagATrous]"
840               <<"  =  " <<resetiosflags(std::ios::right)
841               <<stringize(par.getFlagATrous())     <<std::endl;
842    if(par.getFlagATrous()){                           
843      theStream<<std::setw(widthText)<<"Number of dimensions in reconstruction"     
844               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[reconDim]"
845               <<"  =  " <<resetiosflags(std::ios::right)
846               <<par.getReconDim()       <<std::endl;
847      if(par.getMaxScale()>0){
848        theStream<<std::setw(widthText-1)<<"Scales used in reconstruction"     
849                 <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[scaleMin-scaleMax]"
850                 <<"  =  " <<resetiosflags(std::ios::right)
851                 <<par.getMinScale() << "-" << par.getMaxScale()   <<std::endl;
852      }
853      else{
854        theStream<<std::setw(widthText)<<"Minimum scale in reconstruction"     
855                 <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[scaleMin]"
856                 <<"  =  " <<resetiosflags(std::ios::right)
857                 <<par.getMinScale()      <<std::endl;
858      }
859      theStream<<std::setw(widthText)<<"SNR Threshold within reconstruction" 
860               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[snrRecon]"
861               <<"  =  " <<resetiosflags(std::ios::right)
862               <<par.getAtrousCut()      <<std::endl;
863      theStream<<std::setw(widthText)<<"Filter being used for reconstruction"
864               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[filterCode]"
865               <<"  =  " <<resetiosflags(std::ios::right)
866               <<par.getFilterCode()
867               << " (" << par.getFilterName()  << ")" <<std::endl;
868    }                                                 
869    theStream  <<std::setw(widthText)<<"Using Robust statistics?"                 
870               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagRobustStats]"
871               <<"  =  " <<resetiosflags(std::ios::right)
872               <<stringize(par.getFlagRobustStats()) <<std::endl;
873    if(par.getFlagStatSec()){
874      theStream<<std::setw(widthText)<<"Section used by statistics calculation"
875               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[statSec]"
876               <<"  =  " <<resetiosflags(std::ios::right)
877               <<par.statSec.getSection()          <<std::endl;
878    }
879    theStream  <<std::setw(widthText)<<"Using FDR analysis?"                 
880               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagFDR]"
881               <<"  =  " <<resetiosflags(std::ios::right)
882               <<stringize(par.getFlagFDR())        <<std::endl;
883    if(par.getFlagFDR()){                                     
884      theStream<<std::setw(widthText)<<"Alpha value for FDR analysis"         
885               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[alphaFDR]"
886               <<"  =  " <<resetiosflags(std::ios::right)
887               <<par.getAlpha()          <<std::endl;
888    }                                                 
889    else {
890      if(par.getFlagUserThreshold()){
891        theStream<<std::setw(widthText)<<"Detection Threshold"                       
892                 <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[threshold]"
893                 <<"  =  " <<resetiosflags(std::ios::right)
894                 <<par.getThreshold()            <<std::endl;
895      }
896      else{
897        theStream<<std::setw(widthText)<<"SNR Threshold (in sigma)"
898                 <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[snrCut]"
899                 <<"  =  " <<resetiosflags(std::ios::right)
900                 <<par.getCut()            <<std::endl;
901      }
902    }
903    theStream  <<std::setw(widthText)<<"Minimum # Pixels in a detection"     
904               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[minPix]"
905               <<"  =  " <<resetiosflags(std::ios::right)
906               <<par.getMinPix()         <<std::endl;
907    theStream  <<std::setw(widthText)<<"Minimum # Channels in a detection"   
908               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[minChannels]"
909               <<"  =  " <<resetiosflags(std::ios::right)
910               <<par.getMinChannels()    <<std::endl;
911    theStream  <<std::setw(widthText)<<"Growing objects after detection?"     
912               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagGrowth]"
913               <<"  =  " <<resetiosflags(std::ios::right)
914               <<stringize(par.getFlagGrowth())     <<std::endl;
915    if(par.getFlagGrowth()) {                         
916      theStream<<std::setw(widthText)<<"SNR Threshold for growth"             
917               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[growthCut]"
918               <<"  =  " <<resetiosflags(std::ios::right)
919               <<par.getGrowthCut()      <<std::endl;
920    }
921    theStream  <<std::setw(widthText)<<"Using Adjacent-pixel criterion?"     
922               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[flagAdjacent]"
923               <<"  =  " <<resetiosflags(std::ios::right)
924               <<stringize(par.getFlagAdjacent())   <<std::endl;
925    if(!par.getFlagAdjacent()){
926      theStream<<std::setw(widthText)<<"Max. spatial separation for merging" 
927               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[threshSpatial]"
928               <<"  =  " <<resetiosflags(std::ios::right)
929               <<par.getThreshS()        <<std::endl;
930    }
931    theStream  <<std::setw(widthText)<<"Max. velocity separation for merging"
932               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[threshVelocity]"
933               <<"  =  " <<resetiosflags(std::ios::right)
934               <<par.getThreshV()        <<std::endl;
935    theStream  <<std::setw(widthText)<<"Method of spectral plotting"         
936               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[spectralMethod]"
937               <<"  =  " <<resetiosflags(std::ios::right)
938               <<par.getSpectralMethod() <<std::endl;
939    theStream  <<std::setw(widthText)<<"Type of object centre used in results"
940               <<std::setw(widthPar)<<setiosflags(std::ios::right)<<"[pixelCentre]"
941               <<"  =  " <<resetiosflags(std::ios::right)
942               <<par.getPixelCentre() <<std::endl;
943    theStream  <<"--------------------\n\n";
944    theStream  << std::setfill(' ');
945    theStream.unsetf(std::ios::left);
946    //  theStream.unsetf(std::ios::boolalpha);
947    return theStream;
948  }
949
950
951  void Param::copyHeaderInfo(FitsHeader &head)
952  {
953    /**
954     * A function to copy across relevant header keywords from the
955     *  FitsHeader class to the Param class, as they are needed by
956     *  functions in the Param class.
957     * The parameters are the keywords BLANK, BSCALE, BZERO, and the beam size.
958     */
959
960    this->blankKeyword  = head.getBlankKeyword();
961    this->bscaleKeyword = head.getBscaleKeyword();
962    this->bzeroKeyword  = head.getBzeroKeyword();
963    this->blankPixValue = this->blankKeyword * this->bscaleKeyword +
964      this->bzeroKeyword;
965
966    this->numPixBeam    = head.getBeamSize();
967  }
968
969  std::string Param::outputMaskFile()
970  {
971    /**
972     *  This function produces the required filename in which to save
973     *  the mask image, indicating which pixels have been detected as
974     *  part of an object. If the input image is image.fits, then the
975     *  output will be image.MASK.fits.
976     */
977    std::string inputName = this->imageFile;
978    std::stringstream ss;
979    ss << inputName.substr(0,inputName.size()-5); 
980    // remove the ".fits" on the end.
981    ss << ".MASK.fits";
982    return ss.str();
983  }
984
985  std::string Param::outputSmoothFile()
986  {
987    /**
988     * This function produces the required filename in which to save
989     *  the smoothed array. If the input image is image.fits, then
990     *  the output will be:
991     *   <ul><li> Spectral smoothing: image.SMOOTH-1D-3.fits, where the
992     *            width of the Hanning filter was 3 pixels.
993     *       <li> Spatial smoothing : image.SMOOTH-2D-3-2-20.fits, where
994     *            kernMaj=3, kernMin=2 and kernPA=20 degrees.
995     *   </ul>
996     */
997    std::string inputName = this->imageFile;
998    std::stringstream ss;
999    ss << inputName.substr(0,inputName.size()-5); 
1000    // remove the ".fits" on the end.
1001    if(this->flagSubsection) ss<<".sub";
1002    if(this->smoothType=="spectral")
1003      ss << ".SMOOTH-1D-" << this->hanningWidth << ".fits";
1004    else if(this->smoothType=="spatial")
1005      ss << ".SMOOTH-2D-"
1006         << this->kernMaj << "-"
1007         << this->kernMin << "-"
1008         << this->kernPA  << ".fits";
1009    return ss.str();
1010  }
1011
1012  std::string Param::outputReconFile()
1013  {
1014    /**
1015     * This function produces the required filename in which to save
1016     *  the reconstructed array. If the input image is image.fits, then
1017     *  the output will be eg. image.RECON-3-2-4-1.fits, where the numbers are
1018     *  3=reconDim, 2=filterCode, 4=snrRecon, 1=minScale
1019     */
1020    std::string inputName = this->imageFile;
1021    std::stringstream ss;
1022    // First we remove the ".fits" from the end of the filename.
1023    ss << inputName.substr(0,inputName.size()-5); 
1024    if(this->flagSubsection) ss<<".sub";
1025    ss << ".RECON-" << this->reconDim
1026       << "-"       << this->filterCode
1027       << "-"       << this->snrRecon
1028       << "-"       << this->scaleMin
1029       << ".fits";
1030    return ss.str();
1031  }
1032
1033  std::string Param::outputResidFile()
1034  {
1035    /**
1036     * This function produces the required filename in which to save
1037     *  the reconstructed array. If the input image is image.fits, then
1038     *  the output will be eg. image.RESID-3-2-4-1.fits, where the numbers are
1039     *  3=reconDim, 2=filterCode, 4=snrRecon, 1=scaleMin
1040     */
1041    std::string inputName = this->imageFile;
1042    std::stringstream ss;
1043    // First we remove the ".fits" from the end of the filename.
1044    ss << inputName.substr(0,inputName.size()-5);
1045    if(this->flagSubsection) ss<<".sub";
1046    ss << ".RESID-" << this->reconDim
1047       << "-"       << this->filterCode
1048       << "-"       << this->snrRecon
1049       << "-"       << this->scaleMin
1050       << ".fits";
1051    return ss.str();
1052  }
1053
1054}
Note: See TracBrowser for help on using the repository browser.