source: trunk/src/Detection/ObjectGrower.cc @ 1069

Last change on this file since 1069 was 1069, checked in by MatthewWhiting, 12 years ago

Adding the licensing text to files that didn't have it.

File size: 9.5 KB
RevLine 
[1069]1// -----------------------------------------------------------------------
2// ObjectGrower.cc: Implementation of the object growing functions
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// -----------------------------------------------------------------------
[922]28
[742]29#include <iostream>
[906]30#include <vector>
[742]31#include <duchamp/duchamp.hh>
[1052]32#include <duchamp/Detection/ObjectGrower.hh>
33#include <duchamp/Detection/detection.hh>
34#include <duchamp/Cubes/cubes.hh>
[742]35#include <duchamp/Utils/Statistics.hh>
36#include <duchamp/PixelMap/Voxel.hh>
37
38
39namespace duchamp {
40
41  ObjectGrower::ObjectGrower() {
42  }
43
44  ObjectGrower::ObjectGrower(ObjectGrower &o)
45  {
46    this->operator=(o);
47  }
48
49  ObjectGrower& ObjectGrower::operator=(const ObjectGrower &o)
50  {
51    if(this == &o) return *this;
52    this->itsFlagArray = o.itsFlagArray;
53    this->itsArrayDim = o.itsArrayDim;
54    this->itsGrowthStats = o.itsGrowthStats;
55    this->itsSpatialThresh = o.itsSpatialThresh;
56    this->itsVelocityThresh = o.itsVelocityThresh;
57    this->itsFluxArray = o.itsFluxArray;
58    return *this;
59  }
60
61  void ObjectGrower::define( Cube *theCube )
62  {
[759]63    /// @details This copies all necessary information from the Cube
64    /// and its parameters & statistics. It also defines the array of
65    /// pixel flags, which involves looking at each object to assign
66    /// them as detected, all blank & "milky-way" pixels to assign
67    /// them appropriately, and all others to "available". It is only
68    /// the latter that will be considered in the growing function.
69    /// @param theCube A pointer to a duchamp::Cube
70
[742]71    this->itsGrowthStats = Statistics::StatsContainer<float>(theCube->stats());
72    if(theCube->pars().getFlagUserGrowthThreshold())
73      this->itsGrowthStats.setThreshold(theCube->pars().getGrowthThreshold());
74    else
75      this->itsGrowthStats.setThresholdSNR(theCube->pars().getGrowthCut());   
76    this->itsGrowthStats.setUseFDR(false);
77
78    if(theCube->isRecon()) this->itsFluxArray = theCube->getRecon();
79    else this->itsFluxArray = theCube->getArray();
80
[984]81    this->itsArrayDim = std::vector<size_t>(3);
[742]82    this->itsArrayDim[0]=theCube->getDimX();
83    this->itsArrayDim[1]=theCube->getDimY();
84    this->itsArrayDim[2]=theCube->getDimZ();
85    size_t spatsize=this->itsArrayDim[0]*this->itsArrayDim[1];
86    size_t fullsize=spatsize*this->itsArrayDim[2];
87
88    if(theCube->pars().getFlagAdjacent())
89      this->itsSpatialThresh = 1;
90    else
91      this->itsSpatialThresh = int(theCube->pars().getThreshS());
92    this->itsVelocityThresh = int(theCube->pars().getThreshV());
93
94    this->itsFlagArray = std::vector<STATE>(fullsize,AVAILABLE);
95
[894]96    for(size_t o=0;o<theCube->getNumObj();o++){
[742]97      std::vector<Voxel> voxlist = theCube->getObject(o).getPixelSet();
98      for(size_t i=0; i<voxlist.size(); i++){
[779]99        size_t pos = voxlist[i].getX() + voxlist[i].getY()*this->itsArrayDim[0] + voxlist[i].getZ()*spatsize;
[742]100        this->itsFlagArray[pos] = DETECTED;
101      }
102    }
103
104    if(theCube->pars().getFlagMW()){
[779]105      int minz=std::max(0,theCube->pars().getMinMW());
106      int maxz=std::min(int(theCube->getDimZ())-1,theCube->pars().getMaxMW());
107      if(minz<maxz){
108        for(size_t i=minz*spatsize;i<(maxz+1)*spatsize;i++) this->itsFlagArray[i]=MW;
109      }
[742]110    }
111
112    for(size_t i=0;i<fullsize;i++)
113      if(theCube->isBlank(i)) this->itsFlagArray[i]=BLANK;
114
115  }
116
[984]117
118  void ObjectGrower::updateDetectMap(short *map)
119  {
120
121    int numNondegDim=0;
122    for(int i=0;i<3;i++) if(this->itsArrayDim[i]>1) numNondegDim++;
123
124    if(numNondegDim>1){
125      size_t spatsize=this->itsArrayDim[0]*this->itsArrayDim[1];
126      for(size_t xy=0;xy<spatsize;xy++){
127        short ct=0;
128        for(size_t z=0;z<this->itsArrayDim[2];z++){
129          if(this->itsFlagArray[xy+z*spatsize] == DETECTED) ct++;
130        }
131        map[xy]=ct;
132      }
133    }
134    else{
135      for(size_t z=0;z<this->itsArrayDim[2];z++){
136        map[z] = (this->itsFlagArray[z] == DETECTED) ? 1 : 0;
137      }
138    }
139
140  }
141
142
[742]143  void ObjectGrower::grow(Detection *theObject)
144  {
[759]145    /// @details This function grows the provided object out to the
146    /// secondary threshold provided in itsGrowthStats. For each pixel
147    /// in an object, all surrounding pixels are considered and, if
148    /// their flag is AVAILABLE, their flux is examined. If it's above
149    /// the threshold, that pixel is added to the list to be looked at
150    /// and their flag is changed to DETECTED.
151    /// @param theObject The duchamp::Detection object to be grown. It
152    /// is returned with new pixels in place. Only the basic
153    /// parameters that belong to PixelInfo::Object3D are
154    /// recalculated.
155
[984]156    size_t spatsize=this->itsArrayDim[0]*this->itsArrayDim[1];
[922]157    long zero = 0;
[742]158    std::vector<Voxel> voxlist = theObject->getPixelSet();
[922]159    size_t origSize = voxlist.size();
160    long xpt,ypt,zpt;
[984]161    long xmin,xmax,ymin,ymax,zmin,zmax,x,y,z;
[922]162    size_t pos;
[742]163    for(size_t i=0; i<voxlist.size(); i++){
164     
[922]165      // std::vector<Voxel> newvox = this->growFromPixel(voxlist[i]);
166      // for(size_t v=0;v<newvox.size();v++) voxlist.push_back(newvox[v]);
[868]167
[922]168      xpt=voxlist[i].getX();
169      ypt=voxlist[i].getY();
170      zpt=voxlist[i].getZ();
[742]171     
[984]172      xmin = size_t(std::max(xpt - this->itsSpatialThresh, zero));
173      xmax = size_t(std::min(xpt + this->itsSpatialThresh, long(this->itsArrayDim[0])-1));
174      ymin = size_t(std::max(ypt - this->itsSpatialThresh, zero));
175      ymax = size_t(std::min(ypt + this->itsSpatialThresh, long(this->itsArrayDim[1])-1));
176      zmin = size_t(std::max(zpt - this->itsVelocityThresh, zero));
177      zmax = size_t(std::min(zpt + this->itsVelocityThresh, long(this->itsArrayDim[2])-1));
[742]178     
[922]179      //loop over surrounding pixels.
180      for(x=xmin; x<=xmax; x++){
181        for(y=ymin; y<=ymax; y++){
182          for(z=zmin; z<=zmax; z++){
[742]183
[922]184            pos=x+y*this->itsArrayDim[0]+z*spatsize;
185            if( ((x!=xpt) || (y!=ypt) || (z!=zpt))
186                && this->itsFlagArray[pos]==AVAILABLE ) {
[742]187
[922]188              if(this->itsGrowthStats.isDetection(this->itsFluxArray[pos])){
189                this->itsFlagArray[pos]=DETECTED;
190                voxlist.push_back(Voxel(x,y,z));
191              }
192            }
[742]193
[922]194          } //end of z loop
195        } // end of y loop
196      } // end of x loop
[742]197
198    } // end of i loop (voxels)
199
200    // Add in new pixels to the Detection
201    for(size_t i=origSize; i<voxlist.size(); i++){
202      theObject->addPixel(voxlist[i]);
203    }
204   
205
206  }
207
208
[906]209  std::vector<Voxel> ObjectGrower::growFromPixel(Voxel &vox)
[868]210  {
211
[922]212    std::vector<Voxel> newVoxels;
[906]213    // std::cerr << vox << "\n";
[868]214    long xpt=vox.getX();
215    long ypt=vox.getY();
216    long zpt=vox.getZ();
[915]217    size_t spatsize=this->itsArrayDim[0]*this->itsArrayDim[1];
[868]218    long zero = 0;
[906]219    // std::cerr << "--> " << xpt << " " << ypt << " " << zpt << "\n";
220
[868]221    int xmin = std::max(xpt - this->itsSpatialThresh, zero);
[984]222    int xmax = std::min(xpt + this->itsSpatialThresh, long(this->itsArrayDim[0])-1);
[868]223    int ymin = std::max(ypt - this->itsSpatialThresh, zero);
[984]224    int ymax = std::min(ypt + this->itsSpatialThresh, long(this->itsArrayDim[1])-1);
[868]225    int zmin = std::max(zpt - this->itsVelocityThresh, zero);
[984]226    int zmax = std::min(zpt + this->itsVelocityThresh, long(this->itsArrayDim[2])-1);
[868]227     
[906]228    // std::cerr << xmin << " " << xmax << "  " << ymin << " " << ymax << "  " << zmin << " " << zmax << "\n";
[868]229    //loop over surrounding pixels.
[915]230    size_t pos;
[906]231    Voxel nvox;
232    std::vector<Voxel> morevox;
[868]233    for(int x=xmin; x<=xmax; x++){
234      for(int y=ymin; y<=ymax; y++){
235        for(int z=zmin; z<=zmax; z++){
236
[906]237          pos=x+y*this->itsArrayDim[0]+z*spatsize;
[868]238          if( ((x!=xpt) || (y!=ypt) || (z!=zpt))
239              && this->itsFlagArray[pos]==AVAILABLE ) {
240
241            if(this->itsGrowthStats.isDetection(this->itsFluxArray[pos])){
242              this->itsFlagArray[pos]=DETECTED;
[906]243              nvox.setXYZF(x,y,z,this->itsFluxArray[pos]);
244              newVoxels.push_back(nvox);
245              // std::cerr << x << " " << y << " " << z << " " << this->itsFluxArray[pos] << "  =  " << nvox << "\n";
[922]246              // morevox = this->growFromPixel(nvox);
247              // if(morevox.size()>0)
248              //        for(size_t v=0;v<morevox.size();v++) newVoxels.push_back(morevox[v]);
[868]249             
250            }
251          }
252
253        } //end of z loop
254      } // end of y loop
255    } // end of x loop
256
[922]257    std::vector<Voxel>::iterator v,v2;
258    for(v=newVoxels.begin();v<newVoxels.end();v++) {
259      std::vector<Voxel> morevox = this->growFromPixel(*v);
260      for(v2=morevox.begin();v2<morevox.end();v2++)
261        newVoxels.push_back(*v2);
262    }
263
[868]264    return newVoxels;
265
266  }
267
268  // void ObjectGrower::resetDetectionFlags()
269  // {
270  //   for(size_t i=0;i<itsFlagArray.size();i++)
271  //     if(itsFlagArray[i]==DETECTED) itsFlagArray[i] = AVAILABLE;
272  // }
273
274  // void ObjectGrower::growInwardsFromEdge()
275  // {
276   
277
278
279  // }
280
[742]281}
Note: See TracBrowser for help on using the repository browser.