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
RevLine 
[301]1// -----------------------------------------------------------------------
[528]2// Object3D.cc: Member functions for Object3D class.
[301]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// -----------------------------------------------------------------------
[244]28#include <iostream>
[393]29#include <duchamp/PixelMap/Voxel.hh>
30#include <duchamp/PixelMap/Scan.hh>
31#include <duchamp/PixelMap/Object2D.hh>
[528]32#include <duchamp/PixelMap/ChanMap.hh>
[393]33#include <duchamp/PixelMap/Object3D.hh>
[238]34#include <vector>
35
[252]36namespace PixelInfo
37{
[365]38  Object3D::Object3D()
39  {
40    this->numVox=0;
41  }
42
[270]43  Object3D::Object3D(const Object3D& o)
44  {
[365]45    operator=(o);
[252]46  }
47  //--------------------------------------------
48
[270]49  Object3D& Object3D::operator= (const Object3D& o)
50  {
51    if(this == &o) return *this;
[252]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;
[270]63    return *this;
[252]64  }
65  //--------------------------------------------
[243]66 
[252]67  bool Object3D::isInObject(long x, long y, long z)
68  {
69    bool returnval = false;
[536]70    uint mapCount = 0;
[252]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++;
[238]77    }
[252]78    return returnval;
[238]79  }
[252]80  //--------------------------------------------
[238]81
[252]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;
[536]86    uint mapCount = 0;
[252]87    while(!haveZ && mapCount < this->maplist.size()){
88      haveZ = haveZ || (z==this->maplist[mapCount++].itsZ);
89    }
[238]90
[252]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++;   
[246]116    }
[252]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;
[246]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;
[252]144      // don't need to do anything to zmin/zmax -- the z-value is
145      // already in the list
[246]146    }
147
[238]148  }
[252]149  //--------------------------------------------
[238]150
[472]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
[252]160  void Object3D::addChannel(ChanMap channel)
161  {
162    // first test to see if we have a chanmap of same z
163    bool haveZ = false;
[536]164    uint mapCount = 0;
[252]165    while( !haveZ && (mapCount < this->maplist.size()) ){
166      haveZ = haveZ || (channel.itsZ==this->maplist[mapCount].itsZ);
167      mapCount++;
168    }
[238]169
[252]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;
[246]176        this->xmin = channel.itsObject.xmin;
177        this->xmax = channel.itsObject.xmax;
[252]178        this->ySum = channel.itsObject.ySum;
[246]179        this->ymin = channel.itsObject.ymin;
180        this->ymax = channel.itsObject.ymax;
[252]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;
[246]202    }
[252]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++;
[244]208
[252]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;
[244]214
[252]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();   
[246]222
[252]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
[246]236
[252]237    }
238
[240]239  }
[252]240  //--------------------------------------------
[419]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
[252]249  long Object3D::getNumDistinctZ()
250  {
251    return this->maplist.size();
252  }
253  //--------------------------------------------
[238]254
[252]255  long Object3D::getSpatialSize()
256  {
257    Object2D spatialMap;
[536]258    for(uint i=0;i<this->maplist.size();i++){
[252]259      for(int s=0;s<this->maplist[i].itsObject.getNumScan();s++){
260        spatialMap.addScan(this->maplist[i].itsObject.getScan(s));
261      }
[238]262    }
[252]263    return spatialMap.getSize();
[238]264  }
[252]265  //--------------------------------------------
[238]266
[252]267  Object2D Object3D::getSpatialMap()
268  {
269    Object2D spatialMap = this->maplist[0].itsObject;
[536]270    for(uint i=1;i<this->maplist.size();i++){
[252]271      spatialMap = spatialMap + this->maplist[i].itsObject;
272    }
273    return spatialMap;
[238]274  }
[252]275  //--------------------------------------------
[238]276 
[252]277  void Object3D::calcParams()
278  {
279    this->xSum = 0;
280    this->ySum = 0;
281    this->zSum = 0;
[536]282    for(uint m=0;m<this->maplist.size();m++){
[238]283
[252]284      this->maplist[m].itsObject.calcParams();
[238]285
[252]286      if(m==0){
[243]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();
[252]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
[238]311    }
312
313  }
[252]314  //------------------------------------------------------
[238]315
[252]316  std::ostream& operator<< ( std::ostream& theStream, Object3D& obj)
317  {
[419]318    std::vector<ChanMap>::iterator map;
[420]319    for(map=obj.maplist.begin();map<obj.maplist.end();map++){
[419]320      Object2D tempObject = map->getObject();
[252]321      for(int s=0;s<tempObject.getNumScan();s++){
322        Scan tempscan = tempObject.getScan(s);
[419]323        theStream << tempscan << ", " << map->getZ() << "\n";
[244]324      }
[252]325    } 
326    theStream << "\n";
[270]327    return theStream;
[252]328  }
329  //--------------------------------------------
[241]330
[252]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;
[536]336    for(uint m=0;m<this->maplist.size();m++)
[252]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++)
[241]343              {
[252]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();
[241]352              }
[252]353          }
354        count1+=this->maplist[m].itsObject.getSize();     
355      }
[270]356    return returnVox;
[252]357  }
358  //--------------------------------------------------------------------
359
360  std::vector<Voxel> Object3D::getPixelSet()
361  {
362    std::vector<Voxel> voxList(this->numVox);
363    long count = 0;
[536]364    for(uint m=0;m<this->maplist.size();m++){
[252]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++;
[241]373        }
[252]374      }
[241]375    }
[252]376    return voxList;
[243]377
378  }
379
[399]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)
[419]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  }
[399]401
[243]402}
Note: See TracBrowser for help on using the repository browser.