source: trunk/src/param.cc @ 474

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

Rename Rrose to Selavy and starting to fix up the reading of options

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