source: trunk/src/Utils/getStats.cc @ 204

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

A large commit, based on improving memory usage, allocation, etc:

  • src/param.hh :
    • Added a delete command for the offsets array in Param. Keep track of size via new sizeOffsets variable.
    • Changed "wcsprm" to "struct wcsprm", for clarity.
    • Put wcsvfree in the FitsHeader? destructor so that memory is deallocated correctly.
  • src/param.cc :
    • Improved the FitsHeader? constructor functions, so that memory for the wcsprm structures is allocated appropriately.
    • Other wcsprm-related tweaks.
    • Included code for sizeOffsets -- the size of the offsets array in Param, so that we can properly deallocate its memory in the destructor function.
  • src/FitsIO/subsection.cc : Changed "wcsprm" to "struct wcsprm", for clarity, and added a sizeOffsets to track the memory allocation for offsets.
  • src/FitsIO/dataIO.cc : renamed the local variable array to pixarray so that there is no confusion. Added delete[] commands for local arrays.
  • src/FitsIO/wcsIO.cc : Improved the struct wcsprm memory allocation. Now using a local wcs variable so that we don't get confusion with the FitsHeader? one.
  • src/Utils/wcsFunctions.cc : changed "wcsprm" to "struct wcsprm", for clarity.
  • src/Cubes/CubicSearch.cc : removed two allocation calls (to new) that were not needed, as well as unused commented-out code.
  • src/Cubes/plotting.cc :
    • Corrected the way the detection map is worked out and the scale bar range calculated.
    • Changed "wcsprm" to "struct wcsprm", for clarity.
  • src/duchamp.hh : better implementation of the rewind() and remove() functions for ProgressBar?
  • src/Utils/getStats.cc : minor diffs
  • src/Utils/utils.hh : changed prototypes
  • src/Cubes/cubes.cc : Changed the way the setCubeStats() function works, so that stats aren't needlessly calculated if the threshold has already been specified.
  • src/Cubes/cubes.hh : minor presentation changes
  • src/Cubes/drawMomentCutout.cc : Tried to improve the scale-bar drawing function, to cope with very high angular resolution data. Not quite working properly yet.
  • src/Cubes/outputSpectra.cc : Corrected the flux labels so that the appropriate units are used, and not just Jy or Jy/beam.
