source: branches/pixelmap-refactor-branch/src/PixelMap/Object3D.cc @ 1441

Last change on this file since 1441 was 569, checked in by MatthewWhiting, 15 years ago

Improving the updateDetectMap functions and the default values for Detection. Otherwise just cleaning up.

File size: 11.3 KB
Line 
1// -----------------------------------------------------------------------
2// Object3D.cc: Member functions for Object3D class.
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 <duchamp/PixelMap/Voxel.hh>
30#include <duchamp/PixelMap/Scan.hh>
31#include <duchamp/PixelMap/Object2D.hh>
32#include <duchamp/PixelMap/Object3D.hh>
33#include <vector>
34#include <map>
35
36namespace PixelInfo
37{
38  Object3D::Object3D()
39  {
40    this->numVox=0;
41    this->xSum = 0;
42    this->ySum = 0;
43    this->zSum = 0;
44    this->xmin = this->xmax = this->ymin = this->ymax = this->zmin = this->zmax = -1;
45  }
46  //--------------------------------------------
47
48  Object3D::Object3D(const Object3D& o)
49  {
50    operator=(o);
51  }
52  //--------------------------------------------
53
54  Object3D& Object3D::operator= (const Object3D& o)
55  {
56    if(this == &o) return *this;
57    this->chanlist = o.chanlist;
58    this->numVox  = o.numVox;
59    this->xSum    = o.xSum;
60    this->ySum    = o.ySum;
61    this->zSum    = o.zSum;
62    this->xmin    = o.xmin;
63    this->ymin    = o.ymin;
64    this->zmin    = o.zmin;
65    this->xmax    = o.xmax;
66    this->ymax    = o.ymax;
67    this->zmax    = o.zmax;
68    return *this;
69  }
70  //--------------------------------------------
71
72  Object3D operator+ (Object3D lhs, Object3D rhs)
73  {
74    Object3D output = lhs;
75    for(std::map<long, Object2D>::iterator it = rhs.chanlist.begin(); it!=rhs.chanlist.end();it++)
76      output.addChannel(it->first, it->second);
77    return output;
78  }
79
80  //--------------------------------------------
81  float Object3D::getXaverage()
82  {
83    if(numVox>0) return xSum/float(numVox);
84    else return 0.;
85  }
86  //--------------------------------------------
87
88  float Object3D::getYaverage()
89  {
90    if(numVox>0) return ySum/float(numVox);
91    else return 0.;
92  }
93  //--------------------------------------------
94
95  float Object3D::getZaverage()
96  {
97    if(numVox>0) return zSum/float(numVox);
98    else return 0.;
99  }
100  //--------------------------------------------
101 
102  bool Object3D::isInObject(long x, long y, long z)
103  {
104    std::map<long,Object2D>::iterator it=this->chanlist.begin();
105    while(it!=this->chanlist.end() && it->first!=z) it++;
106
107    if(it==this->chanlist.end()) return false;
108    else                         return it->second.isInObject(x,y);
109  }
110  //--------------------------------------------
111
112  void Object3D::addPixel(long x, long y, long z)
113  {
114 
115    std::map<long,Object2D>::iterator it=this->chanlist.begin();
116    while(it!=this->chanlist.end() && it->first!=z) it++;
117
118    if(it==this->chanlist.end()){ //new channel
119      Object2D obj;
120      obj.addPixel(x,y);
121      chanlist.insert( std::pair<int,Object2D>(z,obj) );
122      // update the centres, min & max, as well as the number of voxels
123      if(this->numVox==0){
124        this->xSum = this->xmin = this->xmax = x;
125        this->ySum = this->ymin = this->ymax = y;
126        this->zSum = this->zmin = this->zmax = z;
127      }
128      else{
129        this->xSum += x;
130        this->ySum += y;
131        this->zSum += z;
132        if(x<this->xmin) this->xmin = x;
133        if(x>this->xmax) this->xmax = x;
134        if(y<this->ymin) this->ymin = y;
135        if(y>this->ymax) this->ymax = y;
136        // since we've ordered the maplist, the min & max z fall out naturally
137        this->zmin = this->chanlist.begin()->first;
138        this->zmax = this->chanlist.rbegin()->first;
139      }
140      this->numVox++;   
141    }
142    else{ // existing channel
143      // This method deals with the case of a new pixel being added AND
144      // with the new pixel already existing in the Object2D
145 
146      // Remove that channel's information from the Object's information
147      long oldChanSize = it->second.numPix;
148      this->xSum -= it->second.xSum;
149      this->ySum -= it->second.ySum;
150      this->zSum -= z*oldChanSize;
151
152      // Add the pixel
153      it->second.addPixel(x,y);
154   
155      // and update the information...
156     long newChanSize = it->second.numPix;
157   
158      this->numVox += (newChanSize - oldChanSize);
159      this->xSum += it->second.xSum;
160      this->ySum += it->second.ySum;
161      this->zSum += z*newChanSize;
162      if(x<this->xmin) this->xmin = x;
163      if(x>this->xmax) this->xmax = x;
164      if(y<this->ymin) this->ymin = y;
165      if(y>this->ymax) this->ymax = y;
166      // don't need to do anything to zmin/zmax -- the z-value is
167      // already in the list
168    }
169
170  }
171  //--------------------------------------------
172
173  void Object3D::addScan(Scan s, long z)
174  {
175    long y=s.getY();
176    for(int x=s.getX(); x<=s.getXmax(); x++)
177      this->addPixel(x,y,z);
178  }
179
180  //--------------------------------------------
181
182  void Object3D::addChannel(const long &z, Object2D &obj)
183  {
184
185    std::map<long,Object2D>::iterator it=this->chanlist.begin();
186    while(it!=this->chanlist.end() && it->first!=z) it++;
187
188    if(it == this->chanlist.end()){
189      this->chanlist.insert(std::pair<long,Object2D>(z,obj));
190      if(this->numVox == 0){
191        this->xmin = obj.xmin;
192        this->xmax = obj.xmax;
193        this->ymin = obj.ymin;
194        this->ymax = obj.ymax;
195        this->zmin = this->zmax = z;
196        this->xSum = obj.xSum;
197        this->ySum = obj.ySum;
198        this->zSum = z * obj.getSize();
199      }
200      else{
201        if(obj.xmin<this->xmin) this->xmin = obj.xmin;
202        if(obj.xmax>this->xmax) this->xmax = obj.xmax;
203        if(obj.ymin<this->ymin) this->ymin = obj.ymin;
204        if(obj.ymax>this->ymax) this->ymax = obj.ymax;
205        if(z<this->zmin) this->zmin = z;
206        if(z>this->zmax) this->zmax = z;
207        this->xSum += obj.xSum;
208        this->ySum += obj.ySum;
209        this->zSum += z * obj.getSize();
210      }
211      this->numVox += obj.getSize();
212    }
213    else{
214      this->xSum -= it->second.xSum;
215      this->ySum -= it->second.ySum;
216      this->zSum -= z*it->second.getSize();
217      this->numVox -= it->second.getSize();
218      it->second += obj;
219      this->xSum += it->second.xSum;
220      this->ySum += it->second.ySum;
221      this->zSum += z*it->second.getSize();
222      this->numVox += it->second.getSize();
223      if(obj.xmin<this->xmin) this->xmin = obj.xmin;
224      if(obj.xmax>this->xmax) this->xmax = obj.xmax;
225      if(obj.ymin<this->ymin) this->ymin = obj.ymin;
226      if(obj.ymax>this->ymax) this->ymax = obj.ymax;
227    }
228  }
229
230  //--------------------------------------------
231
232  long Object3D::getSpatialSize()
233  {
234    Object2D spatialMap = this->getSpatialMap();
235    return spatialMap.getSize();
236  }
237  //--------------------------------------------
238
239  Object2D Object3D::getSpatialMap()
240  {
241    Object2D spatialMap;
242    for(std::map<long, Object2D>::iterator it = this->chanlist.begin();
243        it!=this->chanlist.end();it++){
244      spatialMap = spatialMap + it->second;
245    }
246    return spatialMap;
247  }
248  //--------------------------------------------
249 
250  void Object3D::calcParams()
251  {
252    this->xSum = 0;
253    this->ySum = 0;
254    this->zSum = 0;
255    this->numVox = 0;
256
257    this->zmin = this->chanlist.begin()->first;
258    this->zmax = this->chanlist.rbegin()->first;
259    for(std::map<long, Object2D>::iterator it = this->chanlist.begin();
260        it!=this->chanlist.end();it++){
261
262      it->second.calcParams();
263
264      if(it==this->chanlist.begin()){
265        this->xmin = it->second.getXmin();
266        this->xmax = it->second.getXmax();
267        this->ymin = it->second.getYmin();
268        this->ymax = it->second.getYmax();
269      }
270      else{
271        if(it->second.xmin<this->xmin) this->xmin = it->second.xmin;
272        if(it->second.xmax>this->xmax) this->xmax = it->second.xmax;
273        if(it->second.ymin<this->ymin) this->ymin = it->second.ymin;
274        if(it->second.ymax>this->ymax) this->ymax = it->second.ymax;
275      }
276
277      this->xSum += it->second.xSum;
278      this->ySum += it->second.ySum;
279      this->zSum += it->first * it->second.getSize();
280      this->numVox += it->second.getSize();
281
282    }
283
284  }
285  //------------------------------------------------------
286
287  std::ostream& operator<< ( std::ostream& theStream, Object3D& obj)
288  {
289    for(std::map<long, Object2D>::iterator it = obj.chanlist.begin();
290        it!=obj.chanlist.end();it++){
291      for(int s=0;s<it->second.getNumScan();s++){
292        Scan tempscan = it->second.getScan(s);
293        theStream << tempscan << ", " << it->first << "\n";
294      }
295    } 
296    theStream << "\n";
297    return theStream;
298  }
299  //--------------------------------------------
300
301  std::vector<Voxel> Object3D::getPixelSet()
302  {
303    std::vector<Voxel> voxList(this->numVox);
304    long count = 0;
305    for(std::map<long, Object2D>::iterator it = this->chanlist.begin();
306        it!=this->chanlist.end();it++){
307      long z = it->first;
308      for(int s=0;s<it->second.getNumScan();s++){
309        Scan scn = it->second.getScan(s);
310        long y = scn.getY();
311        for(long x=scn.getX(); x<=scn.getXmax(); x++){
312          voxList[count].setXYZF(x,y,z,0);
313          count++;
314        }
315      }
316    }
317    return voxList;
318
319  }
320
321  //--------------------------------------------------------------------
322
323  std::vector<long> Object3D::getChannelList()
324  {
325
326    std::vector<long> chanlist;
327    for(std::map<long, Object2D>::iterator it = this->chanlist.begin();
328        it != this->chanlist.end(); it++){
329      chanlist.push_back(it->first);
330    }
331    return chanlist;
332  }
333
334  //--------------------------------------------------------------------
335
336  Object2D Object3D::getChanMap(long z)
337  {
338    Object2D obj;
339    std::map<long,Object2D>::iterator it=this->chanlist.begin();
340    while(it!=this->chanlist.end() && it->first!=z) it++;
341
342    if(it==this->chanlist.end()) obj = Object2D();
343    else obj = it->second;
344
345    return obj;
346  }
347
348  //--------------------------------------------------------------------
349
350  int Object3D::getMaxAdjacentChannels()
351  {
352    int maxnumchan=0;
353    int zcurrent, zprevious,zcount=0;
354    std::map<long, Object2D>::iterator it = this->chanlist.begin();
355    zcurrent = it->first;
356    zcount++;
357    it++;
358    for(; it!=this->chanlist.end();it++)
359      {
360        zprevious = zcurrent;
361        zcurrent = it->first;
362        if(zcurrent-zprevious>1){
363          maxnumchan = std::max(maxnumchan, zcount);
364          zcount=1;
365        }
366        else zcount++;
367      }
368    maxnumchan = std::max(maxnumchan,zcount);
369    return maxnumchan;
370  }
371
372  //--------------------------------------------------------------------
373
374  void Object3D::addOffsets(long xoff, long yoff, long zoff)
375  {
376    for(std::map<long, Object2D>::iterator it = this->chanlist.begin(); it!=this->chanlist.end();it++)
377      it->second.addOffsets(xoff,yoff);
378    if(this->numVox>0){
379      this->xSum += xoff*numVox;
380      this->xmin += xoff; this->xmax += xoff;
381      this->ySum += yoff*numVox;
382      this->ymin += yoff; this->ymax += yoff;
383      this->zSum += zoff*numVox;
384      this->zmin += zoff; this->zmax += zoff;
385    }
386  }
387
388}
Note: See TracBrowser for help on using the repository browser.