source: trunk/src/Cubes/cubes.hh @ 272

Last change on this file since 272 was 272, checked in by Matthew Whiting, 17 years ago
  • Moved the FitsHeader? class & functions to a separate file (fitsHeader.{cc,hh}).
  • This entailed changing a bunch of #include statements.
  • Also fixed up the declaration/implementation of Col functions.
File size: 20.8 KB
Line 
1#ifndef CUBES_H
2#define CUBES_H
3
4#include <iostream>
5#include <string>
6#include <vector>
7
8#include <param.hh>
9#include <fitsHeader.hh>
10#include <Detection/detection.hh>
11#include <Detection/columns.hh>
12#include <Cubes/plots.hh>
13#include <Utils/Statistics.hh>
14#include <PixelMap/Scan.hh>
15#include <PixelMap/Object2D.hh>
16
17using namespace Column;
18using namespace Statistics;
19using namespace PixelInfo;
20
21/****************************************************************/
22/**
23 * Base class for the image container.
24 *
25 * Definition of an n-dimensional data array:
26 *     array of pixel values, size & dimensions
27 *     array of Detection objects
28 */
29
30class DataArray
31{
32public:
33  DataArray();  ///< Basic DataArray constructor
34  DataArray(short int nDim); ///< Basic nDim-dimensional DataArray constructor
35  DataArray(short int nDim, long size);///< Basic nDim-dimensional DataArray constructor, specifying size.
36  DataArray(short int nDim, long *dimensions); ///< Basic nDim-dimensional DataArray constructor, specifying size of dimensions.
37  virtual ~DataArray(); ///< Basic DataArray constructor
38
39  //-----------------------------------------
40  // Obvious inline accessor functions.
41  //
42  long               getDimX(){if(numDim>0) return this->axisDim[0];else return 0;};
43  long               getDimY(){if(numDim>1) return this->axisDim[1];else return 1;};
44  long               getDimZ(){if(numDim>2) return this->axisDim[2];else return 1;};
45  long               getSize(){ return this->numPixels; };
46  short int          getNumDim(){ return this->numDim; };
47  virtual float      getPixValue(long pos){ return array[pos]; };
48  virtual void       setPixValue(long pos, float f){array[pos] = f;};;
49  Detection          getObject(long number){ return objectList[number]; };
50  std::vector <Detection> getObjectList(){ return objectList; };
51  long               getNumObj(){ return objectList.size(); };
52
53  /** Delete all objects from the list of detections. */
54  void               clearDetectionList(){ this->objectList.clear(); };
55
56  /** Read a parameter set from file. */
57  int                readParam(std::string paramfile){
58    /**
59     *  Uses Param::readParams() to read parameters from a file.
60     *  \param paramfile The file to be read.
61     */
62    return par.readParams(paramfile);
63  };
64
65  //-----------------------------------------
66  // Related to the various arrays
67  //
68  /**  Return first three dimensional axes. */
69  void               getDim(long &x, long &y, long &z);
70  /** Return array of dimensional sizes.*/
71  void               getDimArray(long *output);
72  long *             getDimArray(){return axisDim;};
73
74  /** Return pixel value array. */
75  void               getArray(float *output);
76  float *            getArray(){return array;};
77
78  /** Save pixel value array. */
79  virtual void       saveArray(float *input, long size);
80
81  //-----------------------------------------
82  // Related to the object lists
83  //
84  /** Adds a single detection to the object list.*/
85  void               addObject(Detection object);
86
87  /** Adds all objects in a detection list to the object list. */
88  void               addObjectList(std::vector <Detection> newlist);   
89
90  /** Add pixel offsets to object coordinates. */
91  void               addObjectOffsets();
92
93  //-----------------------------------------
94  // Parameter list related.
95  //
96  /** Output the Param set.*/
97  void               showParam(std::ostream &stream){ stream << this->par; };
98  /** Return the Param set.*/
99  Param              getParam(){ return this->par; };
100  /** Save a Param set to the Cube.*/
101  void               saveParam(Param newpar){this->par = newpar;};
102  /** Provides a reference to the Param set.*/
103  Param&             pars(){ Param &rpar = this->par; return rpar; };
104  /** Is the voxel number given by vox a BLANK value?*/
105  bool               isBlank(int vox);
106
107  // --------------------------------------------
108  // Statistics
109  //
110  /**  Returns the StatsContainer. */
111  StatsContainer<float> getStats(){ return this->Stats; };
112
113  /** Provides a reference to the StatsContainer. */
114  StatsContainer<float>& stats(){
115    StatsContainer<float> &rstats = this->Stats;  return rstats;
116  };
117 
118  /** Save a StatsContainer to the Cube. */
119  void saveStats(StatsContainer<float> newStats){ this->Stats = newStats;};
120
121  /** A detection test for value. */
122  bool isDetection(float value);
123
124  /**  A detection test for pixel.  */
125  bool isDetection(long voxel);
126
127
128  /** Output operator for DataArray.*/
129  friend std::ostream& operator<< (std::ostream& theStream, DataArray &array);
130 
131
132protected:
133  short int               numDim;     ///< Number of dimensions.
134  long                   *axisDim;    ///< Array of dimensions of cube
135                                      ///   (ie. how large in each
136                                      ///        direction).
137  long                    numPixels;  ///< Total number of pixels in cube.
138  float                  *array;      ///< Array of data.
139  std::vector <Detection> objectList; ///< The list of detected objects.
140  Param                   par;        ///< A parameter list.
141  StatsContainer<float>   Stats;      ///< The statistics for the DataArray.
142};
143
144
145
146//=========================================================================
147
148/**
149 * Definition of an data-cube object (3D):
150 *     a DataArray object limited to dim=3
151 */
152
153class Cube : public DataArray
154{
155public:
156  Cube();                 ///< Basic Cube constructor.
157  Cube(long nPix);        ///< Alternative Cube constructor.
158  Cube(long *dimensions); ///< Alternative Cube constructor.
159  virtual ~Cube();        ///< Basic Cube destructor.
160
161  // INLINE functions -- definitions included after class declaration.
162  /** Is the voxel number given by vox a BLANK value? */
163  bool        isBlank(int vox){ return par.isBlank(array[vox]); };
164
165  /** Is the voxel at (x,y,z) a BLANK value? */
166  bool        isBlank(long x, long y, long z){
167    return par.isBlank(array[z*axisDim[0]*axisDim[1] + y*axisDim[0] + x]); };
168
169  /** Does the Cube::recon array exist? */
170  bool        isRecon(){ return reconExists; };
171
172  float       getPixValue(long pos){ return array[pos]; };
173  float       getPixValue(long x, long y, long z){
174    return array[z*axisDim[0]*axisDim[1] + y*axisDim[0] + x]; };
175  short       getDetectMapValue(long pos){ return detectMap[pos]; };
176  short       getDetectMapValue(long x, long y){ return detectMap[y*axisDim[0]+x]; };
177  float       getReconValue(long pos){ return recon[pos]; };
178  float       getReconValue(long x, long y, long z){
179    return recon[z*axisDim[0]*axisDim[1] + y*axisDim[0] + x];};
180  float       getBaselineValue(long pos){ return baseline[pos]; };
181  float       getBaselineValue(long x, long y, long z){
182    return baseline[z*axisDim[0]*axisDim[1] + y*axisDim[0] + x]; };
183  void        setPixValue(long pos, float f){array[pos] = f;};;
184  void        setPixValue(long x, long y, long z, float f){
185    array[z*axisDim[0]*axisDim[1] + y*axisDim[0] + x] = f;};
186  void        setDetectMapValue(long pos, short f){ detectMap[pos] = f;};
187  void        setDetectMapValue(long x, long y, short f){ detectMap[y*axisDim[0] + x] = f;};
188  void        setReconValue(long pos, float f){recon[pos] = f;};
189  void        setReconValue(long x, long y, long z, float f){
190    recon[z*axisDim[0]*axisDim[1] + y*axisDim[0] + x] = f; };
191  void        setReconFlag(bool f){reconExists = f;};
192
193  std::vector<Col> getLogCols(){return logCols;};
194  void        setLogCols(std::vector<Col> C){logCols=C;};
195  std::vector<Col> getFullCols(){return fullCols;};
196  void        setFullCols(std::vector<Col> C){fullCols=C;};
197
198  // additional functions -- in Cubes/cubes.cc
199  /** Allocate memory correctly, with WCS defining the correct axes. */
200  void        initialiseCube(long *dimensions);
201
202  /** Read in a FITS file, with subsection correction. */
203  int         getCube();
204
205  /** Read in command-line options. */
206//   int         getopts(int argc, char ** argv);
207  int         getopts(int argc, char ** argv){return par.getopts(argc,argv);};
208
209  /** Read in reconstructed & smoothed arrays from FITS files on disk. */
210  void        readSavedArrays();
211
212  /** Save an external array to the Cube's pixel array */
213  void        saveArray(float *input, long size);
214
215  /** Save an external array to the Cube's reconstructed array. */
216  void        saveRecon(float *input, long size);
217
218  /** Save reconstructed array to an external array. */
219  void        getRecon(float *output);
220
221  /** Set Milky Way channels to zero. */
222  void        removeMW();
223
224  //------------------------
225  // Statistics for cube
226  //
227
228  /** Calculate the statistics for the Cube (older version). */
229  void        setCubeStatsOld();
230
231  /** Calculate the statistics for the Cube. */
232  void        setCubeStats();
233
234  /** Set up thresholds for the False Discovery Rate routine. */
235  void        setupFDR();
236
237  /** A detection test for a given voxel. */
238  bool        isDetection(long x, long y, long z);
239
240  //-----------------------------
241  // Dealing with the detections
242  //
243
244  /** Calculate the WCS parameters for each Cube Detection. */
245  void        calcObjectWCSparams();
246
247  /** Sort the list of detections. */
248  void        sortDetections();
249
250  /** Update the map of detected pixels. */
251  void        updateDetectMap();
252
253  /** Update the map of detected pixels for a given Detection. */
254  void        updateDetectMap(Detection obj);
255
256  /** Find the flux enclosed by a Detection. */
257  float       enclosedFlux(Detection obj);
258
259  /** Set up the output column definitions for the Cube and its
260      Detection list. */
261  void        setupColumns();
262
263  /** Is the object at the edge of the image? */
264  bool        objAtSpatialEdge(Detection obj);
265
266  /** Is the object at an end of the spectrum? */
267  bool        objAtSpectralEdge(Detection obj);
268
269  /** Set warning flags for the detections. */
270  void        setObjectFlags();
271
272  // ----------------------------
273  // Dealing with the WCS
274  //
275  FitsHeader  getHead(){ return head; };
276  void        setHead(FitsHeader F){head = F;};
277  FitsHeader& header(){ FitsHeader &h = head; return h; };
278
279  /** Convert a point from WCS to Pixel coords. */
280  int         wcsToPix(const double *world, double *pix);
281
282  /** Convert a set of points from WCS to Pixel coords. */
283  int         wcsToPix(const double *world, double *pix, const int npts);
284
285  /** Convert a point from Pixel to WCS coords. */
286  int         pixToWCS(const double *pix, double *world);
287
288  /** Convert a set of points from Pixel to WCS coords. */
289  int         pixToWCS(const double *pix, double *world, const int npts);
290
291  //-------------------------------------------
292  // FITS-I/O related functions -- not in cubes.cc
293  //
294  /** Function to read in FITS file.*/
295  int         getCube(std::string fname);  // in Cubes/getImage.cc
296
297  /** Function to retrieve FITS data array */
298  int         getFITSdata(std::string fname);   // in FitsIO/dataIO.cc
299
300  /** Save Hanning-smoothed array to disk.*/
301  void        saveSmoothedCube();       // in Cubes/saveImage.cc
302
303  /** Save Reconstructed array to disk. */
304  void        saveReconstructedCube();  // in Cubes/saveImage.cc
305
306  /** Read in reconstructed array from FITS file. */
307  int         readReconCube();  // in Cubes/readRecon.cc
308 
309  /** Read in Hanning-smoothed array from FITS file. */
310  int         readSmoothCube();     // in Cubes/readSmooth.cc 
311
312  //-------------------------------------
313  // Functions that act on the cube
314  //
315
316  /** Remove excess BLANK pixels from spatial edge of cube. */
317  void        trimCube();         // in Cubes/trimImage.cc
318
319  /** Replace BLANK pixels to spatial edge of cube. */
320  void        unTrimCube();       // in Cubes/trimImage.cc
321
322  /** Removes the baselines from the spectra, and stores in Cube::baseline */
323  void        removeBaseline();   // in Cubes/baseline.cc
324
325  /** Replace the baselines stored in Cube::baseline */
326  void        replaceBaseline();  // in Cubes/baseline.cc
327
328  /** Multiply all pixel values by -1. */
329  void        invert();           // in Cubes/invertCube.cc
330
331  /** Undo the inversion, and invert fluxes of all detected objects. */
332  void        reInvert();         // in Cubes/invertCube.cc
333
334  //-------------------------------------
335  // Reconstruction, Searching and Merging functions
336  //
337  // in ATrous/ReconSearch.cc
338  /** Front-end to reconstruction & searching functions.*/
339  void        ReconSearch();
340  /** Switcher to reconstruction functions */
341  void        ReconCube();
342  /** Performs 1-dimensional a trous reconstruction on the Cube. */
343  void        ReconCube1D();
344  /** Performs 2-dimensional a trous reconstruction on the Cube. */
345  void        ReconCube2D();
346  /** Performs 3-dimensional a trous reconstruction on the Cube. */
347  void        ReconCube3D();
348
349  // in Cubes/CubicSearch.cc
350  /** Front-end to the cubic searching routine. */
351  void        CubicSearch();
352
353  // in Cubes/smoothCube.cc
354  /** Front-end to the smoothing and searching functions. */
355  void        SmoothSearch();
356  /** A function to Hanning-smooth the cube. */
357  void        SmoothCube();
358
359  // in Cubes/Merger.cc
360  /** Merge all objects in the detection list so that only distinct
361      ones are left. */
362  void        ObjectMerger();
363 
364  //-------------------------------------
365  // Text outputting of detected objects.
366  //   in Cubes/detectionIO.cc
367  //
368  /** Output detections to a Karma annotation file. */
369  void        outputDetectionsKarma(std::ostream &stream);
370
371  /** Output detections to a VOTable. */
372  void        outputDetectionsVOTable(std::ostream &stream);
373
374  /** Output detections to the output file and standard output. */
375  void        outputDetectionList();
376
377  /** Output detections to the log file. */
378  void        logDetectionList();
379
380  /** Output a single detection to the log file. */
381  void        logDetection(Detection obj, int counter);
382
383
384  // ----------------------------------
385  // Graphical plotting of the cube and the detections.
386  //
387  /** Draw blank edges of cube. */
388  void        plotBlankEdges();  // in cubes.cc
389
390  //  in Cubes/plotting.cc
391  /** Plot a spatial map of detections based on number of detected
392      channels. */
393  void        plotDetectionMap(std::string pgDestination);
394
395  /** Plot a spatial map of detections based on 0th moment map of each
396      object. */
397  void        plotMomentMap(std::string pgDestination);
398
399  /** Plot a spatial map of detections based on 0th moment map of each
400      object to a number of PGPLOT devices. */
401  void        plotMomentMap(std::vector<std::string> pgDestination);
402
403  /** Draw WCS axes over a PGPLOT map. */
404  void        plotWCSaxes();
405
406  //  in Cubes/outputSpectra.cc
407  /** Print spectra of each detected object. */
408  void        outputSpectra();
409
410  /** Print spectrum of a single object */
411  void        plotSpectrum(Detection obj,Plot::SpectralPlot &plot);
412
413  //  in Cubes/drawMomentCutout.cc
414  /** Draw the 0th moment map for a single object. */
415  void        drawMomentCutout(Detection &object);
416
417  /** Draw a scale bar indicating angular size of the cutout. */
418  void        drawScale(float xstart,float ystart,float channel);
419
420  /** Draw a yellow line around the edge of the spatial extent of
421      pixels. */
422  void        drawFieldEdge();
423
424private:
425  float      *recon;            ///< reconstructed array - used when
426                                ///   doing a trous reconstruction.
427  bool        reconExists;      ///< flag saying whether there is a
428                                ///   reconstruction
429  short      *detectMap;        ///< "moment map" - x,y locations of
430                                ///   detected pixels
431  float      *baseline;         ///< array of spectral baseline
432                                ///   values.
433                             
434  bool        reconAllocated;   ///< have we allocated memory for the
435                                ///   recon array?
436  bool        baselineAllocated;///< have we allocated memory for the
437                                ///   baseline array?
438  FitsHeader  head;             ///< the WCS and other header
439                                ///   information.
440  std::vector<Col> fullCols;    ///< the list of all columns as
441                                ///   printed in the results file
442  std::vector<Col> logCols;     ///< the list of columns as printed in
443                                ///   the log file
444
445};
446
447////////////
448//// Cube inline function definitions
449////////////
450
451inline int Cube::wcsToPix(const double *world, double *pix)
452{
453  /**
454   *  Use the WCS in the FitsHeader to convert from WCS to pixel coords for
455   *   a single point.
456   *  \param world The world coordinates.
457   *  \param pix The returned pixel coordinates.
458   */
459  return this->head.wcsToPix(world,pix);
460}
461inline int Cube::wcsToPix(const double *world, double *pix, const int npts)
462{
463  /**
464   *  Use the WCS in the FitsHeader to convert from WCS to pixel coords for
465   *   a set of points.
466   *  \param world The world coordinates.
467   *  \param pix The returned pixel coordinates.
468   *  \param npts The number of points being converted.
469   */
470  return this->head.wcsToPix(world,pix,npts);
471}
472inline int Cube::pixToWCS(const double *pix, double *world)
473{
474  /**
475   *  Use the WCS in the FitsHeader to convert from pixel to WCS coords for
476   *   a single point.
477   *  \param pix The pixel coordinates.
478   *  \param world The returned world coordinates.
479   */
480  return this->head.pixToWCS(pix,world);
481}
482inline int Cube::pixToWCS(const double *pix, double *world, const int npts)
483{
484  /**
485   *  Use the WCS in the FitsHeader to convert from pixel to WCS coords for
486   *   a set of points.
487   *  \param pix The pixel coordinates.
488   *  \param world The returned world coordinates.
489   *  \param npts The number of points being converted.
490   */
491  return this->head.pixToWCS(pix,world,npts);
492}
493
494
495//===============================================================================
496
497/**
498 *  A DataArray object limited to two dimensions, and with some additional
499 *   special functions.
500 *
501 *  It is used primarily for searching a 1- or 2-D array with
502 *   lutz_detect() and spectrumDetect().
503 */
504
505class Image : public DataArray
506{
507public:
508  Image(){numPixels=0; numDim=2;};
509  Image(long nPix);
510  Image(long *dimensions);
511  virtual ~Image(){};
512
513  //--------------------
514  // Defining the array
515  //
516  /** Save an external array to the Cube's pixel array */
517  void      saveArray(float *input, long size);
518
519  /** Extract a spectrum from an array and save to the local pixel array. */
520  void      extractSpectrum(float *Array, long *dim, long pixel);
521
522  /** Extract an image from an array and save to the local pixel array. */
523  void      extractImage(float *Array, long *dim, long channel);
524
525  /** Extract a spectrum from a cube and save to the local pixel array. */
526  void      extractSpectrum(Cube &cube, long pixel);
527
528  /** Extract an image from a cube and save to the local pixel array. */
529  void      extractImage(Cube &cube, long channel);
530
531  //--------------------
532  // Accessing the data.
533  //
534  float     getPixValue(long pos){ return array[pos]; };
535  float     getPixValue(long x, long y){return array[y*axisDim[0] + x];};
536  // the next few should have checks against array overflow...
537  void      setPixValue(long pos, float f){array[pos] = f;};;
538  void      setPixValue(long x, long y, float f){array[y*axisDim[0] + x] = f;};
539  bool      isBlank(int vox){return par.isBlank(array[vox]);};
540  bool      isBlank(long x,long y){return par.isBlank(array[y*axisDim[0]+x]);};
541
542  //-----------------------
543  // Detection-related
544  //
545  /** Detect objects in a 2-D image */
546  std::vector<Object2D> lutz_detect();    // in Detection/lutz_detect.cc
547
548  /** Detect objects in a 1-D spectrum */
549  std::vector<Scan> spectrumDetect();     // in Detection/spectrumDetect.cc
550
551  int       getMinSize(){return minSize;};
552  void      setMinSize(int i){minSize=i;};
553
554  /**  A detection test for a pixel location.  */
555  bool      isDetection(long x, long y){
556    /**
557     * Test whether a pixel (x,y) is a statistically significant detection,
558     * according to the set of statistics in the local StatsContainer object.
559     */
560    long voxel = y*axisDim[0] + x;
561    if(isBlank(x,y)) return false;
562    else return Stats.isDetection(array[voxel]);
563  }; 
564
565  /** Blank out a set of channels marked as being Milky Way channels */
566  void      removeMW();
567
568private:
569  int       minSize;    ///< the minimum number of pixels for a
570                        ///   detection to be accepted.
571};
572
573
574/****************************************************************/
575//////////////////////////////////////////////////////
576// Prototypes for functions that use above classes
577//////////////////////////////////////////////////////
578
579/** Search a reconstructed array for significant detections. */
580std::vector <Detection> searchReconArray(long *dim, float *originalArray,
581                                         float *reconArray, Param &par,
582                                         StatsContainer<float> &stats);
583std::vector <Detection> searchReconArraySimple(long *dim, float *originalArray,
584                                               float *reconArray, Param &par,
585                                               StatsContainer<float> &stats);
586
587/** Search a 3-dimensional array for significant detections. */
588std::vector <Detection> search3DArray(long *dim, float *Array, Param &par,
589                                      StatsContainer<float> &stats);
590std::vector <Detection> search3DArraySimple(long *dim, float *Array,
591                                            Param &par,
592                                            StatsContainer<float> &stats);
593
594/** Grow an object to a lower threshold */
595void growObject(Detection &object, Cube &cube);
596
597/** Draw the edge of the BLANK region on a map.*/
598void drawBlankEdges(float *dataArray, int xdim, int ydim, Param &par);
599
600#endif
Note: See TracBrowser for help on using the repository browser.