DAS  3.1.6 - 18/09/2017
FFT.c
Go to the documentation of this file.
1 #include <windows.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <malloc.h>
6 #include <math.h>
7 #include <direct.h>
8 #include "mgui.h"
9 #include "DAS_Spatram.h"
10 #include "dcl.h"
11 #include "dil.h"
12 #include "bil.h"
13 #include "DOAS.h"
14 
16 
24 #define SWAP(a,b) temp=(a);(a)=(b);(b)=temp
25 
26 void four1(double data[], unsigned long nn, int isign)
27 /*
28 Replaces data[1..2*nn] by its discrete Fourier transform, if isign is input as 1; or replaces
29 data[1..2*nn] by nn times its inverse discrete Fourier transform, if isign is input as - 1.
30 data is a complex array of length nn or, equivalently, a real array of length 2*nn. nn MUST
31 be an integer power of 2 (this is not checked for!).
32 */
33 {
34  unsigned long n,mmax,m,j,istep,i;
35  double wtemp,wr,wpr,wpi,wi,theta; //Double precision for the trigonomet-ricrecurrences
36  double temp,tempi;
37  n=nn << 1;
38  j=1;
39 
40  for (i=1;i<=n;i+=2)
41  { //This is the bit-reversal section of the routine.
42  if (j > i)
43  {
44  SWAP(data[j],data[i]); //Exchange the two complex numbers.
45  SWAP(data[j+1],data[i+1]);
46  }
47  m=nn;
48  while (m >= 2 && j > m)
49  {
50  j -=m;
51  m >>= 1;
52  }
53  j +=m;
54  }
55 //Here begins the Danielson-Lanczos section of the routine.
56  mmax=2;
57  while (n > mmax)
58  { //Outer loop executed log 2 nn times.
59  istep=mmax << 1;
60  theta=isign*(6.28318530717959/mmax); //Initialize the trigonometric recurrence.
61  wtemp=sin(0.5*theta);
62  wpr = -2.0*wtemp*wtemp;
63  wpi=sin(theta);
64  wr=1.0;
65  wi=0.0;
66 
67  for (m=1;m<=mmax;m+=2)
68  { //Here are the two nested inner loops.
69  for (i=m;i<=n;i+=istep)
70  {
71  j=i+mmax; //This is the Danielson-Lanczos formula:
72  temp=wr*data[j]-wi*data[j+1];
73  tempi=wr*data[j+1]+wi*data[j];
74  data[j]=data[i]-temp;
75  data[j+1]=data[i+1]-tempi;
76  data[i] += temp;
77  data[i+1] += tempi;
78  }
79  wr=(wtemp=wr)*wpr-wi*wpi+wr; //Trigonometric recurrence.
80  wi=wi*wpr+wtemp*wpi+wi;
81  }
82  mmax=istep;
83  }
84 }
85 
86 /*
87 Calculates the Fourier transform of a set of n real-valued data points. Replaces this data (which
88 is stored in array data[1..n]) by the positive frequency half of its complex Fourier transform.
89 The real-valued .rst and last components of the complex transform are returned as elements
90 data[1] and data[2], respectively. n must be a power of 2. This routine also calculates the
91 inverse transform of a complex data array if it is the transform of real data. (Result in this case
92 must be multiplied by 2/n.)
93 */
94 
95 void realft(double data[], unsigned long n, int isign)
96 {
97  void four1(double data[], unsigned long nn, int isign);
98  unsigned long i,i1,i2,i3,i4,np3;
99  double c1=0.5,c2,h1r,h1i,h2r,h2i;
100  double wr,wi,wpr,wpi,wtemp,theta; //Double precision for the trigonometric recurrences.
101  //theta=3.141592653589793/(double) (n>>1);// Initialize the recurrence.
102  theta=3.141592653589793/(double) (n);// Initialize the recurrence.
103  if (isign == 1)
104  {
105  c2 = -0.5;
106  //four1(data ,n>>1,1); //The forward transform is here.
107  four1(data ,n ,1); //The forward transform is here.
108  }
109  else
110  {
111  c2=0.5; //Otherwise set up for an inverse transform.
112  theta = -theta;
113  }
114  wtemp=sin(0.5*theta);
115  wpr = -2.0*wtemp*wtemp;
116  wpi=sin(theta);
117  wr=1.0+wpr;
118  wi=wpi;
119  //np3=n+3;
120  np3=2 *n + 3;
121  //for (i=2;i<=(n>>2);i++)
122  for (i=2;i<=(n/2)+1;i++)
123  { //Case i=1 done separately below.
124  i4=1+(i3=np3-(i2=1+(i1=i+i-1)));
125  h1r=c1*(data[i1]+data[i3]); //The two separate transforms are separated out of data.
126  h1i=c1*(data[i2]-data[i4]);
127  h2r = -c2*(data[i2]+data[i4]);
128  h2i=c2*(data[i1]-data[i3]);
129  data[i1]=h1r+wr*h2r-wi*h2i; //Here they are recombined to form the true transform of the original real data.
130  data[i2]=h1i+wr*h2i+wi*h2r;
131  data[i3]=h1r-wr*h2r+wi*h2i;
132  data[i4] = -h1i+wr*h2i+wi*h2r;
133  wr=(wtemp=wr)*wpr-wi*wpi+wr; //The recurrence.
134  wi=wi*wpr+wtemp*wpi+wi;
135  }
136  if (isign == 1)
137  {
138  data[1] = (h1r=data[1])+data[2]; //Squeeze the .rst and last data together to get them all within the original array.
139  data[2] = h1r-data[2];
140 
141  }
142  else
143  {
144  data[1]=c1*((h1r=data[1])+data[2]);
145  data[2]=c1*(h1r-data[2]);
146  //four1(data ,n>>1,-1); //This is the inverse transform for the case isign=-1.
147  four1(data , n, -1); //This is the inverse transform for the case isign=-1.
148 
149  }
150 }
151 int SmoothingF(double *tmp, int npix, int pts)
152 {
153  long double a, kost;
154  int NMin = 0;
155  //int mmax = 4096;
156  int mmax = 8192;
157  int M = 2, i, k;
158  unsigned long MO2;
159  long double y0, yn, FAC;
160  long double rn1, dummy, dummy1;
161 
162  NMin = npix + 2 * pts;
163  do
164  {
165  M = 2 * M; // find the next power of 2
166 
167  }while(M < NMin);
168 
169  if(M > mmax)
170  {
171  MMessageDialog("Smoothing Error", "MMax too small", "ok", NULL);
172  return 1;
173  }
174 
175  kost = pow( (double)pts / (double)M, (double)2.0); //useful constant
176 
177 
178  y0 = tmp[1];
179  yn = tmp[npix ];
180  rn1 = (double) (1.0 / (double)(npix - 1));
181 /*
182  //remove the linear trend
183  for(i = 0; i< npix;i++)
184  tmp[i] = tmp[i] - rn1 * (y0 * (double)(npix - i) + yn * (double)(i - 1));
185 */
186  //remove the linear trend
187  for(i = 1; i<= npix;i++)
188  tmp[i] = tmp[i ] - rn1 * (y0 * (double)(npix - i) + yn * (double)(i - 1));
189 
190  if(npix+1 <= M)
191  {
192  for(i = npix+1; i<M;i++)
193  tmp[i] = 0;
194  }
195 
196  MO2 = M / 2;
197  realft(tmp , MO2, 1); //fourier transform
198 
199  tmp[1] = tmp[1] / MO2;
200  FAC = 1; // square windows
201 
202  for (i=1; i <= (int) (MO2 - 1);i++)
203  {
204  k = 2 * i + 1;
205 
206  if ((FAC > 0) | (FAC <0))
207  FAC = 0;
208 
209  a = (1 - kost * pow((double)i, (double)2)) / MO2;
210  //a = (1 - kost * pow((0.25 * i),2)) / MO2;
211  //a = (1 - pow((0.25 * i),2)) / MO2;
212  //a = 1 - pow( (((double)i - MO2/2)/( MO2/2)),2 );
213 
214  if(a > FAC)
215  {
216  FAC = a;
217  tmp[k] = FAC * tmp[k];
218  tmp[k + 1] = FAC * tmp[k + 1];
219  }
220  else
221  {
222  tmp[k] = 0;
223  tmp[k + 1] = 0;
224  }
225  }
226  FAC = 0;
227  dummy = pow(((double)0.25 * (double)pts),(double)2);
228  dummy1= (0.25 * pts) * (0.25 * pts);
229  a = (1 - pow(((double)0.25 * (double)pts),(double)2)) / MO2;
230  if (a > 0)
231  FAC = a;
232 
233  tmp[2] = FAC * tmp[2];
234 
235  realft(tmp , MO2, -1); //inverse fourier transform
236  /*
237  for (i=0;i<npix;i++)
238  //Re-Insert the linear trend
239  tmp[i] = tmp[i] + rn1 * (y0 * (double)(npix - i) + yn * (double)(i - 1));
240 */
241  for (i=1;i<=npix;i++)
242  //Re-Insert the linear trend
243  tmp[i] = (tmp[i] + rn1 * (y0 * (double)(npix - i) + yn * (double)(i - 1)));
244 
245 
246  return 0;
247 }
248 
249 
250 int FilterData(unsigned short *mat, int horpix, int verpix, int filw, int bp)
251 {
252 
253 
254  int x, y, n ;
255  FILE *fd;
256  double *avect;
257  unsigned long eln = (unsigned long)(2 * (horpix - bp + 1)) ;
258 
259 
260  fd = fopen("FilterUS_In.tmp", "w");
261  if(fd < 0) return 1;
262 // for(x = 0; x < horpix + 1; x++)
263  for(x = 0; x < horpix ; x++)
264  {
265  if ((x <= horpix - bp ) & (x > 1))
266  {
267  fprintf(fd, "%04u ", x);
268 
269  for(y = 0; y < verpix; y++)
270  {
271  fprintf(fd, "%05u ", mat[y * IDX + x]);
272  }
273  fprintf(fd, "\n", NULL);
274  }
275  }
276  fprintf(fd, "\n", NULL);
277  fclose(fd);
278 
279 
280 
281  if(filw <= 512)
282  avect = (double *) calloc( eln, sizeof(double));
283  else if((filw > 512) & (filw <1024))
284  avect = (double *) calloc( 2*eln, sizeof(double));
285  else if((filw >= 1024) & (filw <2048))
286  avect = (double *) calloc( 4*eln, sizeof(double));
287 
288 
289  if( avect == NULL )
290  return 1;
291 
292  for(y = 0; y < verpix; y++)
293  {
294  n=1;
295  for(x = 0; x < horpix; x++)
296  {
297  if ((x < horpix - bp) & (x > 1))
298  {
299  avect[n] = (double)mat[y * (horpix) + x];
300  n++;
301  }
302 
303  }
304 
305  SmoothingF(avect, n - 1 , filw);
306 
307  for(x = 0; x < horpix; x++)
308  {
309  if ((x < horpix - bp) & (x > 1))
310  {
311  mat[y * horpix + x] = (unsigned int)avect[x - 1] ;
312  }
313 
314  }
315  }
316 
317  free(avect);
318 
319 
320 
321  fd = fopen("FilterUS_Out.tmp", "w");
322  if(fd < 0) return 1;
323 
324 // for(x = 0; x < horpix + 1; x++)
325  for(x = 0; x < horpix ; x++)
326  {
327  if ((x <= horpix - bp ) & (x > 1))
328  {
329  fprintf(fd, "%04u ", x);
330 
331  for(y = 0; y < verpix; y++)
332  {
333  fprintf(fd, "%05u ", mat[y * IDX + x]);
334  }
335  fprintf(fd, "\n", NULL);
336  }
337  }
338  fprintf(fd, "\n", NULL);
339  fclose(fd);
340 
341  return 0;
342 
343 }
344 
345 
346 
347 
348 int CheckSpikes(int mod, double *tmp, int npix)
349 {
350 
351  double deltapoint = 0;
352  double deltapoint1 = 0;
353 
354  int i;
355 
356  for (i = 1;i<npix - 1;i++)
357  {
358  deltapoint = fabs( (double)( (tmp[i+1] - tmp[i])/60000*100) );
359  deltapoint1 = fabs( (double)( (tmp[i+1] - tmp[i+2])/60000*100) );
360  if( (deltapoint > 1.6) && (deltapoint1 > 1.6)) //1.6 = 1000/60000*100
361  tmp[i+1] = tmp[i];
362 
363  }
364 
365  return 0;
366 }
367 
368 
369 int RemoveSpikes(int mod, unsigned short *mat, int horpix, int verpix, int blindpix)
370 {
371 
372 
373  int x, y, n ;
374  double *avect;
375  unsigned long eln = (unsigned long)(2 * (horpix - blindpix + 1)) ;
376  FILE *fd;
377 
378  fd = fopen("Spikes.tmp", "w");
379  if(fd < 0) return 1;
380 // for(x = 0; x < horpix + 1; x++)
381  for(x = 0; x < horpix ; x++)
382  {
383  if ((x <= horpix - blindpix ) & (x > 1))
384  {
385  fprintf(fd, "%04u ", x);
386 
387  for(y = 0; y < verpix; y++)
388  {
389  fprintf(fd, "%05u ", mat[y * IDX + x]);
390  }
391  fprintf(fd, "\n", NULL);
392  }
393  }
394  fprintf(fd, "\n", NULL);
395  fclose(fd);
396 
397 
398 
399  avect = (double *) calloc( eln, sizeof(double));
400 
401 
402  if( avect == NULL )
403  return 1;
404 
405  for(y = 0; y < verpix; y++)
406  {
407  n=1;
408  for(x = 0; x < horpix; x++)
409  {
410  if ((x < horpix - blindpix) & (x > 1))
411  {
412  avect[n] = (double)mat[y * (horpix) + x];
413  n++;
414  }
415 
416  }
417 
418  CheckSpikes(0, avect, n - 1);
419 
420  for(x = 0; x < horpix; x++)
421  {
422  if ((x < horpix - blindpix) & (x > 1))
423  {
424  mat[y * horpix + x] = (unsigned int)avect[x - 1] ;
425  }
426 
427  }
428  }
429 
430  free(avect);
431 
432 
433 
434  fd = fopen("NoSpikes.tmp", "w");
435  if(fd < 0) return 1;
436 
437 // for(x = 0; x < horpix + 1; x++)
438  for(x = 0; x < horpix ; x++)
439  {
440  if ((x <= horpix - blindpix ) & (x > 1))
441  {
442  fprintf(fd, "%04u ", x);
443 
444  for(y = 0; y < verpix; y++)
445  {
446  fprintf(fd, "%05u ", mat[y * IDX + x]);
447  }
448  fprintf(fd, "\n", NULL);
449  }
450  }
451  fprintf(fd, "\n", NULL);
452  fclose(fd);
453 
454  return 0;
455 
456 }
doas DOAS
Definition: FFT.c:15
int IDX
Number of sensible horizontal pixels.
Definition: DAS_Spat.c:118
Definition: DOASdef.h:16
int CheckSpikes(int mod, double *tmp, int npix)
Definition: FFT.c:348
static double c2
Definition: SOLPOS.C:114
void four1(double data[], unsigned long nn, int isign)
Definition: FFT.c:26
int FilterData(unsigned short *mat, int horpix, int verpix, int filw, int bp)
Definition: FFT.c:250
unsigned int data[576]
Conversion data buffer 64 samples * 8 channels * 2 bytes.
Function prototypes.
int MMessageDialog(const char *t, const char *msg, const char *btn1, const char *btn2,...)
Function prototypes.
void realft(double data[], unsigned long n, int isign)
Definition: FFT.c:95
int SmoothingF(double *tmp, int npix, int pts)
Smoothing of 1D array.
Definition: FFT.c:151
#define SWAP(a, b)
Definition: FFT.c:24
int RemoveSpikes(int mod, unsigned short *mat, int horpix, int verpix, int blindpix)
Removes Spikes on a measure.
Definition: FFT.c:369
______________________________________________________________________________________
Generated on Mon Sep 18 2017 11:44:08 for DAS - Rel. 3.1.6 - 18/09/2017.