source: trunk/src/param.cc @ 303

Last change on this file since 303 was 299, checked in by Matthew Whiting, 17 years ago

Adding distribution text at the start of each file...

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