source: tags/release-1.6.1/src/Cubes/momentMap.cc @ 1441

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

A large changeset that moves all use of bool arrays (ie. bool *) to std::vector<bool>. This will be a bit safer, plus potentially cheaper in memory usage. Interfaces to all stats functions with masks have changed accordingly, as well as the Gaussian smoothing functions and some spectral utility functions.

File size: 6.1 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    std::vector<bool> isObj(xdim*ydim*zdim,false);
116    for(size_t i=0;i<this->objectList->size();i++){
117      if(objectChoice[i]){
118        std::vector<Voxel> voxlist = this->objectList->at(i).getPixelSet();
119        std::vector<Voxel>::iterator vox;
120        for(vox=voxlist.begin();vox<voxlist.end();vox++){
121          size_t pixelpos = vox->getX() + xdim*vox->getY() + xdim*ydim*vox->getZ();
122          isObj[pixelpos] = true;
123        }
124      }
125    }
126
127    // Array containing the moment map, initialised to zero
128    for(size_t i=0;i<xdim*ydim;i++) momentMap[i] = 0.;
129
130    // Bool vector containing yes/no on whether a given spatial pixel has a detected object.
131    // Initialise this to false everywhere.
132    std::vector<bool> detectedPixels = std::vector<bool>(xdim*ydim,false);
133
134    // if we are looking for negative features, we need to invert the
135    //  detected pixels for the moment map
136    float sign = 1.;
137    if(this->pars().getFlagNegative()) sign = -1.;
138
139    float deltaVel;
140    double x,y;
141
142    double *zArray  = new double[zdim];
143    for(size_t z=0; z<zdim; z++) zArray[z] = double(z);
144   
145    for(size_t pix=0; pix<xdim*ydim; pix++){
146
147      x = double(pix%xdim);
148      y = double(pix/xdim);
149
150      if( this->detectMap[pix] > 0 ){  // and only where something was detected in the spectrum.
151
152        double * world = this->head.pixToVel(x,y,zArray,zdim);
153     
154        for(size_t z=0; z<zdim; z++){     
155          size_t pos =  z*xdim*ydim + pix;  // the voxel in the cube
156          if(isObj[pos]){ // if it's an object pixel...
157            // delta-vel is half the distance between adjacent channels.
158            // if at end, then just use 0-1 or (zdim-1)-(zdim-2) distance
159            if(z==0){
160              if(zdim==1) deltaVel=1.; // pathological case -- if 2D image.
161              else deltaVel = world[z+1] - world[z];
162            }
163            else if(z==(zdim-1)) deltaVel = world[z-1] - world[z];
164            else deltaVel = (world[z+1] - world[z-1]) / 2.;
165
166            momentMap[pix] += sign * this->array[pos] * fabs(deltaVel);
167            detectedPixels[pix] = true;
168
169          }
170        }
171        delete [] world;
172      }
173
174    }
175   
176    delete [] zArray;
177
178    return detectedPixels;
179
180  }
181
182
183}
Note: See TracBrowser for help on using the repository browser.