source: tags/release-1.1.9/src/Cubes/momentMap.cc @ 705

Last change on this file since 705 was 670, checked in by MatthewWhiting, 14 years ago

Substantive changes aimed at addressing ticket #72. The moment-0 map is now able to be saved to a FITS file. As far as the user is concerned, the functionality is as
for the mask cube, with equivalent parameters. The documentation has also been updated.

File size: 6.2 KB
Line 
1// -----------------------------------------------------------------------
2// momentMap.cc : functions to calculate the momment-0 map of the cube
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#include <iostream>
29#include <iomanip>
30#include <sstream>
31#include <math.h>
32#include <string.h>
33#include <cpgplot.h>
34#include <wcslib/cpgsbox.h>
35#include <wcslib/pgwcsl.h>
36#include <wcslib/wcs.h>
37#include <duchamp/duchamp.hh>
38#include <duchamp/param.hh>
39#include <duchamp/fitsHeader.hh>
40#include <duchamp/Detection/detection.hh>
41#include <duchamp/PixelMap/Object3D.hh>
42#include <duchamp/Cubes/cubes.hh>
43#include <duchamp/Utils/utils.hh>
44
45using namespace PixelInfo;
46
47namespace duchamp
48{
49
50  void Cube::getMomentMapForPlot(float *momentMap, float &z1, float &z2)
51  {
52   
53    /// @details This returns the moment-0 map in a form suitable for
54    /// plotting via pgplot. The map is transformed to log space, and
55    /// the minimum & maximum values are also returned.
56    /// @param momentMap The values of log10(momentMap). This array needs to be declared beforehand.
57    /// @param z1 The minimum value of momentMap
58    /// @param z2 The maximum value of momentMap
59
60
61    long xdim=this->axisDim[0];
62    long ydim=this->axisDim[1];
63
64    std::vector<bool> detectedPixels;
65    this->getMomentMap(momentMap, detectedPixels);
66
67    int count=0;
68    for(int i=0;i<xdim*ydim;i++) {
69      if(momentMap[i]>0.){
70        float logmm = log10(momentMap[i]);
71        bool addPixel = detectedPixels[i];
72        if(addPixel){
73          if(count==0) z1 = z2 = logmm;
74          else{
75            if(logmm < z1) z1 = logmm;
76            if(logmm > z2) z2 = logmm;
77          }
78          count++;
79        }
80      }
81    }
82   
83    for(int i=0;i<xdim*ydim;i++) {
84      bool addPixel = detectedPixels[i];
85      addPixel = addPixel && (momentMap[i]>0.);
86      if(!addPixel) momentMap[i] = z1-1.;
87      else momentMap[i] = log10(momentMap[i]);
88    }
89
90  }
91
92  void Cube::getMomentMap(float *momentMap, std::vector<bool> &detectedPixels)
93  {
94
95    /// @details This returns the moment-0 map (ie. the map of
96    /// integrated flux) for the cube. The momentMap array needs to be
97    /// allocated before calling this function - it should be of the
98    /// same spatial dimensions as the cube. The function also returns
99    /// a map showing which spatial pixels are detected. This provides
100    /// a way of telling whether a given pixel is affected, as
101    /// although the momentMap is initialised to zero, it is
102    /// conceivable that a pixel with detections in its spectrum could
103    /// yield a value of zero. The detection map is stored as a
104    /// vector<bool> for compactness.
105    /// @param momentMap The array holding the moment map values. Needs to be allocated beforehand.
106    /// @param detectedPixel The map showing which spatial pixels contain an object.
107
108    long xdim=this->axisDim[0];
109    long ydim=this->axisDim[1];
110    long zdim=this->axisDim[2];
111
112    // get the list of objects that should be plotted.
113    std::vector<bool> objectChoice = this->par.getObjectChoices(this->objectList->size());
114
115    bool *isObj = new bool[xdim*ydim*zdim];
116    for(int i=0;i<xdim*ydim*zdim;i++) isObj[i] = false;
117    for(size_t i=0;i<this->objectList->size();i++){
118      if(objectChoice[i]){
119        std::vector<Voxel> voxlist = this->objectList->at(i).getPixelSet();
120        std::vector<Voxel>::iterator vox;
121        for(vox=voxlist.begin();vox<voxlist.end();vox++){
122          int pixelpos = vox->getX() + xdim*vox->getY() + xdim*ydim*vox->getZ();
123          isObj[pixelpos] = true;
124        }
125      }
126    }
127
128    // Array containing the moment map, initialised to zero
129    for(int i=0;i<xdim*ydim;i++) momentMap[i] = 0.;
130
131    // Bool vector containing yes/no on whether a given spatial pixel has a detected object.
132    // Initialise this to false everywhere.
133    detectedPixels = std::vector<bool>(xdim*ydim,false);
134
135    // if we are looking for negative features, we need to invert the
136    //  detected pixels for the moment map
137    float sign = 1.;
138    if(this->pars().getFlagNegative()) sign = -1.;
139
140    float deltaVel;
141    double x,y;
142
143    double *zArray  = new double[zdim];
144    for(int z=0; z<zdim; z++) zArray[z] = double(z);
145   
146    for(int pix=0; pix<xdim*ydim; pix++){
147
148      x = double(pix%xdim);
149      y = double(pix/xdim);
150
151      if(!this->isBlank(pix) &&   // only do this for non-blank pixels. Judge this by the first pixel of the channel.
152         this->detectMap[pix] > 0 ){  // and only where something was detected in the spectrum.
153
154        double * world = this->head.pixToVel(x,y,zArray,zdim);
155     
156        for(int z=0; z<zdim; z++){     
157          int pos =  z*xdim*ydim + pix;  // the voxel in the cube
158          if(isObj[pos]){ // if it's an object pixel...
159            // delta-vel is half the distance between adjacent channels.
160            // if at end, then just use 0-1 or (zdim-1)-(zdim-2) distance
161            if(z==0){
162              if(zdim==1) deltaVel=1.; // pathological case -- if 2D image.
163              else deltaVel = world[z+1] - world[z];
164            }
165            else if(z==(zdim-1)) deltaVel = world[z-1] - world[z];
166            else deltaVel = (world[z+1] - world[z-1]) / 2.;
167
168            momentMap[pix] += sign * this->array[pos] * fabs(deltaVel);
169            detectedPixels[pix] = true;
170
171          }
172        }
173        delete [] world;
174      }
175
176    }
177   
178    delete [] zArray;
179    delete [] isObj;
180
181  }
182
183
184}
Note: See TracBrowser for help on using the repository browser.