source: tags/release-1.0.2/src/param.cc @ 167

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

Introduced error and warning reporting functions, to normalise the format
of errors and warnings. Definitions of functions go in duchamp.cc.
Changed all code that reports errors/warnings to use these new functions.

Fixed a couple of bugs that affected the way 2D images were dealt with:
ReconSearch? now looks at how many dimensions there are in the data array
before choosing the dimension of the reconstruction, and the minChannels
test was improved for the case of minChannels=0.

Some minor additions made to the Guide as well.

File size: 27.3 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
324void Param::readParams(string paramfile)
325{
326
327  std::ifstream fin(paramfile.c_str());
328  string line;
329  string sval;
330  float fval;
331  int ival;
332  bool bval;
333  while( !std::getline(fin,line,'\n').eof()){
334
335    if(line[0]!='#'){
336      std::stringstream ss;
337      ss.str(line);
338      string arg;
339      ss >> arg;     
340      if(makelower(arg)=="imagefile"){       ss >> sval; this->imageFile = sval;}
341      if(makelower(arg)=="flagsubsection"){  ss >> bval; this->flagSubsection = bval; }
342      if(makelower(arg)=="subsection"){      ss >> sval; this->subsection = sval; }
343      if(makelower(arg)=="flagreconexists"){ ss >> bval; this->flagReconExists = bval; }
344      if(makelower(arg)=="reconfile"){       ss >> sval; this->reconFile = sval; }
345
346      if(makelower(arg)=="flaglog"){         ss >> bval; this->flagLog = bval; }
347      if(makelower(arg)=="logfile"){         ss >> sval; this->logFile = sval; }
348      if(makelower(arg)=="outfile"){         ss >> sval; this->outFile = sval; }
349      if(makelower(arg)=="spectrafile"){     ss >> sval; this->spectraFile = sval; }
350      if(makelower(arg)=="flagoutputrecon"){ ss >> bval; this->flagOutputRecon = bval; }
351      if(makelower(arg)=="flagoutputresid"){ ss >> bval; this->flagOutputResid = bval; }
352      if(makelower(arg)=="flagvot"){         ss >> bval; this->flagVOT = bval; }
353      if(makelower(arg)=="votfile"){         ss >> sval; this->votFile = sval; }
354      if(makelower(arg)=="flagkarma"){       ss >> bval; this->flagKarma = bval; }
355      if(makelower(arg)=="karmafile"){       ss >> sval; this->karmaFile = sval; }
356      if(makelower(arg)=="flagmaps"){        ss >> bval; this->flagMaps = bval; }
357      if(makelower(arg)=="detectionmap"){    ss >> sval; this->detectionMap = sval; }
358      if(makelower(arg)=="momentmap"){       ss >> sval; this->momentMap = sval; }
359
360      if(makelower(arg)=="flagnegative"){    ss >> bval; this->flagNegative = bval;}
361      if(makelower(arg)=="flagblankpix"){    ss >> bval; this->flagBlankPix = bval; }
362      if(makelower(arg)=="blankpixvalue"){   ss >> fval; this->blankPixValue = fval; }
363      if(makelower(arg)=="flagmw"){          ss >> bval; this->flagMW = bval; }
364      if(makelower(arg)=="maxmw"){           ss >> ival; this->maxMW = ival; }
365      if(makelower(arg)=="minmw"){           ss >> ival; this->minMW = ival; }
366
367      if(makelower(arg)=="flagbaseline"){    ss >> bval; this->flagBaseline = bval; }
368      if(makelower(arg)=="minpix"){          ss >> ival; this->minPix = ival; }
369      if(makelower(arg)=="flaggrowth"){      ss >> bval; this->flagGrowth = bval; }
370      if(makelower(arg)=="growthcut"){       ss >> fval; this->growthCut = fval; }
371
372      if(makelower(arg)=="flagfdr"){         ss >> bval; this->flagFDR = bval; }
373      if(makelower(arg)=="alphafdr"){        ss >> fval; this->alphaFDR = fval; }
374
375      if(makelower(arg)=="snrcut"){          ss >> fval; this->snrCut = fval; }
376
377      if(makelower(arg)=="flagatrous"){      ss >> bval; this->flagATrous = bval; }
378      if(makelower(arg)=="recondim"){        ss >> ival; this->reconDim = ival; }
379      if(makelower(arg)=="scalemin"){        ss >> ival; this->scaleMin = ival; }
380      if(makelower(arg)=="snrrecon"){        ss >> fval; this->snrRecon = fval; }
381      if(makelower(arg)=="filtercode"){      ss >> ival; this->filterCode = ival; }
382
383      if(makelower(arg)=="flagadjacent"){    ss >> bval; this->flagAdjacent = bval; }
384      if(makelower(arg)=="threshspatial"){   ss >> fval; this->threshSpatial = fval; }
385      if(makelower(arg)=="threshvelocity"){  ss >> fval; this->threshVelocity = fval; }
386      if(makelower(arg)=="minchannels"){     ss >> ival; this->minChannels = ival; }
387
388      if(makelower(arg)=="spectralmethod"){  ss >> sval; this->spectralMethod = makelower(sval); }
389      if(makelower(arg)=="spectralunits"){   ss >> sval; this->spectralUnits = makelower(sval); }
390      if(makelower(arg)=="drawborders"){     ss >> bval; this->borders = bval; }
391      if(makelower(arg)=="verbose"){         ss >> bval; this->verbose = bval; }
392    }
393  }
394}
395
396
397std::ostream& operator<< ( std::ostream& theStream, Param& par)
398{
399  // Only show the [blankPixValue] bit if we are using the parameter
400  // otherwise we have read it from the FITS header.
401  string blankParam = "";
402  if(par.getFlagUsingBlank()) blankParam = "[blankPixValue]";
403
404  // BUG -- can get error: `boolalpha' is not a member of type `ios' -- old compilers: gcc 2.95.3?
405//   theStream.setf(std::ios::boolalpha);
406  theStream.setf(std::ios::left);
407  theStream  <<"---- Parameters ----"<<endl;
408  theStream  << std::setfill('.');
409  if(par.getFlagSubsection())
410    theStream<<setw(38)<<"Image to be analysed"                 
411             <<setw(18)<<setiosflags(std::ios::right)  <<"[imageFile]"
412             <<"  =  " <<resetiosflags(std::ios::right)
413             <<(par.getImageFile()+par.getSubsection())   <<endl;
414  else
415    theStream<<setw(38)<<"Image to be analysed"                 
416             <<setw(18)<<setiosflags(std::ios::right)  <<"[imageFile]"
417             <<"  =  " <<resetiosflags(std::ios::right)<<par.getImageFile()      <<endl;
418  if(par.getFlagReconExists() && par.getFlagATrous()){
419    theStream<<setw(38)<<"Reconstructed array exists?"         
420             <<setw(18)<<setiosflags(std::ios::right)  <<"[reconExists]"
421             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagReconExists())<<endl;
422    theStream<<setw(38)<<"FITS file containing reconstruction" 
423             <<setw(18)<<setiosflags(std::ios::right)  <<"[reconFile]"
424             <<"  =  " <<resetiosflags(std::ios::right)<<par.getReconFile()      <<endl;
425  }
426  theStream  <<setw(38)<<"Intermediate Logfile"
427             <<setw(18)<<setiosflags(std::ios::right)  <<"[logFile]"
428             <<"  =  " <<resetiosflags(std::ios::right)<<par.getLogFile()        <<endl;
429  theStream  <<setw(38)<<"Final Results file"                   
430             <<setw(18)<<setiosflags(std::ios::right)  <<"[outFile]"
431             <<"  =  " <<resetiosflags(std::ios::right)<<par.getOutFile()        <<endl;
432  theStream  <<setw(38)<<"Spectrum file"                       
433             <<setw(18)<<setiosflags(std::ios::right)  <<"[spectraFile]"
434             <<"  =  " <<resetiosflags(std::ios::right)<<par.getSpectraFile()    <<endl;
435  if(par.getFlagVOT()){
436    theStream<<setw(38)<<"VOTable file"                         
437             <<setw(18)<<setiosflags(std::ios::right)  <<"[votFile]"
438             <<"  =  " <<resetiosflags(std::ios::right)<<par.getVOTFile()        <<endl;
439  }
440  if(par.getFlagKarma()){
441    theStream<<setw(38)<<"Karma annotation file"               
442             <<setw(18)<<setiosflags(std::ios::right)  <<"[karmaFile]"
443             <<"  =  " <<resetiosflags(std::ios::right)<<par.getKarmaFile()      <<endl;
444  }
445  if(par.getFlagMaps()){
446    theStream<<setw(38)<<"0th Moment Map"                       
447             <<setw(18)<<setiosflags(std::ios::right)  <<"[momentMap]"
448             <<"  =  " <<resetiosflags(std::ios::right)<<par.getMomentMap()      <<endl;
449    theStream<<setw(38)<<"Detection Map"                       
450             <<setw(18)<<setiosflags(std::ios::right)  <<"[detectionMap]"
451             <<"  =  " <<resetiosflags(std::ios::right)<<par.getDetectionMap()   <<endl;
452  }
453  if(par.getFlagATrous()){                             
454    theStream<<setw(38)<<"Saving reconstructed cube?"           
455             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagoutputrecon]"
456             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagOutputRecon())<<endl;
457    theStream<<setw(38)<<"Saving residuals from reconstruction?"
458             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagoutputresid]"
459             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagOutputResid())<<endl;
460  }                                                   
461  theStream  <<"------"<<endl;
462  theStream  <<setw(38)<<"Searching for Negative features?"     
463             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagNegative]"
464             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagNegative())   <<endl;
465  theStream  <<setw(38)<<"Fixing Blank Pixels?"                 
466             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagBlankPix]"
467             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagBlankPix())   <<endl;
468  if(par.getFlagBlankPix()){
469    theStream<<setw(38)<<"Blank Pixel Value"                   
470             <<setw(18)<<setiosflags(std::ios::right)  << blankParam
471             <<"  =  " <<resetiosflags(std::ios::right)<<par.getBlankPixVal()    <<endl;
472  }
473  theStream  <<setw(38)<<"Removing Milky Way channels?"         
474             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagMW]"
475             <<"  =  " <<resetiosflags(std::ios::right)<<par.getFlagMW()         <<endl;
476  if(par.getFlagMW()){
477    theStream<<setw(38)<<"Milky Way Channels"                   
478             <<setw(18)<<setiosflags(std::ios::right)  <<"[minMW - maxMW]"
479             <<"  =  " <<resetiosflags(std::ios::right)<<par.getMinMW()
480             <<"-" <<par.getMaxMW()          <<endl;
481  }
482  theStream  <<setw(38)<<"Beam Size (pixels)"                   
483             <<setw(18)<<setiosflags(std::ios::right)  <<""
484             <<"  =  " <<resetiosflags(std::ios::right)<<par.getBeamSize()       <<endl;
485  theStream  <<setw(38)<<"Removing baselines before search?"   
486             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagBaseline]"
487             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagBaseline())   <<endl;
488  theStream  <<setw(38)<<"Minimum # Pixels in a detection"     
489             <<setw(18)<<setiosflags(std::ios::right)  <<"[minPix]"
490             <<"  =  " <<resetiosflags(std::ios::right)<<par.getMinPix()         <<endl;
491  theStream  <<setw(38)<<"Minimum # Channels in a detection"   
492             <<setw(18)<<setiosflags(std::ios::right)  <<"[minChannels]"
493             <<"  =  " <<resetiosflags(std::ios::right)<<par.getMinChannels()    <<endl;
494  theStream  <<setw(38)<<"Growing objects after detection?"     
495             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagGrowth]"
496             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagGrowth())     <<endl;
497  if(par.getFlagGrowth()) {                           
498    theStream<<setw(38)<<"SNR Threshold for growth"             
499             <<setw(18)<<setiosflags(std::ios::right)  <<"[growthCut]"
500             <<"  =  " <<resetiosflags(std::ios::right)<<par.getGrowthCut()      <<endl;
501  }
502  theStream  <<setw(38)<<"Using A Trous reconstruction?"       
503             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagATrous]"
504             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagATrous())     <<endl;
505  if(par.getFlagATrous()){                             
506    theStream<<setw(38)<<"Number of dimensions in reconstruction"     
507             <<setw(18)<<setiosflags(std::ios::right)  <<"[reconDim]"
508             <<"  =  " <<resetiosflags(std::ios::right)<<par.getReconDim()       <<endl;
509    theStream<<setw(38)<<"Minimum scale in reconstruction"     
510             <<setw(18)<<setiosflags(std::ios::right)  <<"[scaleMin]"
511             <<"  =  " <<resetiosflags(std::ios::right)<<par.getMinScale()       <<endl;
512    theStream<<setw(38)<<"SNR Threshold within reconstruction" 
513             <<setw(18)<<setiosflags(std::ios::right)  <<"[snrRecon]"
514             <<"  =  " <<resetiosflags(std::ios::right)<<par.getAtrousCut()      <<endl;
515    theStream<<setw(38)<<"Filter being used for reconstruction"
516             <<setw(18)<<setiosflags(std::ios::right)  <<"[filterCode]"
517             <<"  =  " <<resetiosflags(std::ios::right)<<par.getFilterCode()
518             << " (" << par.getFilterName()  << ")" <<endl;
519  }                                                   
520  theStream  <<setw(38)<<"Using FDR analysis?"                 
521             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagFDR]"
522             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagFDR())        <<endl;
523  if(par.getFlagFDR()){                               
524    theStream<<setw(38)<<"Alpha value for FDR analysis"         
525             <<setw(18)<<setiosflags(std::ios::right)  <<"[alphaFDR]"
526             <<"  =  " <<resetiosflags(std::ios::right)<<par.getAlpha()          <<endl;
527  }                                                   
528  else {
529    theStream<<setw(38)<<"SNR Threshold"                       
530             <<setw(18)<<setiosflags(std::ios::right)  <<"[snrCut]"
531             <<"  =  " <<resetiosflags(std::ios::right)<<par.getCut()            <<endl;
532  }
533  theStream  <<setw(38)<<"Using Adjacent-pixel criterion?"     
534             <<setw(18)<<setiosflags(std::ios::right)  <<"[flagAdjacent]"
535             <<"  =  " <<resetiosflags(std::ios::right)<<stringize(par.getFlagAdjacent())   <<endl;
536  if(!par.getFlagAdjacent()){
537    theStream<<setw(38)<<"Max. spatial separation for merging" 
538             <<setw(18)<<setiosflags(std::ios::right)  <<"[threshSpatial]"
539             <<"  =  " <<resetiosflags(std::ios::right)<<par.getThreshS()        <<endl;
540  }
541  theStream  <<setw(38)<<"Max. velocity separation for merging"
542             <<setw(18)<<setiosflags(std::ios::right)  <<"[threshVelocity]"
543             <<"  =  " <<resetiosflags(std::ios::right)<<par.getThreshV()        <<endl;
544  theStream  <<setw(38)<<"Method of spectral plotting"         
545             <<setw(18)<<setiosflags(std::ios::right)  <<"[spectralMethod]"
546             <<"  =  " <<resetiosflags(std::ios::right)<<par.getSpectralMethod() <<endl;
547  theStream  <<"--------------------"<<endl;
548  theStream  << std::setfill(' ');
549  theStream.unsetf(std::ios::left);
550  //  theStream.unsetf(std::ios::boolalpha);
551}
552
553void Param::parseSubsection()
554{
555  /**
556   *  Param::parseSubsection()
557   *
558   *   Convert the Param::subsection string to a series of offset values
559   *    for each dimension.
560   *   This involves reading the individual substrings and converting to
561   *    integers, and storing in the {x,y,z}SubOffset parameters.
562   *   Steps in the subsection string are not dealt with -- a warning message
563   *    is written to the screen, and the step values are ignored.
564   */
565
566  std::stringstream ss;
567  ss.str(this->subsection);
568  bool removeStep = false;
569  string x,y,z;
570  getline(ss,x,'[');
571  getline(ss,x,',');
572  getline(ss,y,',');
573  getline(ss,z,']');
574  char *end;
575  if(x!="*") {
576    int x1,x2,dx;
577    int a = x.find(':');  // first occurence of ':' in x-subsection string
578    int b = x.find(':',a+1); // location of second ':' -- will be -1 if there is no second occurence.
579    x1 = atoi( x.substr(0,a).c_str() ); // minimum x in subsection
580    this->xSubOffset = x1 - 1;
581    if(b>0){ // there is a dx component
582      x2 = atoi( x.substr(a+1,b-a-1).c_str() ); // maximum x in subsection
583      dx = atoi( x.substr(b+1,x.size()).c_str() ); // delta x in subsection
584      x = x.substr(0,b); // rewrite x without the delta-x part.
585      removeStep = true;
586    }
587  }
588  if(y!="*") {
589    int y1,y2,dy;
590    int a = y.find(':');  // first occurence of ':' in y-subsection string
591    int b = y.find(':',a+1); // location of second ':' -- will be -1 if there is no second occurence.
592    y1 = atoi( y.substr(0,a).c_str() ); // minimum y in subsection
593    this->ySubOffset = y1 - 1;
594    if(b>0){ // there is a dy component
595      y2 = atoi( y.substr(a+1,b-a-1).c_str() ); // maximum y in subsection
596      dy = atoi( y.substr(b+1,y.size()).c_str() ); // delta y in subsection
597      y = y.substr(0,b); // rewrite y without the delta-y part.
598      removeStep = true;
599    }
600  }
601  if(z!="*") {
602    int z1,z2,dz;
603    int a = z.find(':');  // first occurence of ':' in z-subsection string
604    int b = z.find(':',a+1); // location of second ':' -- will be -1 if there is no second occurence.
605    z1 = atoi( z.substr(0,a).c_str() ); // minimum z in subsection
606    this->zSubOffset = z1 - 1;
607    if(b>0){ // there is a dz component
608      z2 = atoi( z.substr(a+1,b-a-1).c_str() ); // maximum z in subsection
609      dz = atoi( z.substr(b+1,z.size()).c_str() ); // delta z in subsection
610      z = z.substr(0,b); // rewrite z without the delta-z part.
611      removeStep = true;
612    }
613  }
614
615  if(removeStep){
616    std::cerr << "\a\tThe subsection given is " << this->subsection <<".\n";
617    std::cerr << "\tDuchamp is currently unable to deal with pixel steps in the subsection.\n";
618    std::cerr << "\tThese have been ignored, and so the subection used is ";   
619    this->subsection = "[" + x + "," + y + "," + z + "]";  // rewrite subsection without any step sizes.
620    std::cerr << this->subsection << std::endl;
621  }
622
623}
624
625void Param::copyHeaderInfo(FitsHeader &head)
626{
627  /**
628   *  Param::copyHeaderInfo(FitsHeader &head)
629   * A function to copy across relevant header keywords from the
630   *  FitsHeader class to the Param class, as they are needed by
631   *  functions in the Param class.
632   */
633
634  this->blankKeyword  = head.getBlankKeyword();
635  this->bscaleKeyword = head.getBscaleKeyword();
636  this->bzeroKeyword  = head.getBzeroKeyword();
637  this->blankPixValue = this->blankKeyword * this->bscaleKeyword + this->bzeroKeyword;
638
639  this->numPixBeam    = head.getBeamSize();
640}
641
642bool Param::isBlank(float &value)
643{
644  /**
645   *  Param::isBlank(float)
646   *   Tests whether the value passed as the argument is BLANK or not.
647   *   If flagBlankPix is false, return false.
648   *   Otherwise, compare to the relevant FITS keywords, using integer comparison.
649   *   Return a bool.
650   */
651
652  return this->flagBlankPix &&
653    (this->blankKeyword == int((value-this->bzeroKeyword)/this->bscaleKeyword));
654}
655
656string Param::outputReconFile()
657{
658  /**
659   *  outputReconFile()
660   *
661   *   This function produces the required filename in which to save
662   *    the reconstructed array. If the input image is image.fits, then
663   *    the output will be eg. image.RECON-3-2-4-1.fits, where the numbers are
664   *    3=reconDim, 2=filterCode, 4=snrRecon, 1=minScale
665   */
666  string inputName = this->imageFile;
667  std::stringstream ss;
668  ss << inputName.substr(0,inputName.size()-5);  // remove the ".fits" on the end.
669  if(this->flagSubsection) ss<<".sub";
670  ss << ".RECON-" << this->reconDim
671     << "-"       << this->filterCode
672     << "-"       << this->snrRecon
673     << "-"       << this->scaleMin
674     << ".fits";
675  return ss.str();
676}
677
678string Param::outputResidFile()
679{
680  /**
681   *  outputResidFile()
682   *
683   *   This function produces the required filename in which to save
684   *    the reconstructed array. If the input image is image.fits, then
685   *    the output will be eg. image.RESID-3-2-4-1.fits, where the numbers are
686   *    3=reconDim, 2=filterCode, 4=snrRecon, 1=scaleMin
687   */
688  string inputName = this->imageFile;
689  std::stringstream ss;
690  ss << inputName.substr(0,inputName.size()-5);  // remove the ".fits" on the end.
691  if(this->flagSubsection) ss<<".sub";
692  ss << ".RESID-" << this->reconDim
693     << "-"       << this->filterCode
694     << "-"       << this->snrRecon
695     << "-"       << this->scaleMin
696     << ".fits";
697  return ss.str();
698}
Note: See TracBrowser for help on using the repository browser.