source: trunk/src/param.cc @ 410

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

Added unistd.h to the include statements in param.cc, to ensure it compiles properly.

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