source: tags/release-1.1.7/src/Cubes/VOTable.cc @ 533

Last change on this file since 533 was 528, checked in by MatthewWhiting, 15 years ago

Changing the documentation comments to match the askapsoft style. Also have split ChanMap? and Object3D into separate files.

File size: 15.2 KB
Line 
1// -----------------------------------------------------------------------
2// VOTable.cc: Output of the detected objects to a VOTable
3// -----------------------------------------------------------------------
4// Copyright (C) 2006, Matthew Whiting, ATNF
5//
6// This program is free software; you can redistribute it and/or modify it
7// under the terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 2 of the License, or (at your
9// option) any later version.
10//
11// Duchamp is distributed in the hope that it will be useful, but WITHOUT
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14// for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with Duchamp; if not, write to the Free Software Foundation,
18// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
19//
20// Correspondence concerning Duchamp may be directed to:
21//    Internet email: Matthew.Whiting [at] atnf.csiro.au
22//    Postal address: Dr. Matthew Whiting
23//                    Australia Telescope National Facility, CSIRO
24//                    PO Box 76
25//                    Epping NSW 1710
26//                    AUSTRALIA
27// -----------------------------------------------------------------------
28
29#include <iostream>
30#include <sstream>
31#include <fstream>
32#include <iomanip>
33#include <string>
34#include <vector>
35#include <time.h>
36#include <duchamp/Cubes/VOTable.hh>
37#include <duchamp/param.hh>
38#include <duchamp/fitsHeader.hh>
39#include <duchamp/Cubes/cubes.hh>
40#include <duchamp/Detection/detection.hh>
41#include <duchamp/Detection/columns.hh>
42 
43namespace duchamp
44{
45
46  using namespace Column;
47  std::string fixUnitsVOT(std::string oldstring)
48  {
49    ///  @details
50    /// Fix a string containing units to make it acceptable for a VOTable.
51    ///
52    /// This function makes the provided units string acceptable
53    /// according to the standard found at
54    /// http://vizier.u-strasbg.fr/doc/catstd-3.2.htx
55    /// This should then be able to convert the units used in the text
56    /// table to units suitable for putting in a VOTable.
57    ///
58    /// Specifically, it removes any square brackets [] from the
59    /// start/end of the string, and replaces blank spaces (representing
60    /// multiplication) with a '.' (full stop).
61    ///
62    /// \param oldstring Input unit string to be fixed
63    /// \return String with fixed units
64
65    std::string newstring;
66    for(int i=0;i<oldstring.size();i++){
67      if((oldstring[i]!='[')&&(oldstring[i]!=']')){
68        if(oldstring[i]==' ') newstring += '.';
69        else newstring += oldstring[i];
70      }
71    }
72    return newstring; 
73  }
74 
75
76  void VOField::define(std::string i, std::string n, std::string U, std::string u, std::string d, std::string r, int w, int p)
77  {
78    /// @details
79    /// A basic definition function, defining each parameter individually.
80    /// \param i The ID parameter
81    /// \param n The name parameter
82    /// \param U The UCD
83    /// \param u The units (fixed by fixUnits())
84    /// \param d The datatype
85    /// \param r The ref
86    /// \param w The width
87    /// \param p The precision
88
89    this->ID = i;
90    this->name = n;
91    this->UCD = U;
92    this->unit = fixUnitsVOT(u);
93    this->datatype = d;
94    this->ref = r;
95    this->width = w;
96    this->precision = p;
97  }
98
99  void VOField::define(Column::Col column, std::string i, std::string U, std::string d, std::string r)
100  {
101    /// @details
102    /// Another definition function, using the information in a Column::Col object for some parameters.
103    /// \param column A Column::Col object, used for name, unit, width & precision
104    /// \param i The ID parameter
105    /// \param U The UCD
106    /// \param d The datatype
107    /// \param r The ref
108
109    this->ID = i;
110    this->name = column.getName();
111    this->UCD = U;
112    this->unit = fixUnitsVOT(column.getUnits());
113    this->datatype = d;
114    this->ref = r;
115    this->width = column.getWidth();
116    this->precision = column.getPrecision();
117  }
118
119  void VOField::define(Column::Col column)
120  {
121    /// @details
122    /// A more useful definition function, using the Column::COLNAME
123    /// key to specify particular values for each of the parameters for
124    /// different columns.
125    /// \param column A Column::Col object of a particular type. The
126    /// column.getType() function is used to decide which call to
127    /// VOField::define(Column::Col column, std::string i, std::string
128    /// U, std::string d, std::string r) to use
129
130    switch(column.getType())
131      {
132      case NUM:
133        this->define(column,"col01","meta.id","int","");
134        break;
135      case NAME:
136        this->define(column,"col02","meta.id;meta.main","char","");
137        break;
138      case RAJD:
139        this->define(column,"col03","","float","J2000");
140        break;
141      case DECJD:
142        this->define(column,"col04","","float","J2000");
143        break;
144      case VEL:
145        this->define(column,"col05","phys.veloc;src.dopplerVeloc","float","");
146        break;
147      case WRA:
148        this->define(column,"col06","","float","J2000");
149        break;
150      case WDEC:
151        this->define(column,"col07","","float","J2000");
152        break;
153      case W50:
154        this->define(column,"col08","phys.veloc;src.dopplerVeloc;spect.line.width","float","");
155        break;
156      case W20:
157        this->define(column,"col09","phys.veloc;src.dopplerVeloc;spect.line.width","float","");
158        break;
159      case WVEL:
160        this->define(column,"col10","phys.veloc;src.dopplerVeloc;spect.line.width","float","");
161        break;
162      case FINT:
163        this->define(column,"col11","phot.flux;spect.line.intensity","float","");
164        this->name = "Integrated_Flux";
165        break;
166      case FTOT:
167        this->define(column,"col11","phot.flux;spect.line.intensity","float","");
168        this->name = "Total_Flux";
169        break;
170      case FPEAK:
171        this->define(column,"col12","phot.flux;spect.line.intensity","float","");
172        this->name = "Peak_Flux";
173        break;
174      case SNRPEAK:
175        this->define(column,"col13","phot.flux;stat.snr","float","");
176        break;
177      case FLAG:
178        this->define(column,"col14","meta.code.qual","char","");
179        break;
180      case XAV:
181        this->define(column,"col15","pos.cartesian.x","float","");
182        break;
183      case YAV:
184        this->define(column,"col16","pos.cartesian.y","float","");
185        break;
186      case ZAV:
187        this->define(column,"col17","pos.cartesian.z","float","");
188        break;
189      case XCENT:
190        this->define(column,"col18","pos.cartesian.x","float","");
191        this->name = "X_Centroid";
192        break;
193      case YCENT:
194        this->define(column,"col19","pos.cartesian.y","float","");
195        this->name = "Y_Centroid";
196        break;
197      case ZCENT:
198        this->define(column,"col20","pos.cartesian.z","float","");
199        this->name = "Z_Centroid";
200        break;
201      case XPEAK:
202        this->define(column,"col21","pos.cartesian.x","int","");
203        break;
204      case YPEAK:
205        this->define(column,"col22","pos.cartesian.y","int","");
206        break;
207      case ZPEAK:
208        this->define(column,"col23","pos.cartesian.z","int","");
209        break;
210      default:
211        break;
212      };
213  }
214
215  void VOField::printField(std::ostream &stream)
216  {
217    /// @details
218    /// Print the Field entry with appropriate formatting.
219    /// \param stream The output stream to send the text to.
220
221    stream << "<FIELD name=\"" <<this->name
222           << "\" ID=\"" << this->ID
223           << "\" ucd=\"" << this->UCD;
224    if(this->ref!="") stream << "\" ref=\"" << this->ref;
225    stream << "\" datatype=\"" << this->datatype;
226    stream << "\" unit=\"" << this->unit;
227    if(datatype=="char")
228      stream << "\" arraysize=\"" << this->width;
229    else{
230      stream << "\" width=\"" << this->width;
231      if(datatype=="float" || datatype=="double")
232        stream << "\" precision=\"" << this->precision;
233    }
234    stream << "\"/>\n";
235
236  }
237
238
239
240  //------------------------------------------------
241
242
243  template <class T> void VOParam::define(std::string n, std::string U, std::string d, T v, int w, std::string u)
244  {
245    /// @details
246    /// A basic definition function, defining each parameter
247    /// individually. The value (v) is written to a stringstream, and
248    /// from there stored as a string.
249    /// \param n The name
250    /// \param U The UCD
251    /// \param d The datatype
252    /// \param v The value
253    /// \param w The width
254    /// \param u The units
255
256    this->name = n;
257    this->UCD = U;
258    this->datatype = d;
259    this->width = w;
260    std::stringstream ss;
261    ss << v;
262    this->value = ss.str();
263    this->units = u;
264  }
265  template void VOParam::define<int>(std::string n, std::string U, std::string d, int v, int w, std::string u);
266  template void VOParam::define<long>(std::string n, std::string U, std::string d, long v, int w, std::string u);
267  template void VOParam::define<float>(std::string n, std::string U, std::string d, float v, int w, std::string u);
268  template void VOParam::define<double>(std::string n, std::string U, std::string d, double v, int w, std::string u);
269  template void VOParam::define<std::string>(std::string n, std::string U, std::string d, std::string v, int w, std::string u);
270
271  void VOParam::printParam(std::ostream &stream)
272  {
273    /// @details
274    /// Print the Param entry with appropriate formatting.
275    /// \param stream The output stream to send the text to.
276
277    stream << "<PARAM name=\"" <<this->name
278           << "\" ucd=\"" << this->UCD
279           << "\" datatype=\"" << this->datatype;
280    if(this->units!="")
281      stream << "\" units=\"" << this->units;
282    if(this->width!=0){
283      if(datatype=="char")
284        stream << "\" arraysize=\"" << this->width;
285      else
286        stream << "\" width=\"" << this->width;
287    }
288    stream << "\" value=\"" << this->value
289           << "\"/>\n";
290  }
291
292  //------------------------------------------------
293
294
295 
296  void Cube::outputDetectionsVOTable(std::ostream &stream)
297  {
298    /// @details
299    ///  Prints to a stream (provided) the list of detected objects in the cube
300    ///   in a VOTable format.
301    ///  Uses WCS information and assumes WCS parameters have been calculated for each
302    ///   detected object.
303    /// \param stream The output stream to send the text to.
304   
305    stream<<"<?xml version=\"1.0\"?>\n";
306    stream<<"<VOTABLE version=\"1.1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
307    stream<<" xsi:noNamespaceSchemaLocation=\"http://www.ivoa.net/xml/VOTable/VOTable/v1.1\">\n";
308
309    stream<<"  <COOSYS ID=\"J2000\" equinox=\"J2000.\" epoch=\"J2000.\" system=\"eq_FK5\"/>\n";
310    stream<<"  <RESOURCE name=\"Duchamp Output\">\n";
311    stream<<"    <TABLE name=\"Detections\">\n";
312    stream<<"      <DESCRIPTION>Detected sources and parameters from running the Duchamp source finder.</DESCRIPTION>\n";
313
314    // PARAM section -- parts that are not entry-specific ie. apply to whole dataset
315    std::vector<VOParam> paramList;
316    std::vector<VOParam>::iterator param;
317    VOParam singleParam;
318
319    std::string fname = this->par.getImageFile();
320    if(this->par.getFlagSubsection()) fname+=this->par.getSubsection();
321   
322    singleParam.define("FITS file","meta.file;meta.fits","char",fname,fname.size(),"");
323    paramList.push_back(singleParam);
324    if(this->par.getFlagFDR())
325      singleParam.define("FDR Significance","stat.param","float",this->par.getAlpha(),0,"");
326    else
327      singleParam.define("Threshold (SNR)","stat.snr","float",this->par.getCut(),0,"");
328    paramList.push_back(singleParam);
329    singleParam.define("Flux Threshold","phot.flux;stat.min","float",this->Stats.getThreshold(),0,this->head.getFluxUnits());
330    paramList.push_back(singleParam);
331   
332    if(this->par.getFlagATrous()){
333      std::string note = "The a trous reconstruction method was used, with the following parameters.";
334      singleParam.define("ATrous note","meta.note","char",note,note.size(),"");
335      paramList.push_back(singleParam);
336      singleParam.define("ATrous Dimension","meta.code;stat","int",this->par.getReconDim(),0,"");
337      paramList.push_back(singleParam);
338      singleParam.define("ATrous Threshold","stat.snr","float",this->par.getAtrousCut(),0,"");
339      paramList.push_back(singleParam);
340      singleParam.define("ATrous Minimum Scale","stat.param","int",this->par.getMinScale(),0,"");
341      paramList.push_back(singleParam);
342      singleParam.define("ATrous Filter","meta.code;stat","char",this->par.getFilterName(),this->par.getFilterName().size(),"");
343      paramList.push_back(singleParam);
344    }
345    if(this->par.getFlagSmooth()){
346      if(this->par.getSmoothType()=="spectral"){
347        std::string note = "The cube was smoothed spectrally with a Hanning filter, with the following parameters.";
348        singleParam.define("Smoothing note","meta.note","char",note,note.size(),"");
349        paramList.push_back(singleParam);
350        singleParam.define("Hanning filter width","meta.code;stat","int",this->par.getHanningWidth(),0,"");
351        paramList.push_back(singleParam);
352      }
353      else if(this->par.getSmoothType()=="spatial"){
354        std::string note = "The cube was smoothed spatially with a Gaussian kernel, with the following parameters.";
355        singleParam.define("Smoothing note","meta.note","char",note,note.size(),"");
356        paramList.push_back(singleParam);
357        singleParam.define("Gaussian kernel major-axis FWHM","meta.code;stat","int",this->par.getKernMaj(),0,"");
358        paramList.push_back(singleParam);
359        singleParam.define("Gaussian kernel minor-axis FWHM","meta.code;stat","int",this->par.getKernMin(),0,"");
360        paramList.push_back(singleParam);
361        singleParam.define("Gaussian kernel position angle","meta.code;stat","int",this->par.getKernPA(),0,"");
362        paramList.push_back(singleParam);
363      }   
364    }
365
366    for(param=paramList.begin();param<paramList.end();param++){
367      stream << "      ";
368      param->printParam(stream);
369    }   
370
371
372    if(this->fullCols.size()==0) this->setupColumns();
373    // in case cols haven't been set -- need the column names
374
375    std::string posUCD[4];
376    if(makelower(this->fullCols[Column::RAJD].getName())=="ra"){
377      posUCD[0] = "pos.eq.ra;meta.main";
378      posUCD[2] = "phys.angSize;pos.eq.ra";
379    }
380    else{
381      posUCD[0] = "pos.galactic.lat;meta.main";
382      posUCD[2] = "phys.angSize;pos.galactic.lat";
383    }
384    if(makelower(this->fullCols[DECJD].getName())=="dec"){
385      posUCD[1] = "pos.eq.dec;meta.main";
386      posUCD[3] = "phys.angSize;pos.eq.dec";
387    }
388    else{
389      posUCD[1] = "pos.galactic.lon;meta.main";
390      posUCD[3] = "phys.angSize;pos.galactic.lon";
391    }
392
393    std::vector<Column::Col>::iterator col;
394    for(col=this->fullCols.begin();col<this->fullCols.end();col++){
395
396      if(col->doCol("votable",this->head.isSpecOK())){
397        VOField field;
398        field.define(*col);
399        if(col->getType()==RAJD)  field.setUCD(posUCD[0]);
400        if(col->getType()==WRA)   field.setUCD(posUCD[1]);
401        if(col->getType()==DECJD) field.setUCD(posUCD[2]);
402        if(col->getType()==WDEC)  field.setUCD(posUCD[3]);     
403        stream << "      ";
404        field.printField(stream);
405      }
406
407    }
408
409    stream<<"      <DATA>\n"
410          <<"        <TABLEDATA>\n";
411
412    stream.setf(std::ios::fixed); 
413
414    std::vector<Detection>::iterator obj;
415    for(obj=this->objectList->begin();obj<this->objectList->end();obj++){
416
417      stream<<"        <TR>\n";
418      stream<<"          ";
419      std::vector<Column::Col>::iterator col;
420      for(col=this->fullCols.begin();col<this->fullCols.end();col++){
421        if(col->doCol("votable",this->head.isSpecOK())){
422          stream<<"<TD>";
423          obj->printTableEntry(stream, *col);
424          stream<<"</TD>";
425        }
426      }
427      stream<<"\n";
428      stream<<"        </TR>\n";
429
430    }
431
432    stream<<"        </TABLEDATA>\n";
433    stream<<"      </DATA>\n";
434    stream<<"    </TABLE>\n";
435    stream<<"  </RESOURCE>\n";
436    stream<<"</VOTABLE>\n";
437    resetiosflags(std::ios::fixed);
438 
439  }
440
441
442
443
444}
Note: See TracBrowser for help on using the repository browser.