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

Last change on this file since 1441 was 420, checked in by MatthewWhiting, 16 years ago
  • Fixed a bug from the "fix" of setupColumns -- the fluxes were not being calculated properly, so have defined a general call to calcObjectFluxes().
  • Fixed ticket #26, with flagXoutput set to false if pgplot is not compiled.
  • Other minor fixes.
File size: 13.5 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  void Object3D::order(){
254    std::vector<ChanMap>::iterator map;
255    for(map=maplist.begin();map<maplist.end();map++) map->itsObject.order();
256    std::stable_sort(maplist.begin(),maplist.end());
257  }
258 
259
260  //--------------------------------------------
261
262  // long Object3D::getSize()
263  // {
264  //   long size=0;
265  //   for(int i=0;i<this->maplist.size();i++)
266  //     size+=this->maplist[i].itsObject.getSize();
267  //   return size;
268  // }
269  //--------------------------------------------
270
271  long Object3D::getNumDistinctZ()
272  {
273    return this->maplist.size();
274  }
275  //--------------------------------------------
276
277  long Object3D::getSpatialSize()
278  {
279    Object2D spatialMap;
280    for(int i=0;i<this->maplist.size();i++){
281      for(int s=0;s<this->maplist[i].itsObject.getNumScan();s++){
282        spatialMap.addScan(this->maplist[i].itsObject.getScan(s));
283      }
284    }
285    return spatialMap.getSize();
286  }
287  //--------------------------------------------
288
289  Object2D Object3D::getSpatialMap()
290  {
291    Object2D spatialMap = this->maplist[0].itsObject;
292    for(int i=1;i<this->maplist.size();i++){
293      spatialMap = spatialMap + this->maplist[i].itsObject;
294    }
295    return spatialMap;
296  }
297  //--------------------------------------------
298 
299  void Object3D::calcParams()
300  {
301    this->xSum = 0;
302    this->ySum = 0;
303    this->zSum = 0;
304    for(int m=0;m<this->maplist.size();m++){
305
306      this->maplist[m].itsObject.calcParams();
307
308      if(m==0){
309        this->xmin = this->maplist[m].itsObject.getXmin();
310        this->xmax = this->maplist[m].itsObject.getXmax();
311        this->ymin = this->maplist[m].itsObject.getYmin();
312        this->ymax = this->maplist[m].itsObject.getYmax();
313        this->zmin = this->zmax = this->maplist[m].itsZ;
314      }
315      else{
316        if(this->xmin>this->maplist[m].itsObject.getXmin())
317          this->xmin = this->maplist[m].itsObject.getXmin();
318        if(this->xmax<this->maplist[m].itsObject.getXmax())
319          this->xmax = this->maplist[m].itsObject.getXmax();
320        if(this->ymin>this->maplist[m].itsObject.getYmin())
321          this->ymin = this->maplist[m].itsObject.getYmin();
322        if(this->ymax<this->maplist[m].itsObject.getYmax())
323          this->ymax = this->maplist[m].itsObject.getYmax();
324        if(this->zmin>this->maplist[m].itsZ) this->zmin = this->maplist[m].itsZ;
325        if(this->zmax<this->maplist[m].itsZ) this->zmax = this->maplist[m].itsZ;
326      }
327
328      long size = this->maplist[m].itsObject.getSize();
329      this->xSum += this->maplist[m].itsObject.xSum;
330      this->ySum += this->maplist[m].itsObject.ySum;
331      this->zSum += this->maplist[m].itsZ * size;
332
333    }
334
335  }
336  //------------------------------------------------------
337
338  std::ostream& operator<< ( std::ostream& theStream, Object3D& obj)
339  {
340    std::vector<ChanMap>::iterator map;
341    for(map=obj.maplist.begin();map<obj.maplist.end();map++){
342      Object2D tempObject = map->getObject();
343      for(int s=0;s<tempObject.getNumScan();s++){
344        Scan tempscan = tempObject.getScan(s);
345        theStream << tempscan << ", " << map->getZ() << "\n";
346      }
347    } 
348    theStream << "\n";
349    return theStream;
350  }
351  //--------------------------------------------
352
353  Voxel Object3D::getPixel(int pixNum)
354  {
355    Voxel returnVox(-1,-1,-1,0.);
356    if((pixNum<0)||(pixNum>=this->getSize())) return returnVox;
357    int count1=0;
358    for(int m=0;m<this->maplist.size();m++)
359      {
360        if(pixNum-count1<this->maplist[m].itsObject.getSize())
361          {
362            returnVox.setZ(this->maplist[m].getZ());
363            int count2=0;
364            for(int s=0;s<this->maplist[m].getNumScan();s++)
365              {
366                if(pixNum-count1-count2<this->maplist[m].getScan(s).getXlen())
367                  {
368                    returnVox.setY(this->maplist[m].getScan(s).getY());
369                    returnVox.setX(this->maplist[m].getScan(s).getX()
370                                   + pixNum - count1 - count2);
371                    return returnVox;
372                  }
373                count2+=this->maplist[m].getScan(s).getXlen();
374              }
375          }
376        count1+=this->maplist[m].itsObject.getSize();     
377      }
378    return returnVox;
379  }
380  //--------------------------------------------------------------------
381
382  std::vector<Voxel> Object3D::getPixelSet()
383  {
384    //   long size = this->getSize();
385    std::vector<Voxel> voxList(this->numVox);
386    long count = 0;
387    for(int m=0;m<this->maplist.size();m++){
388      Object2D obj = this->maplist[m].itsObject;
389      long z = this->maplist[m].itsZ;
390      for(int s=0;s<obj.getNumScan();s++){
391        Scan scn = obj.getScan(s);
392        long y = scn.getY();
393        for(long x=scn.getX(); x<=scn.getXmax(); x++){
394          voxList[count].setXYZF(x,y,z,0);
395          count++;
396        }
397      }
398    }
399    return voxList;
400
401  }
402
403  //--------------------------------------------------------------------
404
405  void ChanMap::addOffsets(long xoff, long yoff, long zoff)
406  {
407    this->itsZ += zoff;
408    this->itsObject.addOffsets(xoff,yoff);
409  }
410 
411  //--------------------------------------------------------------------
412
413  void Object3D::addOffsets(long xoff, long yoff, long zoff)
414  {
415    for(unsigned int i=0;i<this->maplist.size();i++)
416      this->maplist[i].addOffsets(xoff,yoff,zoff);
417    this->xSum += xoff*numVox;
418    this->xmin += xoff; xmax += xoff;
419    this->ySum += yoff*numVox;
420    this->ymin += yoff; ymax += yoff;
421    this->zSum += zoff*numVox;
422    this->zmin += zoff; zmax += zoff;
423  }
424
425}
Note: See TracBrowser for help on using the repository browser.