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

Last change on this file 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.