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

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

Optimising the object grower a little, to try to get around segfaults

File size: 7.3 KB
Line 
1#include <iostream>
2#include <vector>
3#include <duchamp/duchamp.hh>
4#include <Detection/ObjectGrower.hh>
5#include <Detection/detection.hh>
6#include <Cubes/cubes.hh>
7#include <duchamp/Utils/Statistics.hh>
8#include <duchamp/PixelMap/Voxel.hh>
9
10
11namespace duchamp {
12
13  ObjectGrower::ObjectGrower() {
14  }
15
16  ObjectGrower::ObjectGrower(ObjectGrower &o)
17  {
18    this->operator=(o);
19  }
20
21  ObjectGrower& ObjectGrower::operator=(const ObjectGrower &o)
22  {
23    if(this == &o) return *this;
24    this->itsFlagArray = o.itsFlagArray;
25    this->itsArrayDim = o.itsArrayDim;
26    this->itsGrowthStats = o.itsGrowthStats;
27    this->itsSpatialThresh = o.itsSpatialThresh;
28    this->itsVelocityThresh = o.itsVelocityThresh;
29    this->itsFluxArray = o.itsFluxArray;
30    return *this;
31  }
32
33  void ObjectGrower::define( Cube *theCube )
34  {
35    /// @details This copies all necessary information from the Cube
36    /// and its parameters & statistics. It also defines the array of
37    /// pixel flags, which involves looking at each object to assign
38    /// them as detected, all blank & "milky-way" pixels to assign
39    /// them appropriately, and all others to "available". It is only
40    /// the latter that will be considered in the growing function.
41    /// @param theCube A pointer to a duchamp::Cube
42
43    this->itsGrowthStats = Statistics::StatsContainer<float>(theCube->stats());
44    if(theCube->pars().getFlagUserGrowthThreshold())
45      this->itsGrowthStats.setThreshold(theCube->pars().getGrowthThreshold());
46    else
47      this->itsGrowthStats.setThresholdSNR(theCube->pars().getGrowthCut());   
48    this->itsGrowthStats.setUseFDR(false);
49
50    if(theCube->isRecon()) this->itsFluxArray = theCube->getRecon();
51    else this->itsFluxArray = theCube->getArray();
52
53    this->itsArrayDim = std::vector<long>(3);
54    this->itsArrayDim[0]=theCube->getDimX();
55    this->itsArrayDim[1]=theCube->getDimY();
56    this->itsArrayDim[2]=theCube->getDimZ();
57    size_t spatsize=this->itsArrayDim[0]*this->itsArrayDim[1];
58    size_t fullsize=spatsize*this->itsArrayDim[2];
59
60    if(theCube->pars().getFlagAdjacent())
61      this->itsSpatialThresh = 1;
62    else
63      this->itsSpatialThresh = int(theCube->pars().getThreshS());
64    this->itsVelocityThresh = int(theCube->pars().getThreshV());
65
66    this->itsFlagArray = std::vector<STATE>(fullsize,AVAILABLE);
67
68    for(size_t o=0;o<theCube->getNumObj();o++){
69      std::vector<Voxel> voxlist = theCube->getObject(o).getPixelSet();
70      for(size_t i=0; i<voxlist.size(); i++){
71        size_t pos = voxlist[i].getX() + voxlist[i].getY()*this->itsArrayDim[0] + voxlist[i].getZ()*spatsize;
72        this->itsFlagArray[pos] = DETECTED;
73      }
74    }
75
76    if(theCube->pars().getFlagMW()){
77      int minz=std::max(0,theCube->pars().getMinMW());
78      int maxz=std::min(int(theCube->getDimZ())-1,theCube->pars().getMaxMW());
79      if(minz<maxz){
80        for(size_t i=minz*spatsize;i<(maxz+1)*spatsize;i++) this->itsFlagArray[i]=MW;
81      }
82    }
83
84    for(size_t i=0;i<fullsize;i++)
85      if(theCube->isBlank(i)) this->itsFlagArray[i]=BLANK;
86
87  }
88
89  void ObjectGrower::grow(Detection *theObject)
90  {
91    /// @details This function grows the provided object out to the
92    /// secondary threshold provided in itsGrowthStats. For each pixel
93    /// in an object, all surrounding pixels are considered and, if
94    /// their flag is AVAILABLE, their flux is examined. If it's above
95    /// the threshold, that pixel is added to the list to be looked at
96    /// and their flag is changed to DETECTED.
97    /// @param theObject The duchamp::Detection object to be grown. It
98    /// is returned with new pixels in place. Only the basic
99    /// parameters that belong to PixelInfo::Object3D are
100    /// recalculated.
101
102    // long spatsize=this->itsArrayDim[0]*this->itsArrayDim[1];
103    // long zero = 0;
104    std::vector<Voxel> voxlist = theObject->getPixelSet();
105    int origSize = voxlist.size();
106    for(size_t i=0; i<voxlist.size(); i++){
107     
108      std::vector<Voxel> newvox = this->growFromPixel(voxlist[i]);
109      for(size_t v=0;v<newvox.size();v++) voxlist.push_back(newvox[v]);
110
111      // long xpt=voxlist[i].getX();
112      // long ypt=voxlist[i].getY();
113      // long zpt=voxlist[i].getZ();
114     
115      // int xmin = std::max(xpt - this->itsSpatialThresh, zero);
116      // int xmax = std::min(xpt + this->itsSpatialThresh, this->itsArrayDim[0]-1);
117      // int ymin = std::max(ypt - this->itsSpatialThresh, zero);
118      // int ymax = std::min(ypt + this->itsSpatialThresh, this->itsArrayDim[1]-1);
119      // int zmin = std::max(zpt - this->itsVelocityThresh, zero);
120      // int zmax = std::min(zpt + this->itsVelocityThresh, this->itsArrayDim[2]-1);
121     
122      // //loop over surrounding pixels.
123      // for(int x=xmin; x<=xmax; x++){
124      //        for(int y=ymin; y<=ymax; y++){
125      //          for(int z=zmin; z<=zmax; z++){
126
127      //            int pos=x+y*this->itsArrayDim[0]+z*spatsize;
128      //            if( ((x!=xpt) || (y!=ypt) || (z!=zpt))
129      //                && this->itsFlagArray[pos]==AVAILABLE ) {
130
131      //              if(this->itsGrowthStats.isDetection(this->itsFluxArray[pos])){
132      //                this->itsFlagArray[pos]=DETECTED;
133      //                voxlist.push_back(Voxel(x,y,z));
134      //              }
135      //            }
136
137      //          } //end of z loop
138      //        } // end of y loop
139      // } // end of x loop
140
141    } // end of i loop (voxels)
142
143    // Add in new pixels to the Detection
144    for(size_t i=origSize; i<voxlist.size(); i++){
145      theObject->addPixel(voxlist[i]);
146    }
147   
148
149  }
150
151
152  std::vector<Voxel> ObjectGrower::growFromPixel(Voxel &vox)
153  {
154
155    std::vector<Voxel> newVoxels(0);
156    // std::cerr << vox << "\n";
157    long xpt=vox.getX();
158    long ypt=vox.getY();
159    long zpt=vox.getZ();
160    long spatsize=this->itsArrayDim[0]*this->itsArrayDim[1];
161    long zero = 0;
162    // std::cerr << "--> " << xpt << " " << ypt << " " << zpt << "\n";
163
164    int xmin = std::max(xpt - this->itsSpatialThresh, zero);
165    int xmax = std::min(xpt + this->itsSpatialThresh, this->itsArrayDim[0]-1);
166    int ymin = std::max(ypt - this->itsSpatialThresh, zero);
167    int ymax = std::min(ypt + this->itsSpatialThresh, this->itsArrayDim[1]-1);
168    int zmin = std::max(zpt - this->itsVelocityThresh, zero);
169    int zmax = std::min(zpt + this->itsVelocityThresh, this->itsArrayDim[2]-1);
170     
171    // std::cerr << xmin << " " << xmax << "  " << ymin << " " << ymax << "  " << zmin << " " << zmax << "\n";
172    //loop over surrounding pixels.
173    int pos;
174    Voxel nvox;
175    std::vector<Voxel> morevox;
176    for(int x=xmin; x<=xmax; x++){
177      for(int y=ymin; y<=ymax; y++){
178        for(int z=zmin; z<=zmax; z++){
179
180          pos=x+y*this->itsArrayDim[0]+z*spatsize;
181          if( ((x!=xpt) || (y!=ypt) || (z!=zpt))
182              && this->itsFlagArray[pos]==AVAILABLE ) {
183
184            if(this->itsGrowthStats.isDetection(this->itsFluxArray[pos])){
185              this->itsFlagArray[pos]=DETECTED;
186              nvox.setXYZF(x,y,z,this->itsFluxArray[pos]);
187              newVoxels.push_back(nvox);
188              // std::cerr << x << " " << y << " " << z << " " << this->itsFluxArray[pos] << "  =  " << nvox << "\n";
189              morevox = this->growFromPixel(nvox);
190              if(morevox.size()>0)
191                for(size_t v=0;v<morevox.size();v++) newVoxels.push_back(morevox[v]);
192             
193            }
194          }
195
196        } //end of z loop
197      } // end of y loop
198    } // end of x loop
199
200    return newVoxels;
201
202  }
203
204  // void ObjectGrower::resetDetectionFlags()
205  // {
206  //   for(size_t i=0;i<itsFlagArray.size();i++)
207  //     if(itsFlagArray[i]==DETECTED) itsFlagArray[i] = AVAILABLE;
208  // }
209
210  // void ObjectGrower::growInwardsFromEdge()
211  // {
212   
213
214
215  // }
216
217}
Note: See TracBrowser for help on using the repository browser.