source: tags/release-1.1.2/src/PixelMap/Object3D.cc @ 1441

Last change on this file since 1441 was 393, checked in by MatthewWhiting, 17 years ago

Fixed up headers for trunk as well.

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