source: trunk/src/param.cc @ 541

Last change on this file since 541 was 541, checked in by MatthewWhiting, 15 years ago

Changing all calls of uint to unsigned int, as there are sometimes compilers that don't know about that typedef. Also added an include call for stdlib.h to fitsHeader.cc so that it knows about calloc.

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