source: tags/release-1.1.7/src/param.cc @ 533

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

Changing the documentation comments to match the askapsoft style. Also have split ChanMap? and Object3D into separate files.

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