source: branches/fitshead-branch/Cubes/detectionIO.cc @ 1441

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

Four major sets of changes and a couple of minor ones:

  • Changed name of saved recon/resid FITS file, so that it incorporates all reconstruction parameters.
  • Removed MW parameters from header file
  • Added hashed box to be drawn over MW range in spectral plots
  • Fixed bug that meant reon would be done in 1- or 2-d even if recon array has been read in.

Summary:
param.hh -- prototypes for FITS file name calculation functions
param.cc -- FITS file name calculation functions
Cubes/plots.hh -- drawMWRange function
ATrous/ReconSearch.cc -- tests to see if reconExists for 1- and 2-D recon
Cubes/cubes.cc -- work out enclosed flux correctly for flagNegative
Cubes/detectionIO.cc -- added reconDim line to VOTable output
Cubes/outputSpectra.cc -- added code to draw MW range
Cubes/readRecon.cc -- added call to FITS file name function, and removed

MW params and superfluous tests on atrous parameters

Cubes/saveImage.cc -- improved logical flow. added call to FITS file name func

removed MW keywords.

Detection/columns.cc -- added extra column to fluxes if negative.

File size: 12.7 KB
Line 
1#include <iostream>
2#include <sstream>
3#include <fstream>
4#include <iomanip>
5#include <string>
6#include <time.h>
7#include <Cubes/cubes.hh>
8#include <Detection/columns.hh>
9#include <Utils/utils.hh>
10 
11using std::endl;
12using std::setw;
13using std::setprecision;
14
15void Cube::outputDetectionsKarma(std::ostream &stream)
16{
17  /**
18   * outputDetectionsKarma
19   *  Prints to a stream (provided) the list of detected objects in the cube
20   *   in the format of an annotation file for the Karma suite of programs.
21   *  Annotation file draws a box enclosing the detection, and writes the ID number
22   *   of the detection to the right of the box.
23   */
24
25  stream << "# Duchamp Source Finder results for cube " << this->par.getImageFile() << endl;
26  stream << "COLOR RED" << endl;
27  stream << "COORD W" << endl;
28  for(int i=0;i<this->objectList.size();i++){
29    float radius = this->objectList[i].getRAWidth()/120.;
30    if(this->objectList[i].getDecWidth()/120.>radius)
31      radius = this->objectList[i].getDecWidth()/120.;
32    stream << "CIRCLE "
33           << this->objectList[i].getRA() << " "
34           << this->objectList[i].getDec() << " "
35           << radius << endl;
36    stream << "TEXT "
37           << this->objectList[i].getRA() << " "
38           << this->objectList[i].getDec() << " "
39           << this->objectList[i].getID() << endl;
40  }
41
42}
43
44void Cube::outputDetectionsVOTable(std::ostream &stream)
45{
46  /**
47   * outputDetectionsVOTable
48   *  Prints to a stream (provided) the list of detected objects in the cube
49   *   in a VOTable format.
50   *  Uses WCS information and assumes WCS parameters have been calculated for each
51   *   detected object.
52   *  If they have not (given by the isWCS() function), then those objects are not written...
53   */
54
55  // Set up Column definitions here
56  vector<Column::Col> localCol;
57  string posUCD[4];
58  localCol.push_back(this->fullColSet.vec[0]);  // objID
59  localCol.push_back(this->fullColSet.vec[1]);  // name
60  localCol.push_back(this->fullColSet.vec[5]);  // ra
61  if(makelower(localCol[2].getName())=="ra"){
62    posUCD[0] = "pos.eq.ra;meta.main";
63    posUCD[2] = "phys.angSize;pos.eq.ra";
64  }
65  else{
66    posUCD[0] = "pos.galactic.lat;meta.main";
67    posUCD[2] = "phys.angSize;pos.galactic.lat";
68  }
69  localCol.push_back(this->fullColSet.vec[6]);  // dec
70  if(makelower(localCol[2].getName())=="dec"){
71    posUCD[1] = "pos.eq.dec;meta.main";
72    posUCD[3] = "phys.angSize;pos.eq.dec";
73  }
74  else{
75    posUCD[1] = "pos.galactic.lon;meta.main";
76    posUCD[3] = "phys.angSize;pos.galactic.lon";
77  }
78  localCol.push_back(this->fullColSet.vec[8]);  // w_ra
79  localCol.push_back(this->fullColSet.vec[9]);  // w_dec
80  localCol.push_back(this->fullColSet.vec[7]);  // vel
81  localCol.push_back(this->fullColSet.vec[10]); // w_vel
82  localCol.push_back(this->fullColSet.vec[11]); // f_int
83  localCol.push_back(this->fullColSet.vec[12]); // f_peak
84  localCol.push_back(this->fullColSet.vec[20]); // flag
85
86  stream<<"<?xml version=\"1.0\"?>"<<endl;
87  stream<<"<VOTABLE version=\"1.1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""<<endl;
88  stream<<" xsi:noNamespaceSchemaLocation=\"http://www.ivoa.net/xml/VOTable/VOTable/v1.1\">"<<endl;
89
90  stream<<"  <COOSYS ID=\"J2000\" equinox=\"J2000.\" epoch=\"J2000.\" system=\"eq_FK5\"/>"<<endl;
91  stream<<"  <RESOURCE name=\"Duchamp Output\">"<<endl;
92  stream<<"    <TABLE name=\"Detections\">"<<endl;
93  stream<<"      <DESCRIPTION>Detected sources and parameters from running the Duchamp source finder.</DESCRIPTION>"<<endl;
94
95  // PARAM section -- parts that are not entry-specific ie. apply to whole dataset
96  string fname = this->pars().getImageFile();
97  if(this->pars().getFlagSubsection()) fname+=this->pars().getSubsection();
98  stream<<"      <PARAM name=\"FITS file\" datatype=\"char\" ucd=\"meta.file;meta.fits\" value=\"" << fname << "\"/>"<<endl;
99  if(this->pars().getFlagFDR())
100    stream<<"      <PARAM name=\"FDR Significance\" datatype=\"float\" ucd=\"stat.param\" value=\"" << this->pars().getAlpha() << "\">" << endl;
101  else
102    stream<<"      <PARAM name=\"Threshold\" datatype=\"float\" ucd=\"stat.snr\" value=\"" << this->pars().getCut() << "\">" << endl;
103  if(this->pars().getFlagATrous()){
104    stream<<"      <PARAM name=\"ATrous note\" datatype=\"char\" ucd=\"meta.note\" value=\"The a trous reconstruction method was used, with the following parameters.\">" << endl;
105    stream<<"      <PARAM name=\"ATrous Dimension\" datatype=\"int\" ucd=\"meta.code;stat\" value=\"" << this->pars().getReconDim() << "\">" << endl;
106    stream<<"      <PARAM name=\"ATrous Threshold\" datatype=\"float\" ucd=\"stat.snr\" value=\"" << this->pars().getAtrousCut() << "\">" << endl;
107    stream<<"      <PARAM name=\"ATrous Minimum Scale\" datatype=\"int\" ucd=\"stat.param\" value=\"" << this->pars().getMinScale() << "\">" << endl;
108    stream<<"      <PARAM name=\"ATrous Filter\" datatype=\"char\" ucd=\"meta.code;stat\" value=\"" << this->pars().getFilterName() << "\">" << endl;
109  }
110  // FIELD section -- names, titles and info for each column.
111  stream<<"      <FIELD name=\"ID\" ID=\"col01\" ucd=\"meta.id\" datatype=\"int\" width=\""<<localCol[0].getWidth()<<"\"/>"<<endl;
112  stream<<"      <FIELD name=\"Name\" ID=\"col02\" ucd=\"meta.id;meta.main\" datatype=\"char\" arraysize=\""<<localCol[1].getWidth()<<"\"/>"<<endl;
113  stream<<"      <FIELD name=\""<<localCol[2].getName()<<"\" ID=\"col03\" ucd=\""<<posUCD[0]<<"\" ref=\"J2000\" datatype=\"float\" width=\""<<localCol[2].getWidth()<<"\" precision=\""<<Column::posPrec<<"\" unit=\"[deg]\"/>"<<endl;
114  stream<<"      <FIELD name=\""<<localCol[3].getName()<<"\" ID=\"col04\" ucd=\""<<posUCD[1]<<"\" ref=\"J2000\" datatype=\"float\" width=\""<<localCol[3].getWidth()<<"\" precision=\""<<Column::posPrec<<"\" unit=\"[deg]\"/>"<<endl;
115  stream<<"      <FIELD name=\""<<localCol[4].getName()<<"\" ID=\"col05\" ucd=\""<<posUCD[2]<<"\" ref=\"J2000\" datatype=\"float\" width=\""<<localCol[4].getWidth()<<"\" precision=\""<<Column::wposPrec<<"\" unit=\""<<localCol[4].getUnit()<<"\"/>"<<endl;
116  stream<<"      <FIELD name=\""<<localCol[5].getName()<<"\" ID=\"col06\" ucd=\""<<posUCD[2]<<"\" ref=\"J2000\" datatype=\"float\" width=\""<<localCol[5].getWidth()<<"\" precision=\""<<Column::wposPrec<<"\" unit=\""<<localCol[5].getUnit()<<"\"/>"<<endl;
117  stream<<"      <FIELD name=\"Vel\" ID=\"col07\" ucd=\"phys.veloc;src.dopplerVeloc\" datatype=\"float\" width=\""<<localCol[6].getWidth()<<"\" precision=\""<<Column::velPrec<<"\" unit=\""<<localCol[6].getUnit()<<"\"/>"<<endl;
118  stream<<"      <FIELD name=\"w_Vel\" ID=\"col08\" ucd=\"phys.veloc;src.dopplerVeloc;spect.line.width\" datatype=\"float\" width=\""<<localCol[7].getWidth()<<"\" precision=\""<<Column::velPrec<<"\" unit=\""<<localCol[7].getUnit()<<"\"/>"<<endl;
119  stream<<"      <FIELD name=\"Integrated_Flux\" ID=\"col09\" ucd=\"phot.flux;spect.line.intensity\" datatype=\"float\" width=\""<<localCol[8].getWidth()<<"\" precision=\""<<Column::fluxPrec<<"\" unit=\""<<localCol[8].getUnit()<<"\"/>"<<endl;
120  stream<<"      <FIELD name=\"Peak_Flux\" ID=\"col10\" ucd=\"phot.flux;spect.line.intensity\" datatype=\"float\" width=\""<<localCol[9].getWidth()<<"\" precision=\""<<Column::fluxPrec<<"\" unit=\""<<localCol[9].getUnit()<<"\"/>"<<endl;
121  stream<<"      <FIELD name=\"Flag\" ID=\"col11\" ucd=\"meta.code.qual\" datatype=\"char\" arraysize=\"3\"/>"<<endl;
122
123
124  stream<<"      <DATA>"<<endl
125        <<"        <TABLEDATA>"<<endl;
126
127  stream.setf(std::ios::fixed); 
128  for(int i=0;i<this->objectList.size();i++){
129    if(this->objectList[i].isWCS()){
130      stream<<"        <TR>"<<endl;
131      stream<<"          <TD>"<<setw(localCol[0].getWidth())<<i+1<<"</TD>";
132      stream<<"<TD>" << setw(localCol[1].getWidth()) << this->objectList[i].getName()       <<"</TD>";
133      stream<<setprecision(Column::posPrec);                                       
134      stream<<"<TD>" << setw(localCol[2].getWidth()) << this->objectList[i].getRA()         <<"</TD>";
135      stream<<"<TD>" << setw(localCol[3].getWidth()) << this->objectList[i].getDec()        <<"</TD>";
136      stream<<setprecision(Column::wposPrec);                                       
137      stream<<"<TD>" << setw(localCol[4].getWidth()) << this->objectList[i].getRAWidth()    <<"</TD>";
138      stream<<"<TD>" << setw(localCol[5].getWidth()) << this->objectList[i].getDecWidth()   <<"</TD>";
139      stream<<setprecision(Column::velPrec);                                       
140      stream<<"<TD>" << setw(localCol[6].getWidth()) << this->objectList[i].getVel()        <<"</TD>";
141      stream<<"<TD>" << setw(localCol[7].getWidth()) << this->objectList[i].getVelWidth()   <<"</TD>";
142      stream<<setprecision(Column::fluxPrec);
143      stream<<"<TD>" << setw(localCol[8].getWidth()) << this->objectList[i].getIntegFlux()  <<"</TD>";
144      stream<<"<TD>" << setw(localCol[9].getWidth()) << this->objectList[i].getPeakFlux()   <<"</TD>";
145      stream<<"<TD>" << setw(localCol[10].getWidth())<< this->objectList[i].getFlagText()   <<"</TD>";
146     
147      stream<<endl;
148      stream<<"        </TR>"<<endl;
149    }
150  }
151  stream<<"        </TABLEDATA>"<<endl;
152  stream<<"      </DATA>"<<endl;
153  stream<<"    </TABLE>"<<endl;
154  stream<<"  </RESOURCE>"<<endl;
155  stream<<"</VOTABLE>"<<endl;
156  resetiosflags(std::ios::fixed);
157 
158}
159
160
161void Cube::outputDetectionList()
162{
163  /**
164   * outputDetectionList
165   *  A front-end to writing the full list of detected objects to a results
166   *   file and to cout.
167   *  Uses outputDetectionTextWCS for each objects.
168   *  Leaves the testing of whether the WCS parameters for each object
169   *   have been calculated to outputDetectionTextWCS.
170   */
171
172  int count=0;
173  int flag;
174  std::ofstream output(this->par.getOutFile().c_str());
175  output<<"Results of the Duchamp source finder: ";
176  time_t now = time(NULL);
177  output << asctime( localtime(&now) );
178  this->showParam(output);
179  output<<"Total number of detections = "<<this->objectList.size()<<endl;
180  output<<"--------------------"<<endl;
181  this->setupColumns();
182  outputDetectionTextWCSHeader(output,this->fullColSet);
183  outputDetectionTextWCSHeader(std::cout,this->fullColSet);
184  for(int i=0;i<this->objectList.size();i++){
185    this->objectList[i].outputDetectionTextWCS(output,this->fullColSet);
186    this->objectList[i].outputDetectionTextWCS(std::cout,this->fullColSet);
187  }
188}
189
190void Cube::logDetectionList()
191{
192  /**
193   * logDetectionList
194   *  A front-end to writing a list of detected objects to the log file.
195   *  Does not assume WCS, so uses outputDetectionText.
196   *  Designed to be used by searching routines before returning their final list.
197   */
198
199  std::ofstream fout(this->par.getLogFile().c_str(),std::ios::app);
200  this->setupColumns();
201  outputDetectionTextHeader(fout,this->logColSet);
202  long pos;
203  bool baselineFlag = this->par.getFlagBaseline();
204  for(int objCtr=0;objCtr<this->objectList.size();objCtr++){
205    Detection *obj = new Detection;
206    *obj = objectList[objCtr];
207    if(this->par.getFlagCubeTrimmed()){
208      for(int pix=0;pix<obj->getSize();pix++){
209        // Need to correct the pixels first, as this hasn't been done yet.
210        // Corrections needed for positions (to account for trimmed region)
211        //  and for the baseline removal, if it has happened.
212        // Don't want to keep these changes, so just do it on a dummy variable.
213        pos = obj->getX(pix) + obj->getY(pix)*this->axisDim[0]
214          + obj->getZ(pix)*this->axisDim[0]*this->axisDim[1];
215        obj->setX(pix, obj->getX(pix) + this->par.getBorderLeft() );
216        obj->setY(pix, obj->getY(pix) + this->par.getBorderBottom() );
217        if(baselineFlag) obj->setF(pix, obj->getF(pix) + this->baseline[pos]);   // add in baseline
218      }
219      obj->calcParams();
220    }
221    obj->outputDetectionText(fout,logColSet,objCtr+1);
222    delete obj;
223  }
224  fout.close();
225}
226
227void Cube::logDetection(Detection obj, int counter)
228{
229  /**
230   * logDetection
231   *  A front-end to writing a detected object to the log file.
232   *  Does not assume WCS, so uses outputDetectionText.
233   *  obj is passed by value, as we want to potentially change positions etc, but not for
234   *  object in the calling function.
235   *  Corrects for changes to positions of pixels and removal of baselines.
236   *  Designed to be used by searching routines before returning their final list.
237   */
238
239  std::ofstream fout(this->par.getLogFile().c_str(),std::ios::app);
240  bool baselineFlag = this->par.getFlagBaseline();
241  if(this->par.getFlagCubeTrimmed()){
242    for(int pix=0;pix<obj.getSize();pix++){
243      // Need to correct the pixels first, as this hasn't been done yet.
244      // Corrections needed for positions (to account for trimmed region)
245      //  and for the baseline removal, if it has happened.
246      // Don't want to keep these changes, so just do it on a dummy variable.
247      long pos = obj.getX(pix) + obj.getY(pix)*this->axisDim[0]
248        + obj.getZ(pix)*this->axisDim[0]*this->axisDim[1];
249      obj.setX(pix, obj.getX(pix) + this->par.getBorderLeft() );
250      obj.setY(pix, obj.getY(pix) + this->par.getBorderBottom() );
251      if(baselineFlag) obj.setF(pix, obj.getF(pix) + this->baseline[pos]);   // add in baseline
252    }
253    obj.calcParams();
254  }
255  obj.outputDetectionText(fout,this->logColSet,counter);
256  fout.close();
257}
Note: See TracBrowser for help on using the repository browser.