source: trunk/src/Cubes/momentMap.cc @ 1361

Last change on this file since 1361 was 1361, checked in by MatthewWhiting, 10 years ago

Ticket #219 - largely addressing the problem. When doing negative + baseline modes, need to undo the inversion & baseline removal in two steps, so that we get the right sequencing of parameterisation and inversion of values. Also removing the reInvert() function, as it is no longer used.

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 <duchamp/duchamp.hh>
34#include <duchamp/param.hh>
35#include <duchamp/fitsHeader.hh>
36#include <duchamp/Detection/detection.hh>
37#include <duchamp/PixelMap/Object3D.hh>
38#include <duchamp/Cubes/cubes.hh>
39#include <duchamp/Utils/utils.hh>
40
41using namespace PixelInfo;
42
43namespace duchamp
44{
45
46  void Cube::getMomentMapForPlot(float *momentMap, float &z1, float &z2)
47  {
48   
49    /// @details This returns the moment-0 map in a form suitable for
50    /// plotting via pgplot. The map is transformed to log space, and
51    /// the minimum & maximum values are also returned.
52    /// @param momentMap The values of log10(momentMap). This array needs to be declared beforehand.
53    /// @param z1 The minimum value of momentMap
54    /// @param z2 The maximum value of momentMap
55
56
57    long xdim=this->axisDim[0];
58    long ydim=this->axisDim[1];
59
60    std::vector<bool> detectedPixels = this->getMomentMap(momentMap);
61   
62    if(this->pars().getFlagNegative())
63      for(int i=0;i<xdim*ydim;i++) momentMap[i]*=-1.;
64
65    int count=0;
66    for(int i=0;i<xdim*ydim;i++) {
67      if(this->detectMap[i]>0){
68          if(momentMap[i]>0){
69              float logmm = log10(momentMap[i]);
70              bool addPixel = detectedPixels[i];
71              if(addPixel){
72                  if(count==0) z1 = z2 = logmm;
73                  else{
74                      if(logmm < z1) z1 = logmm;
75                      if(logmm > z2) z2 = logmm;
76                  }
77                  count++;
78              }
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  std::vector<bool> Cube::getMomentMap(float *momentMap)
93  {
94
95    /// @details This populates 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 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 Pointer to the array holding the moment map values, which needs to be allocated beforehand.
106    /// @return detectedPixel The map showing which spatial pixels contain an object.
107
108    size_t xdim=this->axisDim[0];
109    size_t ydim=this->axisDim[1];
110    size_t 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(size_t 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          size_t 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(size_t 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    std::vector<bool> 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(size_t z=0; z<zdim; z++) zArray[z] = double(z);
145   
146    for(size_t pix=0; pix<xdim*ydim; pix++){
147
148      x = double(pix%xdim);
149      y = double(pix/xdim);
150
151      if( this->detectMap[pix] > 0 ){  // and only where something was detected in the spectrum.
152
153        double * world = this->head.pixToVel(x,y,zArray,zdim);
154     
155        for(size_t z=0; z<zdim; z++){     
156          size_t pos =  z*xdim*ydim + pix;  // the voxel in the cube
157          if(isObj[pos]){ // if it's an object pixel...
158            // delta-vel is half the distance between adjacent channels.
159            // if at end, then just use 0-1 or (zdim-1)-(zdim-2) distance
160            if(z==0){
161              if(zdim==1) deltaVel=1.; // pathological case -- if 2D image.
162              else deltaVel = world[z+1] - world[z];
163            }
164            else if(z==(zdim-1)) deltaVel = world[z-1] - world[z];
165            else deltaVel = (world[z+1] - world[z-1]) / 2.;
166
167            momentMap[pix] += sign * this->array[pos] * fabs(deltaVel);
168            detectedPixels[pix] = true;
169
170          }
171        }
172        delete [] world;
173      }
174
175    }
176   
177    delete [] zArray;
178    delete [] isObj;
179
180    return detectedPixels;
181
182  }
183
184
185}
Note: See TracBrowser for help on using the repository browser.