source: trunk/src/PixelMap/Object3D.cc @ 416

Last change on this file since 416 was 416, checked in by MatthewWhiting, 16 years ago
  • Fixed headerIO.cc's reading in of beam information
  • Minor fixes to pixelmap functions
  • Making spectralSelection compile, with Devel headers in the duchamp/ directory
File size: 13.4 KB
RevLine 
[301]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// -----------------------------------------------------------------------
[244]28#include <iostream>
[393]29#include <duchamp/PixelMap/Voxel.hh>
30#include <duchamp/PixelMap/Scan.hh>
31#include <duchamp/PixelMap/Object2D.hh>
32#include <duchamp/PixelMap/Object3D.hh>
[238]33#include <vector>
34
[252]35namespace PixelInfo
36{
[243]37
[365]38  ChanMap::ChanMap()
39  {
40    this->itsZ = -1;
41  }
42
[252]43  ChanMap::ChanMap(const ChanMap& m){
[365]44    operator=(m);
[252]45  }
[243]46
[270]47  ChanMap& ChanMap::operator= (const ChanMap& m)
48  {
49    if(this == &m) return *this;
[252]50    this->itsZ=m.itsZ;
51    this->itsObject=m.itsObject;
[270]52    return *this;
[252]53  }
54  //--------------------------------------------
55  //============================================
56  //--------------------------------------------
[243]57
[365]58  Object3D::Object3D()
59  {
60    this->numVox=0;
61  }
62
[270]63  Object3D::Object3D(const Object3D& o)
64  {
[365]65    operator=(o);
[252]66  }
67  //--------------------------------------------
68
[270]69  Object3D& Object3D::operator= (const Object3D& o)
70  {
71    if(this == &o) return *this;
[252]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;
[270]83    return *this;
[252]84  }
85  //--------------------------------------------
[243]86 
[252]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++;
[238]97    }
[252]98    return returnval;
[238]99  }
[252]100  //--------------------------------------------
[238]101
[252]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    }
[238]110
[252]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++;   
[246]136    }
[252]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;
[246]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;
[252]164      // don't need to do anything to zmin/zmax -- the z-value is
165      // already in the list
[246]166    }
167
[238]168  }
[252]169  //--------------------------------------------
[238]170
[252]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    }
[238]180
[252]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;
[246]187        this->xmin = channel.itsObject.xmin;
188        this->xmax = channel.itsObject.xmax;
[252]189        this->ySum = channel.itsObject.ySum;
[246]190        this->ymin = channel.itsObject.ymin;
191        this->ymax = channel.itsObject.ymax;
[252]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;
[246]213    }
[252]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++;
[244]219
[252]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;
[244]225
[252]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();   
[246]233
[252]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
[246]247
[252]248    }
249
[240]250  }
[252]251  //--------------------------------------------
[240]252
[252]253  // long Object3D::getSize()
254  // {
255  //   long size=0;
256  //   for(int i=0;i<this->maplist.size();i++)
257  //     size+=this->maplist[i].itsObject.getSize();
258  //   return size;
259  // }
260  //--------------------------------------------
[240]261
[252]262  long Object3D::getNumDistinctZ()
263  {
264    return this->maplist.size();
265  }
266  //--------------------------------------------
[238]267
[252]268  long Object3D::getSpatialSize()
269  {
270    Object2D spatialMap;
271    for(int i=0;i<this->maplist.size();i++){
272      for(int s=0;s<this->maplist[i].itsObject.getNumScan();s++){
273        spatialMap.addScan(this->maplist[i].itsObject.getScan(s));
274      }
[238]275    }
[252]276    return spatialMap.getSize();
[238]277  }
[252]278  //--------------------------------------------
[238]279
[252]280  Object2D Object3D::getSpatialMap()
281  {
282    Object2D spatialMap = this->maplist[0].itsObject;
283    for(int i=1;i<this->maplist.size();i++){
284      spatialMap = spatialMap + this->maplist[i].itsObject;
285    }
286    return spatialMap;
[238]287  }
[252]288  //--------------------------------------------
[238]289 
[252]290  void Object3D::calcParams()
291  {
292    this->xSum = 0;
293    this->ySum = 0;
294    this->zSum = 0;
295    for(int m=0;m<this->maplist.size();m++){
[238]296
[252]297      this->maplist[m].itsObject.calcParams();
[238]298
[252]299      if(m==0){
[243]300        this->xmin = this->maplist[m].itsObject.getXmin();
301        this->xmax = this->maplist[m].itsObject.getXmax();
302        this->ymin = this->maplist[m].itsObject.getYmin();
303        this->ymax = this->maplist[m].itsObject.getYmax();
[252]304        this->zmin = this->zmax = this->maplist[m].itsZ;
305      }
306      else{
307        if(this->xmin>this->maplist[m].itsObject.getXmin())
308          this->xmin = this->maplist[m].itsObject.getXmin();
309        if(this->xmax<this->maplist[m].itsObject.getXmax())
310          this->xmax = this->maplist[m].itsObject.getXmax();
311        if(this->ymin>this->maplist[m].itsObject.getYmin())
312          this->ymin = this->maplist[m].itsObject.getYmin();
313        if(this->ymax<this->maplist[m].itsObject.getYmax())
314          this->ymax = this->maplist[m].itsObject.getYmax();
315        if(this->zmin>this->maplist[m].itsZ) this->zmin = this->maplist[m].itsZ;
316        if(this->zmax<this->maplist[m].itsZ) this->zmax = this->maplist[m].itsZ;
317      }
318
319      long size = this->maplist[m].itsObject.getSize();
320      this->xSum += this->maplist[m].itsObject.xSum;
321      this->ySum += this->maplist[m].itsObject.ySum;
322      this->zSum += this->maplist[m].itsZ * size;
323
[238]324    }
325
326  }
[252]327  //------------------------------------------------------
[238]328
[252]329  std::ostream& operator<< ( std::ostream& theStream, Object3D& obj)
330  {
331    for(int m=0;m<obj.maplist.size();m++){
332      Object2D tempObject = obj.maplist[m].getObject();
333      for(int s=0;s<tempObject.getNumScan();s++){
334        Scan tempscan = tempObject.getScan(s);
335        //      theStream << obj.maplist[m].getZ() << " " << tempscan << "\n";
336        for(int x=tempscan.getX();x<=tempscan.getXmax();x++){
337          theStream << x                     << " "
338                    << tempscan.getY()       << " "
339                    << obj.maplist[m].getZ() << "\n";
340        }
[244]341      }
[252]342    } 
343    theStream << "\n";
[270]344    return theStream;
[252]345  }
346  //--------------------------------------------
[241]347
[252]348  Voxel Object3D::getPixel(int pixNum)
349  {
350    Voxel returnVox(-1,-1,-1,0.);
351    if((pixNum<0)||(pixNum>=this->getSize())) return returnVox;
352    int count1=0;
353    for(int m=0;m<this->maplist.size();m++)
354      {
355        if(pixNum-count1<this->maplist[m].itsObject.getSize())
356          {
357            returnVox.setZ(this->maplist[m].getZ());
358            int count2=0;
359            for(int s=0;s<this->maplist[m].getNumScan();s++)
[241]360              {
[252]361                if(pixNum-count1-count2<this->maplist[m].getScan(s).getXlen())
362                  {
363                    returnVox.setY(this->maplist[m].getScan(s).getY());
364                    returnVox.setX(this->maplist[m].getScan(s).getX()
365                                   + pixNum - count1 - count2);
366                    return returnVox;
367                  }
368                count2+=this->maplist[m].getScan(s).getXlen();
[241]369              }
[252]370          }
371        count1+=this->maplist[m].itsObject.getSize();     
372      }
[270]373    return returnVox;
[252]374  }
375  //--------------------------------------------------------------------
376
377  std::vector<Voxel> Object3D::getPixelSet()
378  {
379    //   long size = this->getSize();
380    std::vector<Voxel> voxList(this->numVox);
381    long count = 0;
382    for(int m=0;m<this->maplist.size();m++){
383      Object2D obj = this->maplist[m].itsObject;
384      long z = this->maplist[m].itsZ;
385      for(int s=0;s<obj.getNumScan();s++){
386        Scan scn = obj.getScan(s);
387        long y = scn.getY();
388        for(long x=scn.getX(); x<=scn.getXmax(); x++){
389          voxList[count].setXYZF(x,y,z,0);
390          count++;
[241]391        }
[252]392      }
[241]393    }
[252]394    return voxList;
[243]395
396  }
397
[399]398  //--------------------------------------------------------------------
399
400  void ChanMap::addOffsets(long xoff, long yoff, long zoff)
401  {
402    this->itsZ += zoff;
403    this->itsObject.addOffsets(xoff,yoff);
404  }
405 
406  //--------------------------------------------------------------------
407
408  void Object3D::addOffsets(long xoff, long yoff, long zoff)
409    {
410      for(unsigned int i=0;i<this->maplist.size();i++)
411        this->maplist[i].addOffsets(xoff,yoff,zoff);
412      this->xSum += xoff*numVox;
413      this->xmin += xoff; xmax += xoff;
414      this->ySum += yoff*numVox;
415      this->ymin += yoff; ymax += yoff;
416      this->zSum += zoff*numVox;
417      this->zmin += zoff; zmax += zoff;
418    };
419
420
421
[243]422}
Note: See TracBrowser for help on using the repository browser.