source: trunk/src/param.cc @ 132

Last change on this file since 132 was 132, checked in by Matthew Whiting, 18 years ago

Added a new function that changes a string to a bool variable. This way the
user can write "true"/"false" instead of "1"/"0" for the flag parameters in
the input file, and they will get read the same.

File size: 27.7 KB
Line 
1#include <iostream>
2#include <iomanip>
3#include <fstream>
4#include <sstream>
5#include <string>
6#include <math.h>
7#include <wcs.h>
8#include <wcsunits.h>
9#include <duchamp.hh>
10#include <param.hh>
11#include <Utils/utils.hh>
12
13// Define funtion to print bools as words, in case the compiler doesn't recognise
14// the setf(ios::boolalpha) command...
15#ifdef HAVE_STDBOOL_H
16string stringize(bool b){
17  std::stringstream ss;
18  ss.setf(std::ios::boolalpha);
19  ss << b;
20  return ss.str();
21}
22#else
23string stringize(bool b){
24  std::string output;
25  if(b) output="true";
26  else output="false";
27  return output;
28}
29#endif
30
31using std::setw;
32using std::endl;
33
34/****************************************************************/
35///////////////////////////////////////////////////
36//// Functions for FitsHeader class:
37///////////////////////////////////////////////////
38
39FitsHeader::FitsHeader(){
40  this->wcs = new wcsprm;
41  this->wcs->flag=-1;
42  wcsini(true,3,this->wcs);
43  this->wcsIsGood = false;
44  this->nwcs = 0;
45  this->scale=1.;
46  this->offset=0.;
47  this->power=1.;
48  this->fluxUnits="counts";
49}
50
51FitsHeader::FitsHeader(const FitsHeader& h){
52  this->wcs = new wcsprm;
53  this->wcs->flag=-1;
54  wcsini(true,h.wcs->naxis,this->wcs);
55  wcscopy(true,h.wcs,this->wcs);
56  wcsset(this->wcs);
57  nwcs = h.nwcs;
58  wcsIsGood = h.wcsIsGood;
59  spectralUnits = h.spectralUnits;
60  fluxUnits = h.fluxUnits;
61  intFluxUnits = h.intFluxUnits;
62  beamSize = h.beamSize;
63  bmajKeyword = h.bmajKeyword;
64  bminKeyword = h.bminKeyword;
65  blankKeyword = h.blankKeyword;
66  bzeroKeyword = h.bzeroKeyword;
67  bscaleKeyword = h.bscaleKeyword;
68  scale = h.scale;
69  offset = h.offset;
70  power = h.power;
71}
72
73FitsHeader& FitsHeader::operator= (const FitsHeader& h){
74  this->wcs = new wcsprm;
75  this->wcs->flag=-1;
76  wcsini(true,h.wcs->naxis,this->wcs);
77  wcscopy(true,h.wcs,this->wcs);
78  wcsset(this->wcs);
79  nwcs = h.nwcs;
80  wcsIsGood = h.wcsIsGood;
81  spectralUnits = h.spectralUnits;
82  fluxUnits = h.fluxUnits;
83  intFluxUnits = h.intFluxUnits;
84  beamSize = h.beamSize;
85  bmajKeyword = h.bmajKeyword;
86  bminKeyword = h.bminKeyword;
87  blankKeyword = h.blankKeyword;
88  bzeroKeyword = h.bzeroKeyword;
89  bscaleKeyword = h.bscaleKeyword;
90  scale = h.scale;
91  offset = h.offset;
92  power = h.power;
93}
94
95void FitsHeader::setWCS(wcsprm *w)
96{
97  /**
98   * FitsHeader::setWCS(wcsprm *)
99   *  A function that assigns the wcs parameters, and runs
100   *   wcsset to set it up correctly.
101   *  Performs a check to see if the WCS is good (by looking at
102   *   the lng and lat wcsprm parameters), and sets the wcsIsGood
103   *   flag accordingly.
104   */
105  wcscopy(true,w,this->wcs);
106  wcsset(this->wcs);
107  if( (w->lng!=-1) && (w->lat!=-1) ) this->wcsIsGood = true;
108}
109
110wcsprm *FitsHeader::getWCS()
111{
112  /**
113   * FitsHeader::getWCS()
114   *  A function that returns a wcsprm object corresponding to the WCS.
115   */
116  wcsprm *wNew = new wcsprm;
117  wNew->flag=-1;
118  wcsini(true,this->wcs->naxis,wNew);
119  wcscopy(true,this->wcs,wNew);
120  wcsset(wNew);
121  return wNew;
122}
123
124int     FitsHeader::wcsToPix(const double *world, double *pix){
125  return wcsToPixSingle(this->wcs,world,pix);}
126int     FitsHeader::wcsToPix(const double *world, double *pix, const int npts){
127  return wcsToPixMulti(this->wcs,world,pix,npts);}
128int     FitsHeader::pixToWCS(const double *pix, double *world){
129  return pixToWCSSingle(this->wcs,pix,world);}
130int     FitsHeader::pixToWCS(const double *pix, double *world, const int npts){
131  return pixToWCSMulti(this->wcs,pix,world,npts);}
132
133double  FitsHeader::pixToVel(double &x, double &y, double &z)
134{
135//   return pixelToVelocity(this->wcs,x,y,z,this->spectralUnits);};
136  double *pix   = new double[3];
137  double *world = new double[3];
138  pix[0] = x; pix[1] = y; pix[2] = z;
139  pixToWCSSingle(this->wcs,pix,world);
140  double vel = this->specToVel(world[2]);
141  delete [] pix;
142  delete [] world;
143  return vel;
144}
145
146double* FitsHeader::pixToVel(double &x, double &y, double *zarray, int size)
147{
148//   return pixelToVelocity(this->wcs,x,y,z,this->spectralUnits);};
149  double *pix   = new double[size*3];
150  for(int i=0;i<size;i++){
151    pix[3*i] = x; pix[3*i+1] = y; pix[3*i+2] = zarray[i];
152  }
153  double *world = new double[size*3];
154  pixToWCSMulti(this->wcs,pix,world,size);
155  delete [] pix;
156  double *newzarray = new double[size];
157  for(int i=0;i<size;i++) newzarray[i] = this->specToVel(world[3*i+2]);
158  delete [] world;
159  return newzarray;
160}
161
162double  FitsHeader::specToVel(const double &coord)
163{
164//   return coordToVel(this->wcs,coord,this->spectralUnits);};
165  double vel;
166  if(power==1.0){
167//     std::cerr << coord << " --> " << coord*this->scale + this->offset << std::endl;
168    vel =  coord*this->scale + this->offset;
169  }
170  else vel = pow( (coord*this->scale + this->offset), this->power);
171
172  return vel;
173}
174
175double  FitsHeader::velToSpec(const float &velocity)
176{
177//   return velToCoord(this->wcs,velocity,this->spectralUnits);};
178  return (pow(velocity, 1./this->power) - this->offset) / this->scale;}
179
180string  FitsHeader::getIAUName(double ra, double dec)
181{
182  if(strcmp(this->wcs->lngtyp,"RA")==0) return getIAUNameEQ(ra, dec, this->wcs->equinox);
183  else return getIAUNameGAL(ra, dec);
184}
185
186void FitsHeader::fixUnits(Param &par)
187{
188  // define spectral units from the param set
189  this->spectralUnits = par.getSpectralUnits();
190
191  double sc=1.;
192  double of=0.;
193  double po=1.;;
194  if(this->wcsIsGood){
195    int flag = wcsunits( this->wcs->cunit[2], this->spectralUnits.c_str(), &sc, &of, &po);
196    if(flag>0){
197      std::stringstream errmsg;
198      errmsg << "WCSUNITS Error, Code = " << flag << ": "<< wcsunits_errmsg[flag];
199      if(flag==10) errmsg << "\nTried to get conversion from '" << wcs->cunit[2]
200                          << "' to '" << this->spectralUnits.c_str() << "'\n";
201      this->spectralUnits = this->wcs->cunit[2];
202      if(this->spectralUnits==""){
203        errmsg << "Setting coordinates to 'XX' for clarity.\n";
204        this->spectralUnits = "XX";
205      }
206      duchampError("fixUnits", errmsg.str());
207     
208    }
209  }
210  this->scale = sc;
211  this->offset= of;
212  this->power = po;
213
214  // work out the integrated flux units, based on the spectral units
215  // if flux is per beam, trim the /beam from the flux units and multiply by the spectral units.
216  // otherwise, just muliply by the spectral units.
217  if(this->fluxUnits.size()>0){
218    if(this->fluxUnits.substr(this->fluxUnits.size()-5,this->fluxUnits.size())=="/beam"){
219      this->intFluxUnits = this->fluxUnits.substr(0,this->fluxUnits.size()-5)
220        +" " +this->spectralUnits;
221    }
222    else this->intFluxUnits = fluxUnits + " " + this->spectralUnits;
223  }
224
225}
226
227/****************************************************************/
228///////////////////////////////////////////////////
229//// Accessor Functions for Parameter class:
230///////////////////////////////////////////////////
231Param::Param(){
232  /**
233   * Param()
234   *  Default intial values for the parameters.
235   * imageFile has no default value!
236   */
237  // Input files
238  this->imageFile       = "";
239  this->flagSubsection  = false;
240  this->subsection      = "[*,*,*]";
241  this->flagReconExists = false;
242  this->reconFile       = "";
243  // Output files
244  this->flagLog         = true;
245  this->logFile         = "duchamp-Logfile.txt";
246  this->outFile         = "duchamp-Results.txt";
247  this->spectraFile     = "duchamp-Spectra.ps";
248  this->flagOutputRecon = false;
249  this->flagOutputResid = false;
250  this->flagVOT         = false;
251  this->votFile         = "duchamp-Results.xml";
252  this->flagKarma       = false;
253  this->karmaFile       = "duchamp-Results.ann";
254  this->flagMaps        = true;
255  this->detectionMap    = "duchamp-DetectionMap.ps";
256  this->momentMap       = "duchamp-MomentMap.ps";
257  // Cube related parameters
258  this->flagBlankPix    = true;
259  this->blankPixValue   = -8.00061;
260  this->blankKeyword    = 1;
261  this->bscaleKeyword   = -8.00061;
262  this->bzeroKeyword    = 0.;
263  this->flagUsingBlank  = false;
264  this->flagMW          = false;
265  this->maxMW           = 112;
266  this->minMW           = 75;
267  this->numPixBeam      = 0.;
268  // Trim-related         
269  this->flagTrimmed     = false;
270  this->borderLeft      = 0;
271  this->borderRight     = 0;
272  this->borderBottom    = 0;
273  this->borderTop       = 0;
274  // Subsection offsets
275  this->xSubOffset      = 0;
276  this->ySubOffset      = 0;
277  this->zSubOffset      = 0;
278  // Baseline related
279  this->flagBaseline    = false;
280  // Detection-related   
281  this->flagNegative    = false;
282  // Object growth       
283  this->flagGrowth      = false;
284  this->growthCut       = 2.;
285  // FDR analysis         
286  this->flagFDR         = false;
287  this->alphaFDR        = 0.01;
288  // Other detection     
289  this->snrCut          = 3.;
290  // A trous reconstruction parameters
291  this->flagATrous      = true;
292  this->reconDim        = 3;
293  this->scaleMin        = 1;
294  this->snrRecon        = 4.;
295  this->filterCode      = 1;
296  // Volume-merging parameters
297  this->flagAdjacent    = true;
298  this->threshSpatial   = 3.;
299  this->threshVelocity  = 7.;
300  this->minChannels     = 3;
301  this->minPix          = 2;
302  // Input-Output related
303  this->spectralMethod  = "peak";
304  this->borders         = true;
305  this->verbose         = true;
306  this->spectralUnits   = "km/s";
307};
308
309/****************************************************************/
310///////////////////////////////////////////////////
311//// Other Functions using the  Parameter class:
312///////////////////////////////////////////////////
313
314string makelower( string s )
315{
316  // "borrowed" from Matt Howlett's 'fred'
317  string out = "";
318  for( int i=0; i<s.size(); ++i ) {
319    out += tolower(s[i]);
320  }
321  return out;
322}
323
324bool flagify( string s )
325{
326  /**
327   * flagify(string)
328   *  Convert a string to a bool variable
329   *  "1" and "true" get converted to true
330   *  "0" and "false" (and anything else) get converted to false
331   */
332  if((s=="1") || (makelower(s)=="true")) return true;
333  else if((s=="0") || (makelower(s)=="false")) return false;
334  else return false;
335}
336
337void Param::readParams(string paramfile)
338{
339
340  std::ifstream fin(paramfile.c_str());
341  string line;
342  string sval;
343  float fval;
344  int ival;
345  while( !std::getline(fin,line,'\n').eof()){
346
347    if(line[0]!='#'){
348      std::stringstream ss;
349      ss.str(line);
350      string arg;
351      ss >> arg;     
352      if(makelower(arg)=="imagefile"){       ss >> sval; this->imageFile = sval;}
353      if(makelower(arg)=="flagsubsection"){  ss >> sval; this->flagSubsection = flagify(sval); }
354      if(makelower(arg)=="subsection"){      ss >> sval; this->subsection = sval; }
355      if(makelower(arg)=="flagreconexists"){ ss >> sval; this->flagReconExists = flagify(sval); }
356      if(makelower(arg)=="reconfile"){       ss >> sval; this->reconFile = sval; }
357
358      if(makelower(arg)=="flaglog"){         ss >> sval; this->flagLog = flagify(sval); }
359      if(makelower(arg)=="logfile"){         ss >> sval; this->logFile = sval; }
360      if(makelower(arg)=="outfile"){         ss >> sval; this->outFile = sval; }
361      if(makelower(arg)=="spectrafile"){     ss >> sval; this->spectraFile = sval; }
362      if(makelower(arg)=="flagoutputrecon"){ ss >> sval; this->flagOutputRecon = flagify(sval); }
363      if(makelower(arg)=="flagoutputresid"){ ss >> sval; this->flagOutputResid = flagify(sval); }
364      if(makelower(arg)=="flagvot"){         ss >> sval; this->flagVOT = flagify(sval); }
365      if(makelower(arg)=="votfile"){         ss >> sval; this->votFile = sval; }
366      if(makelower(arg)=="flagkarma"){       ss >> sval; this->flagKarma = flagify(sval); }
367      if(makelower(arg)=="karmafile"){       ss >> sval; this->karmaFile = sval; }
368      if(makelower(arg)=="flagmaps"){        ss >> sval; this->flagMaps = flagify(sval); }
369      if(makelower(arg)=="detectionmap"){    ss >> sval; this->detectionMap = sval; }
370      if(makelower(arg)=="momentmap"){       ss >> sval; this->momentMap = sval; }
371
372      if(makelower(arg)=="flagnegative"){    ss >> sval; this->flagNegative = flagify(sval);}
373      if(makelower(arg)=="flagblankpix"){    ss >> sval; this->flagBlankPix = flagify(sval); }
374      if(makelower(arg)=="blankpixvalue"){   ss >> fval; this->blankPixValue = fval; }
375      if(makelower(arg)=="flagmw"){          ss >> sval; this->flagMW = flagify(sval); }
376      if(makelower(arg)=="maxmw"){           ss >> ival; this->maxMW = ival; }
377      if(makelower(arg)=="minmw"){           ss >> ival; this->minMW = ival; }
378
379      if(makelower(arg)=="flagbaseline"){    ss >> sval; this->flagBaseline = flagify(sval); }
380      if(makelower(arg)=="minpix"){          ss >> ival; this->minPix = ival; }
381      if(makelower(arg)=="flaggrowth"){      ss >> sval; this->flagGrowth = flagify(sval); }
382      if(makelower(arg)=="growthcut"){       ss >> fval; this->growthCut = fval; }
383
384      if(makelower(arg)=="flagfdr"){         ss >> sval; this->flagFDR = flagify(sval); }
385      if(makelower(arg)=="alphafdr"){        ss >> fval; this->alphaFDR = fval; }
386
387      if(makelower(arg)=="snrcut"){          ss >> fval; this->snrCut = fval; }
388
389      if(makelower(arg)=="flagatrous"){      ss >> sval; this->flagATrous = flagify(sval); }
390      if(makelower(arg)=="recondim"){        ss >> ival; this->reconDim = ival; }
391      if(makelower(arg)=="scalemin"){        ss >> ival; this->scaleMin = ival; }
392      if(makelower(arg)=="snrrecon"){        ss >> fval; this->snrRecon = fval; }
393      if(makelower(arg)=="filtercode"){      ss >> ival; this->filterCode = ival; }
394
395      if(makelower(arg)=="flagadjacent"){    ss >> sval; this->flagAdjacent = flagify(sval); }
396      if(makelower(arg)=="threshspatial"){   ss >> fval; this->threshSpatial = fval; }
397      if(makelower(arg)=="threshvelocity"){  ss >> fval; this->threshVelocity = fval; }
398      if(makelower(arg)=="minchannels"){     ss >> ival; this->minChannels = ival; }
399
400      if(makelower(arg)=="spectralmethod"){  ss >> sval; this->spectralMethod = makelower(sval); }
401      if(makelower(arg)=="spectralunits"){   ss >> sval; this->spectralUnits = makelower(sval); }
402      if(makelower(arg)=="drawborders"){     ss >> sval; this->borders = flagify(sval); }
403      if(makelower(arg)=="verbose"){         ss >> sval; this->verbose = flagify(sval); }
404    }
405  }
406}
407
408
409std::ostream& operator<< ( std::ostream& theStream, Param& par)
410{
411  // Only show the [blankPixValue] bit if we are using the parameter
412  // otherwise we have read it from the FITS header.
413  string blankParam = "";
414  if(par.getFlagUsingBlank()) blankParam = "[blankPixValue]";
415
416  // BUG -- can get error: `boolalpha' is not a member of type `ios' -- old compilers: gcc 2.95.3?
417//   theStream.setf(std::ios::boolalpha);
418  theStream.setf(std::ios::left);
419  theStream  <<"---- Parameters ----"<<endl;
420  theStream  << std::setfill('.');
421  if(par.getFlagSubsection())
422    theStream<<setw(38)<<"Image to be analysed"                 
423             <<setw(18)<<setiosflags(std::ios::right)  <<"[imageFile]"
424             <<"  =  " <<resetiosflags(std::ios::right)
425             <<(par.getImageFile()+par.getSubsection())   <<endl;
426  else
427    theStream<<setw(38)<<"Image to be analysed"                 
428             <<setw(18)<<setiosflags(std::ios::right)  <<"[imageFile]"
429             <<"  =  " <<resetiosflags(std::ios::right)<<par.getImageFile()      <<endl;
430  if(par.getFlagReconExists() && par.getFlagATrous()){
431    theStream<<setw(38)<<"Reconstructed array exists?"         
432             <<setw(18)<<setiosflags(std::ios::right)  <<"[reconExists]"
433             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagReconExists())<<endl;
434    theStream<<setw(38)<<"FITS file containing reconstruction" 
435             <<setw(18)<<setiosflags(std::ios::right)  <<"[reconFile]"
436             <<"  =  " <<resetiosflags(std::ios::right)<<par.getReconFile()      <<endl;
437  }
438  theStream  <<setw(38)<<"Intermediate Logfile"
439             <<setw(18)<<setiosflags(std::ios::right)  <<"[logFile]"
440             <<"  =  " <<resetiosflags(std::ios::right)<<par.getLogFile()        <<endl;
441  theStream  <<setw(38)<<"Final Results file"                   
442             <<setw(18)<<setiosflags(std::ios::right)  <<"[outFile]"
443             <<"  =  " <<resetiosflags(std::ios::right)<<par.getOutFile()        <<endl;
444  theStream  <<setw(38)<<"Spectrum file"                       
445             <<setw(18)<<setiosflags(std::ios::right)  <<"[spectraFile]"
446             <<"  =  " <<resetiosflags(std::ios::right)<<par.getSpectraFile()    <<endl;
447  if(par.getFlagVOT()){
448    theStream<<setw(38)<<"VOTable file"                         
449             <<setw(18)<<setiosflags(std::ios::right)  <<"[votFile]"
450             <<"  =  " <<resetiosflags(std::ios::right)<<par.getVOTFile()        <<endl;
451  }
452  if(par.getFlagKarma()){
453    theStream<<setw(38)<<"Karma annotation file"               
454             <<setw(18)<<setiosflags(std::ios::right)  <<"[karmaFile]"
455             <<"  =  " <<resetiosflags(std::ios::right)<<par.getKarmaFile()      <<endl;
456  }
457  if(par.getFlagMaps()){
458    theStream<<setw(38)<<"0th Moment Map"                       
459             <<setw(18)<<setiosflags(std::ios::right)  <<"[momentMap]"
460             <<"  =  " <<resetiosflags(std::ios::right)<<par.getMomentMap()      <<endl;
461    theStream<<setw(38)<<"Detection Map"                       
462             <<setw(18)<<setiosflags(std::ios::right)  <<"[detectionMap]"
463             <<"  =  " <<resetiosflags(std::ios::right)<<par.getDetectionMap()   <<endl;
464  }
465  if(par.getFlagATrous()){                             
466    theStream<<setw(38)<<"Saving reconstructed cube?"           
467             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagoutputrecon]"
468             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagOutputRecon())<<endl;
469    theStream<<setw(38)<<"Saving residuals from reconstruction?"
470             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagoutputresid]"
471             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagOutputResid())<<endl;
472  }                                                   
473  theStream  <<"------"<<endl;
474  theStream  <<setw(38)<<"Searching for Negative features?"     
475             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagNegative]"
476             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagNegative())   <<endl;
477  theStream  <<setw(38)<<"Fixing Blank Pixels?"                 
478             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagBlankPix]"
479             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagBlankPix())   <<endl;
480  if(par.getFlagBlankPix()){
481    theStream<<setw(38)<<"Blank Pixel Value"                   
482             <<setw(18)<<setiosflags(std::ios::right)  << blankParam
483             <<"  =  " <<resetiosflags(std::ios::right)<<par.getBlankPixVal()    <<endl;
484  }
485  theStream  <<setw(38)<<"Removing Milky Way channels?"         
486             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagMW]"
487             <<"  =  " <<resetiosflags(std::ios::right)<<par.getFlagMW()         <<endl;
488  if(par.getFlagMW()){
489    theStream<<setw(38)<<"Milky Way Channels"                   
490             <<setw(18)<<setiosflags(std::ios::right)  <<"[minMW - maxMW]"
491             <<"  =  " <<resetiosflags(std::ios::right)<<par.getMinMW()
492             <<"-" <<par.getMaxMW()          <<endl;
493  }
494  theStream  <<setw(38)<<"Beam Size (pixels)"                   
495             <<setw(18)<<setiosflags(std::ios::right)  <<""
496             <<"  =  " <<resetiosflags(std::ios::right)<<par.getBeamSize()       <<endl;
497  theStream  <<setw(38)<<"Removing baselines before search?"   
498             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagBaseline]"
499             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagBaseline())   <<endl;
500  theStream  <<setw(38)<<"Minimum # Pixels in a detection"     
501             <<setw(18)<<setiosflags(std::ios::right)  <<"[minPix]"
502             <<"  =  " <<resetiosflags(std::ios::right)<<par.getMinPix()         <<endl;
503  theStream  <<setw(38)<<"Minimum # Channels in a detection"   
504             <<setw(18)<<setiosflags(std::ios::right)  <<"[minChannels]"
505             <<"  =  " <<resetiosflags(std::ios::right)<<par.getMinChannels()    <<endl;
506  theStream  <<setw(38)<<"Growing objects after detection?"     
507             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagGrowth]"
508             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagGrowth())     <<endl;
509  if(par.getFlagGrowth()) {                           
510    theStream<<setw(38)<<"SNR Threshold for growth"             
511             <<setw(18)<<setiosflags(std::ios::right)  <<"[growthCut]"
512             <<"  =  " <<resetiosflags(std::ios::right)<<par.getGrowthCut()      <<endl;
513  }
514  theStream  <<setw(38)<<"Using A Trous reconstruction?"       
515             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagATrous]"
516             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagATrous())     <<endl;
517  if(par.getFlagATrous()){                             
518    theStream<<setw(38)<<"Number of dimensions in reconstruction"     
519             <<setw(18)<<setiosflags(std::ios::right)  <<"[reconDim]"
520             <<"  =  " <<resetiosflags(std::ios::right)<<par.getReconDim()       <<endl;
521    theStream<<setw(38)<<"Minimum scale in reconstruction"     
522             <<setw(18)<<setiosflags(std::ios::right)  <<"[scaleMin]"
523             <<"  =  " <<resetiosflags(std::ios::right)<<par.getMinScale()       <<endl;
524    theStream<<setw(38)<<"SNR Threshold within reconstruction" 
525             <<setw(18)<<setiosflags(std::ios::right)  <<"[snrRecon]"
526             <<"  =  " <<resetiosflags(std::ios::right)<<par.getAtrousCut()      <<endl;
527    theStream<<setw(38)<<"Filter being used for reconstruction"
528             <<setw(18)<<setiosflags(std::ios::right)  <<"[filterCode]"
529             <<"  =  " <<resetiosflags(std::ios::right)<<par.getFilterCode()
530             << " (" << par.getFilterName()  << ")" <<endl;
531  }                                                   
532  theStream  <<setw(38)<<"Using FDR analysis?"                 
533             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagFDR]"
534             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagFDR())        <<endl;
535  if(par.getFlagFDR()){                               
536    theStream<<setw(38)<<"Alpha value for FDR analysis"         
537             <<setw(18)<<setiosflags(std::ios::right)  <<"[alphaFDR]"
538             <<"  =  " <<resetiosflags(std::ios::right)<<par.getAlpha()          <<endl;
539  }                                                   
540  else {
541    theStream<<setw(38)<<"SNR Threshold"                       
542             <<setw(18)<<setiosflags(std::ios::right)  <<"[snrCut]"
543             <<"  =  " <<resetiosflags(std::ios::right)<<par.getCut()            <<endl;
544  }
545  theStream  <<setw(38)<<"Using Adjacent-pixel criterion?"     
546             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagAdjacent]"
547             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagAdjacent())   <<endl;
548  if(!par.getFlagAdjacent()){
549    theStream<<setw(38)<<"Max. spatial separation for merging" 
550             <<setw(18)<<setiosflags(std::ios::right)  <<"[threshSpatial]"
551             <<"  =  " <<resetiosflags(std::ios::right)<<par.getThreshS()        <<endl;
552  }
553  theStream  <<setw(38)<<"Max. velocity separation for merging"
554             <<setw(18)<<setiosflags(std::ios::right)  <<"[threshVelocity]"
555             <<"  =  " <<resetiosflags(std::ios::right)<<par.getThreshV()        <<endl;
556  theStream  <<setw(38)<<"Method of spectral plotting"         
557             <<setw(18)<<setiosflags(std::ios::right)  <<"[spectralMethod]"
558             <<"  =  " <<resetiosflags(std::ios::right)<<par.getSpectralMethod() <<endl;
559  theStream  <<"--------------------"<<endl;
560  theStream  << std::setfill(' ');
561  theStream.unsetf(std::ios::left);
562  //  theStream.unsetf(std::ios::boolalpha);
563}
564
565void Param::parseSubsection()
566{
567  /**
568   *  Param::parseSubsection()
569   *
570   *   Convert the Param::subsection string to a series of offset values
571   *    for each dimension.
572   *   This involves reading the individual substrings and converting to
573   *    integers, and storing in the {x,y,z}SubOffset parameters.
574   *   Steps in the subsection string are not dealt with -- a warning message
575   *    is written to the screen, and the step values are ignored.
576   */
577
578  std::stringstream ss;
579  ss.str(this->subsection);
580  bool removeStep = false;
581  string x,y,z;
582  getline(ss,x,'[');
583  getline(ss,x,',');
584  getline(ss,y,',');
585  getline(ss,z,']');
586  char *end;
587  if(x!="*") {
588    int x1,x2,dx;
589    int a = x.find(':');  // first occurence of ':' in x-subsection string
590    int b = x.find(':',a+1); // location of second ':' -- will be -1 if there is no second occurence.
591    x1 = atoi( x.substr(0,a).c_str() ); // minimum x in subsection
592    this->xSubOffset = x1 - 1;
593    if(b>0){ // there is a dx component
594      x2 = atoi( x.substr(a+1,b-a-1).c_str() ); // maximum x in subsection
595      dx = atoi( x.substr(b+1,x.size()).c_str() ); // delta x in subsection
596      x = x.substr(0,b); // rewrite x without the delta-x part.
597      removeStep = true;
598    }
599  }
600  if(y!="*") {
601    int y1,y2,dy;
602    int a = y.find(':');  // first occurence of ':' in y-subsection string
603    int b = y.find(':',a+1); // location of second ':' -- will be -1 if there is no second occurence.
604    y1 = atoi( y.substr(0,a).c_str() ); // minimum y in subsection
605    this->ySubOffset = y1 - 1;
606    if(b>0){ // there is a dy component
607      y2 = atoi( y.substr(a+1,b-a-1).c_str() ); // maximum y in subsection
608      dy = atoi( y.substr(b+1,y.size()).c_str() ); // delta y in subsection
609      y = y.substr(0,b); // rewrite y without the delta-y part.
610      removeStep = true;
611    }
612  }
613  if(z!="*") {
614    int z1,z2,dz;
615    int a = z.find(':');  // first occurence of ':' in z-subsection string
616    int b = z.find(':',a+1); // location of second ':' -- will be -1 if there is no second occurence.
617    z1 = atoi( z.substr(0,a).c_str() ); // minimum z in subsection
618    this->zSubOffset = z1 - 1;
619    if(b>0){ // there is a dz component
620      z2 = atoi( z.substr(a+1,b-a-1).c_str() ); // maximum z in subsection
621      dz = atoi( z.substr(b+1,z.size()).c_str() ); // delta z in subsection
622      z = z.substr(0,b); // rewrite z without the delta-z part.
623      removeStep = true;
624    }
625  }
626
627  if(removeStep){
628    std::cerr << "\a\tThe subsection given is " << this->subsection <<".\n";
629    std::cerr << "\tDuchamp is currently unable to deal with pixel steps in the subsection.\n";
630    std::cerr << "\tThese have been ignored, and so the subection used is ";   
631    this->subsection = "[" + x + "," + y + "," + z + "]";  // rewrite subsection without any step sizes.
632    std::cerr << this->subsection << std::endl;
633  }
634
635}
636
637void Param::copyHeaderInfo(FitsHeader &head)
638{
639  /**
640   *  Param::copyHeaderInfo(FitsHeader &head)
641   * A function to copy across relevant header keywords from the
642   *  FitsHeader class to the Param class, as they are needed by
643   *  functions in the Param class.
644   */
645
646  this->blankKeyword  = head.getBlankKeyword();
647  this->bscaleKeyword = head.getBscaleKeyword();
648  this->bzeroKeyword  = head.getBzeroKeyword();
649  this->blankPixValue = this->blankKeyword * this->bscaleKeyword + this->bzeroKeyword;
650
651  this->numPixBeam    = head.getBeamSize();
652}
653
654bool Param::isBlank(float &value)
655{
656  /**
657   *  Param::isBlank(float)
658   *   Tests whether the value passed as the argument is BLANK or not.
659   *   If flagBlankPix is false, return false.
660   *   Otherwise, compare to the relevant FITS keywords, using integer comparison.
661   *   Return a bool.
662   */
663
664  return this->flagBlankPix &&
665    (this->blankKeyword == int((value-this->bzeroKeyword)/this->bscaleKeyword));
666}
667
668string Param::outputReconFile()
669{
670  /**
671   *  outputReconFile()
672   *
673   *   This function produces the required filename in which to save
674   *    the reconstructed array. If the input image is image.fits, then
675   *    the output will be eg. image.RECON-3-2-4-1.fits, where the numbers are
676   *    3=reconDim, 2=filterCode, 4=snrRecon, 1=minScale
677   */
678  string inputName = this->imageFile;
679  std::stringstream ss;
680  ss << inputName.substr(0,inputName.size()-5);  // remove the ".fits" on the end.
681  if(this->flagSubsection) ss<<".sub";
682  ss << ".RECON-" << this->reconDim
683     << "-"       << this->filterCode
684     << "-"       << this->snrRecon
685     << "-"       << this->scaleMin
686     << ".fits";
687  return ss.str();
688}
689
690string Param::outputResidFile()
691{
692  /**
693   *  outputResidFile()
694   *
695   *   This function produces the required filename in which to save
696   *    the reconstructed array. If the input image is image.fits, then
697   *    the output will be eg. image.RESID-3-2-4-1.fits, where the numbers are
698   *    3=reconDim, 2=filterCode, 4=snrRecon, 1=scaleMin
699   */
700  string inputName = this->imageFile;
701  std::stringstream ss;
702  ss << inputName.substr(0,inputName.size()-5);  // remove the ".fits" on the end.
703  if(this->flagSubsection) ss<<".sub";
704  ss << ".RESID-" << this->reconDim
705     << "-"       << this->filterCode
706     << "-"       << this->snrRecon
707     << "-"       << this->scaleMin
708     << ".fits";
709  return ss.str();
710}
Note: See TracBrowser for help on using the repository browser.