source: trunk/src/Cubes/cubes.cc @ 155

Last change on this file since 155 was 153, checked in by Matthew Whiting, 18 years ago

Corrected a bug in the call to Cube::setupColumns() -- the object ID had not
been set when the logfile is written to, so the obj# column was oversized.
Now fixed. Verification files also updated.

File size: 21.9 KB
Line 
1#include <unistd.h>
2#include <iostream>
3#include <iomanip>
4#include <vector>
5#include <string>
6
7#include <wcs.h>
8
9#include <duchamp.hh>
10#include <param.hh>
11#include <Cubes/cubes.hh>
12#include <Detection/detection.hh>
13#include <Detection/columns.hh>
14#include <Utils/utils.hh>
15#include <Utils/mycpgplot.hh>
16using std::endl;
17using namespace Column;
18using namespace mycpgplot;
19
20/****************************************************************/
21///////////////////////////////////////////////////
22//// Functions for DataArray class:
23///////////////////////////////////////////////////
24
25DataArray::DataArray(short int nDim, long size){
26
27  if(size<0)
28    duchampError("DataArray(nDim,size)",
29                 "Negative size -- could not define DataArray");
30  else if(nDim<0)
31    duchampError("DataArray(nDim,size)",
32                 "Negative number of dimensions -- could not define DataArray");
33  else {
34    if(size>0) this->array = new float[size];
35    this->numPixels = size;
36    if(nDim>0) this->axisDim = new long[nDim];
37    this->numDim = nDim;
38  }
39}
40
41DataArray::DataArray(short int nDim, long *dimensions){
42  if(nDim<0)
43    duchampError("DataArray(nDim,dimArray)",
44                 "Negative number of dimensions -- could not define DataArray");
45  else {
46    int size = dimensions[0];
47    for(int i=1;i<nDim;i++) size *= dimensions[i];
48    if(size<0)
49      duchampError("DataArray(nDim,dimArray)",
50                   "Negative size -- could not define DataArray");
51    else{
52      this->numPixels = size;
53      if(size>0){
54        this->array = new float[size];
55      }
56      this->numDim=nDim;
57      if(nDim>0) this->axisDim = new long[nDim];
58      for(int i=0;i<nDim;i++) this->axisDim[i] = dimensions[i];
59    }
60  }
61}
62
63DataArray::~DataArray()
64{
65  delete [] array;
66  delete [] axisDim;
67  objectList.clear();
68}
69
70void DataArray::getDimArray(long *output){
71  for(int i=0;i<this->numDim;i++) output[i] = this->axisDim[i];
72}
73
74void DataArray::getArray(float *output){
75  for(int i=0;i<this->numPixels;i++) output[i] = this->array[i];
76}
77
78void DataArray::saveArray(float *input, long size){
79  if(size != this->numPixels)
80    duchampError("DataArray::saveArray",
81                 "Input array different size to existing array. Cannot save.");
82  else {
83    if(this->numPixels>0) delete [] this->array;
84    this->numPixels = size;
85    this->array = new float[size];
86    for(int i=0;i<size;i++) this->array[i] = input[i];
87  }
88}
89
90void DataArray::getDim(long &x, long &y, long &z){
91  if(numDim>0) x=axisDim[0];
92  else x=0;
93  if(numDim>1) y=axisDim[1];
94  else y=0;
95  if(numDim>2) z=axisDim[2];
96  else z=0;
97}
98
99void DataArray::addObject(Detection object){
100  // adds a single detection to the object list
101  // objectList is a vector, so just use push_back()
102  this->objectList.push_back(object);
103}
104
105void DataArray::addObjectList(vector <Detection> newlist) {
106  for(int i=0;i<newlist.size();i++) this->objectList.push_back(newlist[i]);
107}
108
109void DataArray::addObjectOffsets(){
110  for(int i=0;i<this->objectList.size();i++){
111    for(int p=0;p<this->objectList[i].getSize();p++){
112      this->objectList[i].setX(p,this->objectList[i].getX(p)+this->par.getXOffset());
113      this->objectList[i].setY(p,this->objectList[i].getY(p)+this->par.getYOffset());
114      this->objectList[i].setZ(p,this->objectList[i].getZ(p)+this->par.getZOffset());
115    }
116  }
117}
118
119
120std::ostream& operator<< ( std::ostream& theStream, DataArray &array)
121{
122  for(int i=0;i<array.numDim;i++){
123    if(i>0) theStream<<"x";
124    theStream<<array.axisDim[i];
125  }
126  theStream<<endl;
127  theStream<<array.objectList.size()<<" detections:"<<endl<<"--------------\n";
128  for(int i=0;i<array.objectList.size();i++){
129    theStream << "Detection #" << array.objectList[i].getID()<<endl;
130    Detection *obj = new Detection;
131    *obj = array.objectList[i];
132    for(int j=0;j<obj->getSize();j++){
133      obj->setX(j,obj->getX(j)+obj->getXOffset());
134      obj->setY(j,obj->getY(j)+obj->getYOffset());
135      obj->setZ(j,obj->getZ(j)+obj->getZOffset());
136    }
137    theStream<<*obj;
138    delete obj;
139  }
140  theStream<<"--------------\n";
141}
142
143/****************************************************************/
144/////////////////////////////////////////////////////////////
145//// Functions for Image class
146/////////////////////////////////////////////////////////////
147
148Image::Image(long size){
149  // need error handling in case size<0 !!!
150  if(size<0)
151    duchampError("Image(size)","Negative size -- could not define Image");
152  else{
153    if(size>0){
154      this->array = new float[size];
155      this->pValue = new float[size];
156      this->mask = new short int[size];
157    }
158    this->numPixels = size;
159    this->axisDim = new long[2];
160    this->numDim = 2;
161  }
162}
163
164Image::Image(long *dimensions){
165  int size = dimensions[0] * dimensions[1];
166  if(size<0)
167    duchampError("Image(dimArray)","Negative size -- could not define Image");
168  else{
169    this->numPixels = size;
170    if(size>0){
171      this->array = new float[size];
172      this->pValue = new float[size];
173      this->mask = new short int[size];
174    }
175    this->numDim=2;
176    this->axisDim = new long[2];
177    for(int i=0;i<2;i++) this->axisDim[i] = dimensions[i];
178    for(int i=0;i<size;i++) this->mask[i] = 0;
179  }
180}
181
182Image::~Image(){
183  if(this->numPixels > 0){
184    delete [] this->pValue;
185    delete [] this->mask;
186  }
187}
188
189
190void Image::saveArray(float *input, long size){
191  if(size != this->numPixels)
192    duchampError("Image::saveArray",
193                 "Input array different size to existing array. Cannot save.");
194  else {
195    if(this->numPixels>0){
196      delete [] array;
197      delete [] pValue;
198      delete [] mask;
199    }
200    this->numPixels = size;
201    if(this->numPixels>0){
202      this->array = new float[size];
203      this->pValue = new float[size];
204      this->mask = new short int[size];
205    }
206    for(int i=0;i<size;i++) this->array[i] = input[i];
207    for(int i=0;i<size;i++) this->mask[i] = 0;
208  }
209}
210
211void Image::maskObject(Detection &object)
212{
213  /**
214   * Image::maskObject(Detection &)
215   *  A function that increments the mask for each pixel of the detection.
216   */
217  for(long i=0;i<object.getSize();i++){
218    this->setMaskValue(object.getX(i),object.getY(i),1);
219  }
220}
221
222void Image::extractSpectrum(float *Array, long *dim, long pixel)
223{
224  /**
225   * Image::extractSpectrum(float *, long *, int)
226   *  A function to extract a 1-D spectrum from a 3-D array.
227   *  The array is assumed to be 3-D with the third dimension the spectral one.
228   *  The dimensions of the array are in the dim[] array.
229   *  The spectrum extracted is the one lying in the spatial pixel referenced
230   *    by the third argument.
231   */
232  float *spec = new float[dim[2]];
233  for(int z=0;z<dim[2];z++) spec[z] = Array[z*dim[0]*dim[1] + pixel];
234  this->saveArray(spec,dim[2]);
235  delete [] spec;
236}
237
238void Image::extractSpectrum(Cube &cube, long pixel)
239{
240  /**
241   * Image::extractSpectrum(Cube &, int)
242   *  A function to extract a 1-D spectrum from a Cube class
243   *  The spectrum extracted is the one lying in the spatial pixel referenced
244   *    by the second argument.
245   */
246  long zdim = cube.getDimZ();
247  long spatSize = cube.getDimX()*cube.getDimY();
248  float *spec = new float[zdim];
249  for(int z=0;z<zdim;z++) spec[z] = cube.getPixValue(z*spatSize + pixel);
250  this->saveArray(spec,zdim);
251  delete [] spec;
252}
253
254void Image::extractImage(float *Array, long *dim, long channel)
255{
256  /**
257   * Image::extractImage(float *, long *, int)
258   *  A function to extract a 2-D image from a 3-D array.
259   *  The array is assumed to be 3-D with the third dimension the spectral one.
260   *  The dimensions of the array are in the dim[] array.
261   *  The image extracted is the one lying in the channel referenced
262   *    by the third argument.
263   */
264  float *image = new float[dim[0]*dim[1]];
265  for(int npix=0; npix<dim[0]*dim[1]; npix++){
266    image[npix] = Array[channel*dim[0]*dim[1] + npix];
267  }
268  this->saveArray(image,dim[0]*dim[1]);
269  delete [] image;
270}
271
272void Image::extractImage(Cube &cube, long channel)
273{
274  /**
275   * Image::extractImage(Cube &, int)
276   *  A function to extract a 2-D image from Cube class.
277   *  The image extracted is the one lying in the channel referenced
278   *    by the second argument.
279   */
280  long spatSize = cube.getDimX()*cube.getDimY();
281  float *image = new float[spatSize];
282  for(int npix=0; npix<spatSize; npix++)
283    image[npix] = cube.getPixValue(channel*spatSize + npix);
284  this->saveArray(image,spatSize);
285  delete [] image;
286}
287
288void Image::removeMW()
289{
290  /**
291   * Image::removeMW()
292   *  A function to remove the Milky Way range of channels from a 1-D spectrum.
293   *  The array in this Image is assumed to be 1-D, with only the first axisDim
294   *    equal to 1.
295   *  The values of the MW channels are set to 0, unless they are BLANK.
296   */
297  if(this->par.getFlagMW()){
298    int maxMW = this->par.getMaxMW();
299    int minMW = this->par.getMinMW();
300    if(this->axisDim[1]==1){
301      for(int z=0;z<this->axisDim[0];z++){
302        if(!this->isBlank(z) && this->par.isInMW(z)) this->array[z]=0.;
303      }
304    }
305  }
306}
307
308void Image::findStats(int code)
309{
310  /**
311   *  Image::findStats(int code)
312   *    Front-end to function to find the stats (mean/median & sigma/madfm) and
313   *     store them in the "mean" and "sigma" members of Image.
314   *    The choice of normal(mean & sigma) or robust (median & madfm) is made via the
315   *      code parameter. This is stored as a decimal number, with 0s representing
316   *      normal stats, and 1s representing robust.
317   *      The 10s column is the mean, the 1s column the sigma.
318   *      Eg: 00 -- mean&sigma; 01 -- mean&madfm; 10 -- median&sigma; 11 -- median&madfm
319   *    If calculated, the madfm value is corrected to sigma units.
320   *    The Image member "cut" is also assigned using the parameter in Image's par
321   *      (needs to be defined first -- also for the blank pixel determination).
322   */
323  float *tempArray = new float[this->numPixels];
324  int goodSize=0;
325  for(int i=0; i<this->numPixels; i++)
326    if(!this->isBlank(i)) tempArray[goodSize++] = this->array[i];
327  float tempMean,tempSigma,tempMedian,tempMADFM;
328  if(code != 0) findMedianStats(tempArray,goodSize,tempMedian,tempMADFM);
329  if(code != 11) findNormalStats(tempArray,goodSize,tempMean,tempSigma);
330  switch(code)
331    {
332    case 0:
333      findNormalStats(tempArray,goodSize,tempMean,tempSigma);
334      this->mean = tempMean;
335      this->sigma = tempSigma;
336      break;
337    case 10:
338      this->mean  = findMedian(tempArray,goodSize);;
339      this->sigma = findStddev(tempArray,goodSize);
340      break;
341    case 1:
342      this->mean  = findMean(tempArray,goodSize);
343      this->sigma = findMADFM(tempArray,goodSize)/correctionFactor;
344      break;
345    case 11:
346    default:
347      if(code!=11) {
348        std::stringstream errmsg;
349        errmsg << "Invalid code ("<<code<<") in findStats. Using robust method.\n";
350        duchampWarning("Image::findStats", errmsg.str());
351      }
352      findMedianStats(tempArray,goodSize,tempMedian,tempMADFM);
353      this->mean = tempMedian;
354      this->sigma = tempMADFM/correctionFactor;
355      break;
356    }
357  this->cutLevel = this->par.getCut();
358  delete [] tempArray;
359}
360
361/****************************************************************/
362/////////////////////////////////////////////////////////////
363//// Functions for Cube class
364/////////////////////////////////////////////////////////////
365
366Cube::Cube(long size){
367  // need error handling in case size<0 !!!
368  if(size<0)
369    duchampError("Cube(size)","Negative size -- could not define Cube");
370  else{
371    if(size>0){
372      this->array = new float[size];
373      this->recon = new float[size];
374    }
375    this->numPixels = size;
376    this->axisDim = new long[2];
377    this->numDim = 3;
378    this->reconExists = false;
379  }
380}
381
382Cube::Cube(long *dimensions){
383  int size   = dimensions[0] * dimensions[1] * dimensions[2];
384  int imsize = dimensions[0] * dimensions[1];
385  if((size<0) || (imsize<0) )
386    duchampError("Cube(dimArray)","Negative size -- could not define Cube");
387  else{
388    this->numPixels = size;
389    if(size>0){
390      this->array      = new float[size];
391      this->detectMap  = new short[imsize];
392      if(this->par.getFlagATrous())
393        this->recon    = new float[size];
394      if(this->par.getFlagBaseline())
395        this->baseline = new float[size];
396    }
397    this->numDim  = 3;
398    this->axisDim = new long[3];
399    for(int i=0;i<3     ;i++) this->axisDim[i]   = dimensions[i];
400    for(int i=0;i<imsize;i++) this->detectMap[i] = 0;
401  }
402}
403
404Cube::~Cube()
405{
406  delete [] detectMap;
407  if(this->par.getFlagATrous())   delete [] recon;
408  if(this->par.getFlagBaseline()) delete [] baseline;
409  delete [] specMean,specSigma,chanMean,chanSigma;
410}
411
412void Cube::initialiseCube(long *dimensions){
413  int size   = dimensions[0] * dimensions[1] * dimensions[2];
414  int imsize = dimensions[0] * dimensions[1];
415  if((size<0) || (imsize<0) )
416    duchampError("Cube::initialiseCube(dimArray)",
417                 "Negative size -- could not define Cube");
418  else{
419    this->numPixels = size;
420    if(size>0){
421      this->array      = new float[size];
422      this->detectMap  = new short[imsize];
423      this->specMean   = new float[imsize];
424      this->specSigma  = new float[imsize];
425      this->chanMean   = new float[dimensions[2]];
426      this->chanSigma  = new float[dimensions[2]];
427      if(this->par.getFlagATrous())
428        this->recon    = new float[size];
429      if(this->par.getFlagBaseline())
430        this->baseline = new float[size];
431    }
432    this->numDim  = 3;
433    this->axisDim = new long[3];
434    for(int i=0;i<3     ;i++) this->axisDim[i]   = dimensions[i];
435    for(int i=0;i<imsize;i++) this->detectMap[i] = 0;
436  }
437}
438
439int Cube::getopts(int argc, char ** argv)
440{
441  /**
442   *   Cube::getopt
443   *    A front-end to read in the command-line options,
444   *     and then read in the correct parameters to the cube->par
445   */
446
447  int returnValue;
448  if(argc==1){
449    std::cout << ERR_USAGE_MSG;
450    returnValue = FAILURE;
451  }
452  else {
453    string file;
454    Param *par = new Param;
455    char c;
456    while( ( c = getopt(argc,argv,"p:f:hv") )!=-1){
457      switch(c) {
458      case 'p':
459        file = optarg;
460        this->readParam(file);
461        returnValue = SUCCESS;
462        break;
463      case 'f':
464        file = optarg;
465        par->setImageFile(file);
466        this->saveParam(*par);
467        returnValue = SUCCESS;
468        break;
469      case 'v':
470        std::cout << PROGNAME << " version " << VERSION << std::endl;
471        returnValue = FAILURE;
472        break;
473      case 'h':
474      default :
475        std::cout << ERR_USAGE_MSG;
476        returnValue = FAILURE;
477        break;
478      }
479    }
480    delete par;
481  }
482  return returnValue;
483}
484
485
486
487void Cube::saveArray(float *input, long size){
488  if(size != this->numPixels)
489    duchampError("Cube::saveArray",
490                 "Input array different size to existing array. Cannot save.");
491  else {
492    if(this->numPixels>0) delete [] array;
493    this->numPixels = size;
494    this->array = new float[size];
495    for(int i=0;i<size;i++) this->array[i] = input[i];
496  }
497}
498
499void Cube::saveRecon(float *input, long size){
500  if(size != this->numPixels)
501    duchampError("Cube::saveRecon",
502                 "Input array different size to existing array. Cannot save.");
503  else {
504    if(this->numPixels>0) delete [] this->recon;
505    this->numPixels = size;
506    this->recon = new float[size];
507    for(int i=0;i<size;i++) this->recon[i] = input[i];
508    this->reconExists = true;
509  }
510}
511
512void Cube::getRecon(float *output){
513  // Need check for change in number of pixels!
514  long size = this->numPixels;
515  for(int i=0;i<size;i++){
516    if(this->reconExists) output[i] = this->recon[i];
517    else output[i] = 0.;
518  }
519}
520
521void Cube::removeMW()
522{
523  if(this->par.getFlagMW()){
524    for(int pix=0;pix<this->axisDim[0]*this->axisDim[1];pix++){
525      for(int z=0;z<this->axisDim[2];z++){
526        int pos = z*this->axisDim[0]*this->axisDim[1] + pix;
527        if(!this->isBlank(pos) && this->par.isInMW(z)) this->array[pos]=0.;
528      }
529    }
530  }
531}
532
533void Cube::calcObjectWCSparams()
534{
535  /**
536   * Cube::calcObjectWCSparams()
537   *  A function that calculates the WCS parameters for each object in the
538   *  cube's list of detections.
539   *  Each object gets an ID number set (just the order in the list), and if the
540   *   WCS is good, the WCS paramters are calculated.
541   */
542 
543  for(int i=0; i<this->objectList.size();i++){
544    this->objectList[i].setID(i+1);
545    this->objectList[i].calcWCSparams(this->head);
546  } 
547
548 
549}
550
551void Cube::sortDetections()
552{
553  /**
554   * Cube::sortDetections()
555   *  A front end to the sort-by functions.
556   *  If there is a good WCS, the detection list is sorted by velocity.
557   *  Otherwise, it is sorted by increasing z-pixel value.
558   *  The ID numbers are then re-calculated.
559   */
560 
561  if(this->head.isWCS()) SortByVel(this->objectList);
562  else SortByZ(this->objectList);
563  for(int i=0; i<this->objectList.size();i++) this->objectList[i].setID(i+1);
564
565}
566
567void Cube::updateDetectMap()
568{
569  /**
570   * Cube::updateDetectMap()
571   *  A function that, for each detected object in the cube's list, increments the
572   *  cube's detection map by the required amount at each pixel.
573   */
574
575  for(int obj=0;obj<this->objectList.size();obj++){
576    for(int pix=0;pix<this->objectList[obj].getSize();pix++) {
577      int spatialPos = this->objectList[obj].getX(pix)+
578        this->objectList[obj].getY(pix)*this->axisDim[0];
579      this->detectMap[spatialPos]++;
580    }
581  }
582}
583
584void Cube::updateDetectMap(Detection obj)
585{
586  /**
587   * Cube::updateDetectMap(Detection)
588   *  A function that, for the given object, increments the cube's
589   *  detection map by the required amount at each pixel.
590   */
591  for(int pix=0;pix<obj.getSize();pix++) {
592    int spatialPos = obj.getX(pix)+obj.getY(pix)*this->axisDim[0];
593    this->detectMap[spatialPos]++;
594  }
595}
596
597void Cube::setCubeStats()
598{
599  // First set the stats for each spectrum (ie. each spatial pixel)
600  long xySize = this->axisDim[0]*this->axisDim[1];
601  float *spec = new float[this->axisDim[2]];
602  for(int i=0;i<xySize;i++){
603    for(int z=0;z<this->axisDim[2];z++){
604      //Two cases: i) have reconstructed -- use residuals
605      //          ii) otherwise          -- use original array
606      if(this->reconExists)
607        spec[z] = this->array[z*xySize+i] - this->recon[z*xySize+1];
608      else
609        spec[z] = this->array[z*xySize+i];
610    }
611    findMedianStats(spec,this->axisDim[2],this->specMean[i],this->specSigma[i]);
612  }
613  delete spec;
614  // Then set the stats for each channel map
615  float *im = new float[xySize];
616  for(int z=0;z<this->axisDim[2];z++){
617    for(int i=0;i<xySize;i++){
618      if(this->reconExists)
619        im[i] = this->array[z*xySize+i] - this->recon[z*xySize+1];
620      else
621        im[i] = this->array[z*xySize+i];
622    }
623    findMedianStats(im,this->axisDim[2],this->chanMean[z],this->chanSigma[z]);
624    this->chanSigma[z] /= correctionFactor;
625  }
626  delete im;
627
628}
629
630float Cube::enclosedFlux(Detection obj)
631{
632  /**
633   *  float Cube::enclosedFlux(Detection obj)
634   *   A function to calculate the flux enclosed by the range
635   *    of pixels detected in the object obj (not necessarily all
636   *    pixels will have been detected).
637   */
638  obj.calcParams();
639  int xsize = obj.getXmax()-obj.getXmin()+1;
640  int ysize = obj.getYmax()-obj.getYmin()+1;
641  int zsize = obj.getZmax()-obj.getZmin()+1;
642  vector <float> fluxArray(xsize*ysize*zsize,0.);
643  for(int x=0;x<xsize;x++){
644    for(int y=0;y<ysize;y++){
645      for(int z=0;z<zsize;z++){
646        fluxArray[x+y*xsize+z*ysize*xsize] =
647          this->getPixValue(x+obj.getXmin(),
648                            y+obj.getYmin(),
649                            z+obj.getZmin());
650        if(this->par.getFlagNegative())
651          fluxArray[x+y*xsize+z*ysize*xsize] *= -1.;
652      }
653    }
654  }
655  float sum = 0.;
656  for(int i=0;i<fluxArray.size();i++)
657    if(!this->par.isBlank(fluxArray[i])) sum+=fluxArray[i];
658  return sum;
659}
660
661void Cube::setupColumns()
662{
663  /**
664   *  Cube::setupColumns()
665   *   A front-end to the two setup routines in columns.cc.
666   */
667  for(int i=0; i<this->objectList.size();i++) this->objectList[i].setID(i+1);
668  this->fullCols.clear();
669  this->fullCols = getFullColSet(this->objectList, this->head);
670
671  this->logCols.clear();
672  this->logCols = getLogColSet(this->objectList, this->head);
673
674  int vel,fpeak,fint,pos,xyz,temp;
675  vel = fullCols[VEL].getPrecision();
676  fpeak = fullCols[FPEAK].getPrecision();
677  xyz = fullCols[X].getPrecision();
678  if(temp=fullCols[Y].getPrecision() > xyz) xyz = temp;
679  if(temp=fullCols[Z].getPrecision() > xyz) xyz = temp;
680  if(this->head.isWCS()) fint = fullCols[FINT].getPrecision();
681  else fint = fullCols[FTOT].getPrecision();
682  pos = fullCols[WRA].getPrecision();
683  if(temp=fullCols[WDEC].getPrecision() > pos) pos = temp;
684 
685  for(int obj=0;obj<this->objectList.size();obj++){
686    this->objectList[obj].setVelPrec(vel);
687    this->objectList[obj].setFpeakPrec(fpeak);
688    this->objectList[obj].setXYZPrec(xyz);
689    this->objectList[obj].setPosPrec(pos);
690    this->objectList[obj].setFintPrec(fint);
691  }
692
693}
694
695bool Cube::objAtEdge(Detection obj)
696{
697  /**
698   *  bool Cube::objAtEdge()
699   *   A function to test whether the object obj
700   *    lies at the edge of the cube's field --
701   *    either at the boundary, or next to BLANKs
702   */
703
704  bool atEdge = false;
705
706  int pix = 0;
707  while(!atEdge && pix<obj.getSize()){
708    // loop over each pixel in the object, until we find an edge pixel.
709    Voxel vox = obj.getPixel(pix);
710    for(int dx=-1;dx<=1;dx+=2){
711      if(((vox.getX()+dx)<0) || ((vox.getX()+dx)>=this->axisDim[0]))
712        atEdge = true;
713      else if(this->isBlank(vox.getX()+dx,vox.getY(),vox.getZ()))
714        atEdge = true;
715    }
716    for(int dy=-1;dy<=1;dy+=2){
717      if(((vox.getY()+dy)<0) || ((vox.getY()+dy)>=this->axisDim[1]))
718        atEdge = true;
719      else if(this->isBlank(vox.getX(),vox.getY()+dy,vox.getZ()))
720        atEdge = true;
721    }
722    for(int dz=-1;dz<=1;dz+=2){
723      if(((vox.getZ()+dz)<0) || ((vox.getZ()+dz)>=this->axisDim[2]))
724        atEdge = true;
725      else if(this->isBlank(vox.getX(),vox.getY(),vox.getZ()+dz))
726        atEdge = true;
727    }
728    pix++;
729  }
730
731  return atEdge;
732}
733
734void Cube::setObjectFlags()
735{
736  /**
737   *  void Cube::setObjectFlags()
738   *   A function to set any warning flags for all the detected objects
739   *    associated with the cube.
740   *   Flags to be looked for:
741   *       * Negative enclosed flux (N)
742   *       * Object at edge of field (E)
743   */
744
745  for(int i=0;i<this->objectList.size();i++){
746
747    if( this->enclosedFlux(this->objectList[i]) < 0. ) 
748      this->objectList[i].addToFlagText("N");
749
750    if( this->objAtEdge(this->objectList[i]) )
751      this->objectList[i].addToFlagText("E");
752
753  }
754
755}
756
757void Cube::plotBlankEdges()
758{
759  if(this->par.drawBlankEdge()){
760    int colour;
761    cpgqci(&colour);
762    cpgsci(MAGENTA);
763    drawBlankEdges(this->array,this->axisDim[0],this->axisDim[1],this->par);
764    cpgsci(colour);
765  }
766}
Note: See TracBrowser for help on using the repository browser.