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

Last change on this file since 533 was 528, checked in by MatthewWhiting, 15 years ago

Changing the documentation comments to match the askapsoft style. Also have split ChanMap? and Object3D into separate files.

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    int 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    int 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    int 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(int 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(int 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(int 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(int 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(int 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.