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

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

Changes here mostly aimed at reducing/removing memory leaks. These were one of:

  • Forgetting to delete something allocated with "new". The Cube destructor has improved with the use of bool variables to keep track of when recon & baseline ahave been allocated.
  • Incorrectly using the wcs->flag parameter (eg. wcsIO had it set to -1 *after* calling wcsini)
  • Not closing a fits file once finished with (dataIO)
  • Allocating the wcsprm structs with calloc before calling wcsini, so that wcsvfree can work (it calls "free", so the memory needs to be allocated with calloc or malloc).

The only other change was the following:

  • A new way of doing the Cube::setCubeStats -- rather than calling the functions in getStats.cc, we explicitly do the calculations. This means we can sort the tempArray that has the BLANKS etc removed. This saves a great deal of memory usage on large FITS files (such as Enno's 2Gb one)
  • The old setCubeStats function is still there but called setCubeStatsOld.
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;
253  delete [] keep;
254  delete [] newarray;
255
256}
257//--------------------------------------------------------------------
258
259void findTrimmedHistStats2(float *array, const int size,
260                           float &tmean, float &tsigma)
261{
262
263  const int nbin = 200;
264  float *num = new float[nbin];
265  bool *keep = new bool[nbin];
266
267  // HOW MANY VALUES IN EACH BIN?
268  float min,max;
269  findMinMax(array,size,min,max);
270  for(int i=0; i<nbin; i++) num[i]=0;
271  for(int i=0; i<size; i++){
272    float fraction = (array[i] - min) / (max - min);
273    int bin = (int)( floor(fraction*nbin) );
274    if((bin>=0)&&(bin<nbin)) num[bin]++;
275  }
276  int binmax = 0;
277  for(int i=1; i<nbin; i++)  if(num[i]>num[binmax]) binmax = i;
278  for(int i=0; i<nbin; i++) keep[i] = (num[i]>=num[binmax]/2);
279  float *newarray = new float[size];
280  int newsize = 0;
281  for(int i=0; i<size; i++){
282    float fraction = (array[i] - min) / (max - min);
283    int bin = (int)( floor(fraction*nbin) );
284    if(keep[bin]) newarray[newsize++] = array[i];
285  }
286
287  tmean = findMean(newarray,newsize);
288
289  tsigma = newsize * (max-min)/float(nbin) /
290    (num[binmax] * erf(sqrt(M_LN2)) * sqrt(2.*M_PI));
291
292}
293//--------------------------------------------------------------------
294
295void findTrimmedHistStats(float *array, const int size,
296                          float &tmean, float &tsigma)
297{
298  float datamin,datamax;
299  findMinMax(array,size,datamin,datamax);
300  float *sorted = new float[size];
301  float *cumul  = new float[size];
302  float *angle  = new float[size];
303  for(int i=0;i<size;i++) sorted[i] = array[i]/(datamax-datamin);
304  sort(sorted,0,size);
305  for(int i=0;i<size;i++) cumul[i] = (float)i/(float)size;
306  int width =(int)( 20. * log10((float)size));
307  for(int i=0;i<size;i++){
308    int beg,end;
309    float slope,eSlope,inter,eInter,r;
310    if(i<width/2) beg=0; else beg=i-width/2;
311    if(i>=size-width/2) end=size-1; else end=i+width/2;
312    if(linear_regression(size,sorted,cumul,beg,end,slope,eSlope,inter,eInter,r)==0)
313      angle[i] = atan( fabs(slope) ) * 180. / M_PI;
314    else angle[i] = 90.;
315  }
316
317//   int start = 0;
318//   while(angle[start] < 45.) start++;
319//   int finish = size-1;
320//   while(angle[finish] < 45.) finish--;
321
322  int maxpt = 0;
323  for(int i = 1; i<size; i++) if(angle[i]>angle[maxpt]) maxpt=i;
324  int start = maxpt;
325  while((start>0)&&(angle[start]>45.)) start--;
326  int finish = maxpt;
327  while((finish < size-1)&&(angle[finish]>45.)) finish++;
328
329//   std::cerr << "npts = " << size << ", start = " << start << ", finish = " << finish << std::endl;
330
331  int trimSize=0;
332  float *newarray = new float[finish-start+1];
333  for(int i=0;i<finish-start+1;i++) newarray[i] = sorted[i+start]*(datamax-datamin);
334
335  findNormalStats(newarray,finish-start+1,tmean,tsigma);
336 
337}
Note: See TracBrowser for help on using the repository browser.