source: trunk/src/Cubes/VOTable.cc @ 440

Last change on this file since 440 was 440, checked in by MatthewWhiting, 16 years ago

Finished the meddling with the output. Now using the new functions to write to the tables, and have moved and revamped the VOTable functions -- they now respond to the precision options.

File size: 12.3 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    /**
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
63    std::string newstring;
64    for(int i=0;i<oldstring.size();i++){
65      if((oldstring[i]!='[')&&(oldstring[i]!=']')){
66        if(oldstring[i]==' ') newstring += '.';
67        else newstring += oldstring[i];
68      }
69    }
70    return newstring; 
71  }
72 
73
74  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)
75  {
76    this->ID = i;
77    this->name = n;
78    this->UCD = U;
79    this->unit = fixUnitsVOT(u);
80    this->datatype = d;
81    this->ref = r;
82    this->width = w;
83    this->precision = p;
84  }
85
86  void VOField::define(Column::Col column, std::string i, std::string U, std::string d, std::string r)
87  {
88    this->ID = i;
89    this->name = column.getName();
90    this->UCD = U;
91    this->unit = fixUnitsVOT(column.getUnits());
92    this->datatype = d;
93    this->ref = r;
94    this->width = column.getWidth();
95    this->precision = column.getPrecision();
96  }
97
98  void VOField::define(Column::Col column)
99  {
100    switch(column.getType())
101      {
102      case NUM:
103        this->define(column,"col01","meta.id","int","");
104        break;
105      case NAME:
106        this->define(column,"col02","meta.id;meta.main","char","");
107        break;
108      case RAJD:
109        this->define(column,"col03","","float","J2000");
110        break;
111      case DECJD:
112        this->define(column,"col04","","float","J2000");
113        break;
114      case VEL:
115        this->define(column,"col05","phys.veloc;src.dopplerVeloc","float","");
116        break;
117      case WRA:
118        this->define(column,"col06","","float","J2000");
119        break;
120      case WDEC:
121        this->define(column,"col07","","float","J2000");
122        break;
123      case WVEL:
124        this->define(column,"col08","phys.veloc;src.dopplerVeloc;spect.line.width","float","");
125        break;
126      case FINT:
127        this->define(column,"col09","phot.flux;spect.line.intensity","float","");
128        this->name = "Integrated_Flux";
129        break;
130      case FTOT:
131        this->define(column,"col09","phot.flux;spect.line.intensity","float","");
132        this->name = "Total_Flux";
133        break;
134      case FPEAK:
135        this->define(column,"col10","phot.flux;spect.line.intensity","float","");
136        this->name = "Peak_Flux";
137        break;
138      case SNRPEAK:
139        this->define(column,"col11","phot.flux;stat.snr","float","");
140        break;
141      case FLAG:
142        this->define(column,"col12","meta.code.qual","char","");
143        break;
144      case XAV:
145        this->define(column,"col13","pos.cartesian.x","float","");
146        break;
147      case YAV:
148        this->define(column,"col14","pos.cartesian.y","float","");
149        break;
150      case ZAV:
151        this->define(column,"col15","pos.cartesian.z","float","");
152        break;
153      case XCENT:
154        this->define(column,"col16","pos.cartesian.x","float","");
155        this->name = "X_Centroid";
156        break;
157      case YCENT:
158        this->define(column,"col17","pos.cartesian.y","float","");
159        this->name = "Y_Centroid";
160        break;
161      case ZCENT:
162        this->define(column,"col18","pos.cartesian.z","float","");
163        this->name = "Z_Centroid";
164        break;
165      case XPEAK:
166        this->define(column,"col19","pos.cartesian.x","int","");
167        break;
168      case YPEAK:
169        this->define(column,"col20","pos.cartesian.y","int","");
170        break;
171      case ZPEAK:
172        this->define(column,"col21","pos.cartesian.z","int","");
173        break;
174      default:
175        break;
176      };
177  }
178
179  void VOField::printField(std::ostream &stream)
180  {
181    stream << "<FIELD name=\"" <<this->name
182           << "\" ID=\"" << this->ID
183           << "\" ucd=\"" << this->UCD;
184    if(this->ref!="") stream << "\" ref=\"" << this->ref;
185    stream << "\" datatype=\"" << this->datatype;
186    stream << "\" unit=\"" << this->unit;
187    if(datatype=="char")
188      stream << "\" arraysize=\"" << this->width;
189    else{
190      stream << "\" width=\"" << this->width;
191      if(datatype=="float" || datatype=="double")
192        stream << "\" precision=\"" << this->precision;
193    }
194    stream << "\"/>\n";
195
196  }
197
198
199
200  //------------------------------------------------
201
202
203  template <class T> void VOParam::define(std::string n, std::string U, std::string d, T v, int w)
204  {
205    this->name = n;
206    this->UCD = U;
207    this->datatype = d;
208    this->width = w;
209    std::stringstream ss;
210    ss << v;
211    this->value = ss.str();
212  }
213  template void VOParam::define<int>(std::string n, std::string U, std::string d, int v, int w);
214  template void VOParam::define<long>(std::string n, std::string U, std::string d, long v, int w);
215  template void VOParam::define<float>(std::string n, std::string U, std::string d, float v, int w);
216  template void VOParam::define<double>(std::string n, std::string U, std::string d, double v, int w);
217  template void VOParam::define<std::string>(std::string n, std::string U, std::string d, std::string v, int w);
218
219  void VOParam::printParam(std::ostream &stream)
220  {
221    stream << "<PARAM name=\"" <<this->name
222           << "\" ucd=\"" << this->UCD
223           << "\" datatype=\"" << this->datatype;
224    if(this->width!=0){
225      if(datatype=="char")
226        stream << "\" arraysize=\"" << this->width;
227      else
228        stream << "\" width=\"" << this->width;
229    }
230    stream << "\" value=\"" << this->value
231           << "\"/>\n";
232  }
233
234  //------------------------------------------------
235
236
237 
238  void Cube::outputDetectionsVOTable(std::ostream &stream)
239  {
240
241    stream<<"<?xml version=\"1.0\"?>\n";
242    stream<<"<VOTABLE version=\"1.1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
243    stream<<" xsi:noNamespaceSchemaLocation=\"http://www.ivoa.net/xml/VOTable/VOTable/v1.1\">\n";
244
245    stream<<"  <COOSYS ID=\"J2000\" equinox=\"J2000.\" epoch=\"J2000.\" system=\"eq_FK5\"/>\n";
246    stream<<"  <RESOURCE name=\"Duchamp Output\">\n";
247    stream<<"    <TABLE name=\"Detections\">\n";
248    stream<<"      <DESCRIPTION>Detected sources and parameters from running the Duchamp source finder.</DESCRIPTION>\n";
249
250    // PARAM section -- parts that are not entry-specific ie. apply to whole dataset
251    std::vector<VOParam> paramList;
252    std::vector<VOParam>::iterator param;
253    VOParam singleParam;
254
255    std::string fname = this->par.getImageFile();
256    if(this->par.getFlagSubsection()) fname+=this->par.getSubsection();
257   
258    singleParam.define("FITS file","meta.file;meta.fits","char",fname,fname.size());
259    paramList.push_back(singleParam);
260    if(this->par.getFlagFDR())
261      singleParam.define("FDR Significance","stat.param","float",this->par.getAlpha(),0);
262    else
263      singleParam.define("Threshold","stat.snr","float",this->par.getCut(),0);
264    paramList.push_back(singleParam);
265   
266    if(this->par.getFlagATrous()){
267      std::string note = "The a trous reconstruction method was used, with the following parameters.";
268      singleParam.define("ATrous note","meta.note","char",note,note.size());
269      paramList.push_back(singleParam);
270      singleParam.define("ATrous Dimension","meta.code;stat","int",this->par.getReconDim(),0);
271      paramList.push_back(singleParam);
272      singleParam.define("ATrous Threshold","stat.snr","float",this->par.getAtrousCut(),0);
273      paramList.push_back(singleParam);
274      singleParam.define("ATrous Minimum Scale","stat.param","int",this->par.getMinScale(),0);
275      paramList.push_back(singleParam);
276      singleParam.define("ATrous Filter","meta.code;stat","char",this->par.getFilterName(),this->par.getFilterName().size());
277      paramList.push_back(singleParam);
278    }
279    if(this->par.getFlagSmooth()){
280      if(this->par.getSmoothType()=="spectral"){
281        std::string note = "The cube was smoothed spectrally with a Hanning filter, with the following parameters.";
282        singleParam.define("Smoothing note","meta.note","char",note,note.size());
283        paramList.push_back(singleParam);
284        singleParam.define("Hanning filter width","meta.code;stat","int",this->par.getHanningWidth(),0);
285        paramList.push_back(singleParam);
286      }
287      else if(this->par.getSmoothType()=="spatial"){
288        std::string note = "The cube was smoothed spatially with a Gaussian kernel, with the following parameters.";
289        singleParam.define("Smoothing note","meta.note","char",note,note.size());
290        paramList.push_back(singleParam);
291        singleParam.define("Gaussian kernel major-axis FWHM","meta.code;stat","int",this->par.getKernMaj(),0);
292        paramList.push_back(singleParam);
293        singleParam.define("Gaussian kernel minor-axis FWHM","meta.code;stat","int",this->par.getKernMin(),0);
294        paramList.push_back(singleParam);
295        singleParam.define("Gaussian kernel position angle","meta.code;stat","int",this->par.getKernPA(),0);
296        paramList.push_back(singleParam);
297      }   
298    }
299
300    for(param=paramList.begin();param<paramList.end();param++){
301      stream << "      ";
302      param->printParam(stream);
303    }   
304
305
306    std::string posUCD[4];
307    if(makelower(this->fullCols[Column::RAJD].getName())=="ra"){
308      posUCD[0] = "pos.eq.ra;meta.main";
309      posUCD[2] = "phys.angSize;pos.eq.ra";
310    }
311    else{
312      posUCD[0] = "pos.galactic.lat;meta.main";
313      posUCD[2] = "phys.angSize;pos.galactic.lat";
314    }
315    if(makelower(this->fullCols[DECJD].getName())=="dec"){
316      posUCD[1] = "pos.eq.dec;meta.main";
317      posUCD[3] = "phys.angSize;pos.eq.dec";
318    }
319    else{
320      posUCD[1] = "pos.galactic.lon;meta.main";
321      posUCD[3] = "phys.angSize;pos.galactic.lon";
322    }
323
324    std::vector<Column::Col>::iterator col;
325    for(col=this->fullCols.begin();col<this->fullCols.end();col++){
326
327      if(col->doCol("votable",this->head.isSpecOK())){
328        VOField field;
329        field.define(*col);
330        if(col->getType()==RAJD)  field.setUCD(posUCD[0]);
331        if(col->getType()==WRA)   field.setUCD(posUCD[1]);
332        if(col->getType()==DECJD) field.setUCD(posUCD[2]);
333        if(col->getType()==WDEC)  field.setUCD(posUCD[3]);     
334        stream << "      ";
335        field.printField(stream);
336      }
337
338    }
339
340    stream<<"      <DATA>\n"
341          <<"        <TABLEDATA>\n";
342
343    stream.setf(std::ios::fixed); 
344
345    std::vector<Detection>::iterator obj;
346    for(obj=this->objectList->begin();obj<this->objectList->end();obj++){
347
348      stream<<"        <TR>\n";
349      stream<<"          ";
350      std::vector<Column::Col>::iterator col;
351      for(col=this->fullCols.begin();col<this->fullCols.end();col++){
352        if(col->doCol("votable",this->head.isSpecOK())){
353          stream<<"<TD>";
354          obj->printTableEntry(stream, *col);
355          stream<<"</TD>";
356        }
357      }
358      stream<<"\n";
359      stream<<"        </TR>\n";
360
361    }
362
363    stream<<"        </TABLEDATA>\n";
364    stream<<"      </DATA>\n";
365    stream<<"    </TABLE>\n";
366    stream<<"  </RESOURCE>\n";
367    stream<<"</VOTABLE>\n";
368    resetiosflags(std::ios::fixed);
369 
370  }
371
372
373
374
375}
Note: See TracBrowser for help on using the repository browser.