source: trunk/src/param.cc @ 326

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

Mostly changes to fix some memory allocation/deallocation issues raised by valgrind. Minor changes to the Guide.

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