source: trunk/src/param.cc @ 266

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