source: tags/release-1.1.7/src/PixelMap/Object3D.cc @ 1455

Last change on this file since 1455 was 536, checked in by MatthewWhiting, 15 years ago

Including the recent minor changes to 1.1.7.

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