source: tags/release-1.1/src/PixelMap/Object3D.cc @ 1391

Last change on this file since 1391 was 301, checked in by Matthew Whiting, 17 years ago

Mostly adding the distribution text to the start of files, with a few additional comments added too.

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