source: tags/release-1.0.5/src/Cubes/cubes.cc @ 178

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

Some minor fixes to code:

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