source: trunk/src/param.cc @ 270

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

A large set of changes, each of which small ones from compiling with the -Wall flag (plus the -Wno-sign-compare flag -- as we don't care about warnings about comparing ints and unsigned ints).

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