File size: 10.8 KB
Line 
1#include <cpgplot.h>
2#include <iostream>
3#include <algorithm>
4#include <math.h>
5#include <Utils/utils.hh>
6
7template <class T> T absval(T value)
8{
9  if( value > 0) return value;
10  else return 0-value;
11}
12//--------------------------------------------------------------------
13
14template <class T> void findMinMax(const T *array, const int size,
15                                   T &min, T &max)
16{
17  min = max = array[0];
18  for(int i=1;i<size;i++) {
19    if(array[i]<min) min=array[i];
20    if(array[i]>max) max=array[i];
21  }
22}
23template void findMinMax<int>(const int *array, const int size,
24                              int &min, int &max);
25template void findMinMax<float>(const float *array, const int size,
26                                float &min, float &max);
27//--------------------------------------------------------------------
28
29template <class T> float findMean(T *array, int size)
30{
31  float mean = array[0];
32  for(int i=1;i<size;i++) mean += array[i];
33  mean /= float(size);
34  return mean;
35}
36template float findMean<int>(int *array, int size);
37template float findMean<float>(float *array, int size);
38//--------------------------------------------------------------------
39
40template <class T> float findStddev(T *array, int size)
41{
42  float mean = findMean(array,size);
43  float stddev = (array[0]-mean) * (array[0]-mean);
44  for(int i=1;i<size;i++) stddev += (array[i]-mean)*(array[i]-mean);
45  stddev = sqrt(stddev/float(size-1));
46  return stddev;
47}
48template float findStddev<int>(int *array, int size);
49template float findStddev<float>(float *array, int size);
50//--------------------------------------------------------------------
51
52template <class T> T findMedian(T *array, int size)
53{
54  // NOTE: madfm = median absolute deviation from median
55  T *newarray = new T[size];
56  T median;
57  for(int i=0;i<size;i++) newarray[i] = array[i];
58  sort(newarray,0,size);
59  if((size%2)==0) median = (newarray[size/2-1]+newarray[size/2])/2;
60  else median = newarray[size/2];
61  delete [] newarray;
62  return median;
63}
64template int findMedian<int>(int *array, int size);
65template float findMedian<float>(float *array, int size);
66//--------------------------------------------------------------------
67
68template <class T> T findMADFM(T *array, int size)
69{
70  // NOTE: madfm = median absolute deviation from median
71  T *newarray = new T[size];
72  T median = findMedian<T>(array,size);
73  T madfm;
74  for(int i=0;i<size;i++) newarray[i] = absval(array[i]-median);
75  sort(newarray,0,size);
76  if((size%2)==0) madfm = (newarray[size/2-1]+newarray[size/2])/2;
77  else madfm = newarray[size/2];
78  delete [] newarray;
79  return madfm;
80}
81template int findMADFM<int>(int *array, int size);
82template float findMADFM<float>(float *array, int size);
83//--------------------------------------------------------------------
84
85template <class T> void findMedianStats(T *array, int size,
86                                        T &median, T &madfm)
87{
88  // NOTE: madfm = median absolute deviation from median
89  if(size==0){
90    std::cerr << "Error in findMedianStats: zero sized array!\n";
91    return;
92  }
93  T *newarray = new T[size];
94
95  for(int i=0;i<size;i++) newarray[i] = array[i];
96  sort(newarray,0,size);
97//   int newsize = sizeof(newarray)-1;
98//   stable_sort(newarray,newarray+newsize);
99  if((size%2)==0) median = (newarray[size/2-1]+newarray[size/2])/2;
100  else median = newarray[size/2];
101
102  for(int i=0;i<size;i++) newarray[i] = absval(array[i]-median);
103  sort(newarray,0,size);
104//   stable_sort(newarray,newarray+newsize);
105  if((size%2)==0) madfm = (newarray[size/2-1]+newarray[size/2])/2;
106  else madfm = newarray[size/2];
107
108  delete [] newarray;
109}
110template void findMedianStats<int>(int *array, int size,
111                                   int &median, int &madfm);
112template void findMedianStats<long>(long *array, int size,
113                                    long &median, long &madfm);
114template void findMedianStats<float>(float *array, int size,
115                                     float &median, float &madfm);
116template void findMedianStats<double>(double *array, int size,
117                                      double &median, double &madfm);
118//--------------------------------------------------------------------
119
120template <class T> void findMedianStats(T *array, int size, bool *isGood,
121                                        T &median, T &madfm)
122{
123  // NOTE: madfm = median absolute deviation from median
124  int goodSize=0;
125  for(int i=0;i<size;i++) if(isGood[i]) goodSize++;
126  if(goodSize==0){
127    std::cerr << "Error in findMedianStats: no good values!\n";
128    return;
129  }
130  T *newarray = new T[goodSize];
131  for(int i=0;i<size;i++) if(isGood[i]) newarray[goodSize++] = array[i];
132  sort(newarray,0,goodSize);
133  if((goodSize%2)==0)
134    median = (newarray[goodSize/2-1]+newarray[goodSize/2])/2;
135  else
136    median = newarray[goodSize/2];
137
138  for(int i=0;i<goodSize;i++) newarray[i] = absval(newarray[i]-median);
139  sort(newarray,0,goodSize);
140  if((goodSize%2)==0)
141    madfm = (newarray[goodSize/2-1]+newarray[goodSize/2])/2;
142  else
143    madfm = newarray[goodSize/2];
144
145  delete [] newarray;
146}
147template void findMedianStats<int>(int *array, int size, bool *isGood,
148                                   int &median, int &madfm);
149template void findMedianStats<long>(long *array, int size, bool *isGood,
150                                    long &median, long &madfm);
151template void findMedianStats<float>(float *array, int size, bool *isGood,
152                                     float &median, float &madfm);
153template void findMedianStats<double>(double *array, int size, bool *isGood,
154                                      double &median, double &madfm);
155//--------------------------------------------------------------------
156 
157
158template <class T> void findNormalStats(T *array, int size,
159                                        float &mean, float &stddev)
160{
161  if(size==0){
162    std::cerr << "Error in findNormalStats: zero sized array!\n";
163    return;
164  }
165  mean = array[0];
166  for(int i=1;i<size;i++){
167    mean += array[i];
168  }
169  mean /= float(size);
170
171  stddev = (array[0]-mean) * (array[0]-mean);
172  for(int i=1;i<size;i++){
173    float sqdiff = (array[i]-mean)*(array[i]-mean);
174    stddev += sqdiff;
175  }
176  stddev = sqrt(stddev/float(size-1));
177
178}
179template void findNormalStats<int>(int *array, int size,
180                                   float &mean, float &stddev);
181template void findNormalStats<long>(long *array, int size,
182                                    float &mean, float &stddev);
183template void findNormalStats<float>(float *array, int size,
184                                     float &mean, float &stddev);
185template void findNormalStats<double>(double *array, int size,
186                                      float &mean, float &stddev);
187//--------------------------------------------------------------------
188
189template <class T> void findNormalStats(T *array, int size, bool *isGood,
190                                        float &mean, float &stddev)
191{
192  int goodSize=0;
193  for(int i=0;i<size;i++) if(isGood[i]) goodSize++;
194  if(goodSize==0){
195    std::cerr << "Error in findNormalStats: no good values!\n";
196    return;
197  }
198  int start=0;
199  while(!isGood[start]){start++;}
200  mean = array[start];
201  for(int i=start+1;i<size;i++){
202    if(isGood[i]) mean += array[i];
203  }
204  mean /= float(goodSize);
205
206  stddev = (array[start]-mean) * (array[start]-mean);
207  for(int i=1;i<size;i++){
208    if(isGood[i]) stddev += (array[i]-mean)*(array[i]-mean);
209  }
210  stddev = sqrt(stddev/float(goodSize-1));
211
212}
213template void findNormalStats<int>(int *array, int size, bool *isGood,
214                                   float &mean, float &stddev);
215template void findNormalStats<long>(long *array, int size, bool *isGood,
216                                    float &mean, float &stddev);
217template void findNormalStats<float>(float *array, int size, bool *isGood,
218                                     float &mean, float &stddev);
219template void findNormalStats<double>(double *array, int size, bool *isGood,
220                                      float &mean, float &stddev);
221//--------------------------------------------------------------------
222
223void findTrimmedHistStatsOLD(float *array, const int size,
224                             float &tmean, float &tsigma)
225{
226
227  const int nbin = 100;
228  float *num = new float[nbin];
229  bool *keep = new bool[nbin];
230
231  // HOW MANY VALUES IN EACH BIN?
232  float min,max;
233  findMinMax(array,size,min,max);
234  for(int i=0; i<nbin; i++) num[i]=0;
235  for(int i=0; i<size; i++){
236    float fraction = (array[i] - min) / (max - min);
237    int bin = (int)( floor(fraction*nbin) );
238    if((bin>=0)&&(bin<nbin)) num[bin]++;
239  }
240  int binmax = 0;
241  for(int i=1; i<nbin; i++)  if(num[i]>num[binmax]) binmax = i;
242  for(int i=0; i<nbin; i++) keep[i] = (num[i]>=num[binmax]/2);
243  float *newarray = new float[size];
244  int newsize = 0;
245  for(int i=0; i<size; i++){
246    float fraction = (array[i] - min) / (max - min);
247    int bin = (int)( floor(fraction*nbin) );
248    if(keep[bin]) newarray[newsize++] = array[i];
249  }
250
251  findNormalStats(newarray,newsize,tmean,tsigma);
252  delete [] num,keep,newarray;
253
254}
255//--------------------------------------------------------------------
256
257void findTrimmedHistStats2(float *array, const int size,
258                           float &tmean, float &tsigma)
259{
260
261  const int nbin = 200;
262  float *num = new float[nbin];
263  bool *keep = new bool[nbin];
264
265  // HOW MANY VALUES IN EACH BIN?
266  float min,max;
267  findMinMax(array,size,min,max);
268  for(int i=0; i<nbin; i++) num[i]=0;
269  for(int i=0; i<size; i++){
270    float fraction = (array[i] - min) / (max - min);
271    int bin = (int)( floor(fraction*nbin) );
272    if((bin>=0)&&(bin<nbin)) num[bin]++;
273  }
274  int binmax = 0;
275  for(int i=1; i<nbin; i++)  if(num[i]>num[binmax]) binmax = i;
276  for(int i=0; i<nbin; i++) keep[i] = (num[i]>=num[binmax]/2);
277  float *newarray = new float[size];
278  int newsize = 0;
279  for(int i=0; i<size; i++){
280    float fraction = (array[i] - min) / (max - min);
281    int bin = (int)( floor(fraction*nbin) );
282    if(keep[bin]) newarray[newsize++] = array[i];
283  }
284
285  tmean = findMean(newarray,newsize);
286
287  tsigma = newsize * (max-min)/float(nbin) /
288    (num[binmax] * erf(sqrt(M_LN2)) * sqrt(2.*M_PI));
289
290}
291//--------------------------------------------------------------------
292
293void findTrimmedHistStats(float *array, const int size,
294                          float &tmean, float &tsigma)
295{
296  float datamin,datamax;
297  findMinMax(array,size,datamin,datamax);
298  float *sorted = new float[size];
299  float *cumul  = new float[size];
300  float *angle  = new float[size];
301  for(int i=0;i<size;i++) sorted[i] = array[i]/(datamax-datamin);
302  sort(sorted,0,size);
303  for(int i=0;i<size;i++) cumul[i] = (float)i/(float)size;
304  int width =(int)( 20. * log10((float)size));
305  for(int i=0;i<size;i++){
306    int beg,end;
307    float slope,eSlope,inter,eInter,r;
308    if(i<width/2) beg=0; else beg=i-width/2;
309    if(i>=size-width/2) end=size-1; else end=i+width/2;
310    if(linear_regression(size,sorted,cumul,beg,end,slope,eSlope,inter,eInter,r)==0)
311      angle[i] = atan( fabs(slope) ) * 180. / M_PI;
312    else angle[i] = 90.;
313  }
314
315//   int start = 0;
316//   while(angle[start] < 45.) start++;
317//   int finish = size-1;
318//   while(angle[finish] < 45.) finish--;
319
320  int maxpt = 0;
321  for(int i = 1; i<size; i++) if(angle[i]>angle[maxpt]) maxpt=i;
322  int start = maxpt;
323  while((start>0)&&(angle[start]>45.)) start--;
324  int finish = maxpt;
325  while((finish < size-1)&&(angle[finish]>45.)) finish++;
326
327//   std::cerr << "npts = " << size << ", start = " << start << ", finish = " << finish << std::endl;
328
329  int trimSize=0;
330  float *newarray = new float[finish-start+1];
331  for(int i=0;i<finish-start+1;i++) newarray[i] = sorted[i+start]*(datamax-datamin);
332
333  findNormalStats(newarray,finish-start+1,tmean,tsigma);
334 
335}
Note: See TracBrowser for help on using the repository browser.