Mercurial > hg > fxanalyse
comparison Allan.c @ 135:77539f2597b1
Code cleanup
author | Daniele Nicolodi <daniele.nicolodi@obspm.fr> |
---|---|
date | Wed, 22 Jan 2014 12:29:38 +0100 |
parents | bd28161e5ac2 |
children | 7b9cf3d4346e |
comparison
equal
deleted
inserted
replaced
134:bd28161e5ac2 | 135:77539f2597b1 |
---|---|
1 #include <ansi_c.h> | 1 #include <ansi_c.h> |
2 #include <userint.h> | 2 #include <userint.h> |
3 | 3 |
4 #include "YLCStuff.h" | 4 #include "YLCStuff.h" |
5 | 5 #include "FXAllan.h" |
6 #include "FXAllan.h" // Auto generated panel definitions and protypes | 6 #include "Allan.h" |
7 #include "Allan.h" // My own .h file, containing prototypes and definitions for the class Allan... | 7 |
8 | 8 #define DATAPOINT_COLOR VAL_RED |
9 | 9 #define ERRORBAR_COLOR VAL_RED |
10 | 10 |
11 // ******************* Member functions : constructor and destructor ************************* | 11 |
12 | 12 static void Allan_Reset(Allan_Data * Instance); |
13 int Allan_InitPanel(Allan_Data * Instance, const char * title, double Normalizer, int parent, int control) { | 13 static void Allan_Display(Allan_Data * Instance); |
14 | 14 |
15 int i ; | 15 |
16 | 16 void Allan_InitPanel(Allan_Data * Instance, const char *title, double normalization, int parent, int control) |
17 { | |
17 if ((Instance->AllanPanel = LoadPanel (0, "FXAllan.uir", ALLANPANEL)) < 0) | 18 if ((Instance->AllanPanel = LoadPanel (0, "FXAllan.uir", ALLANPANEL)) < 0) |
18 return -1; | 19 return; |
19 SetPanelAttribute(Instance->AllanPanel, ATTR_TITLE, title) ; | 20 |
20 SetPanelAttribute (Instance->AllanPanel, ATTR_CALLBACK_DATA, (void *)Instance); // the panel callback therefore knows which data structure it is associated to | 21 Allan_Reset(Instance); |
22 Instance->normalization = normalization; | |
23 Instance->autoscale = FALSE; | |
21 Instance->active = TRUE; | 24 Instance->active = TRUE; |
22 Instance->parent = parent; | 25 Instance->parent = parent; |
23 Instance->control = control; | 26 Instance->control = control; |
24 for (i=0 ; i<ALLAN_MAXPOINTSNUMBER ; i++) { | 27 |
25 Instance->AllanVar[i] = 0 ; | 28 SetPanelAttribute(Instance->AllanPanel, ATTR_TITLE, title); |
26 Instance->LastMean[i] = 0 ; | 29 SetPanelAttribute (Instance->AllanPanel, ATTR_CALLBACK_DATA, (void *)Instance); |
27 Instance->BlocksNumber[i] = 0 ; | |
28 Instance->CurrentAverage[i] = 0 ; | |
29 Instance->NbCurrentAverage[i] = 0 ; | |
30 } ; | |
31 Instance->Drift = 0 ; | |
32 DisplayPanel (Instance->AllanPanel); | 30 DisplayPanel (Instance->AllanPanel); |
33 SetCtrlVal(Instance->AllanPanel, ALLANPANEL_NORMALIZER, Normalizer) ; | 31 SetCtrlVal(Instance->AllanPanel, ALLANPANEL_NORMALIZER, normalization); |
34 return 0 ; | 32 } |
35 } | 33 |
36 | 34 |
37 | 35 void Allan_ClosePanel(Allan_Data * Instance) |
38 | 36 { |
39 int Allan_ClosePanel(Allan_Data * Instance) { | |
40 Instance->active = FALSE; | 37 Instance->active = FALSE; |
41 SetCtrlVal(Instance->parent, Instance->control, FALSE); | 38 SetCtrlVal(Instance->parent, Instance->control, FALSE); |
42 DiscardPanel (Instance->AllanPanel); | 39 DiscardPanel (Instance->AllanPanel); |
40 } | |
41 | |
42 | |
43 void Allan_AddFrequency(Allan_Data * Instance, double Freq) | |
44 { | |
45 /* total number of points used. used to calculate the drift rate */ | |
46 int N = 1 + Instance->BlocksNumber[0]; | |
47 double Mean = Instance->Mean; | |
48 double Drift = Instance->Drift; | |
49 double Normalizer = Instance->normalization; | |
50 | |
51 /* compute drift rate */ | |
52 if (N > 1) { | |
53 Instance->Drift = (Drift * (N - 2) + 6 * (Freq - Mean) / N) / (N + 1); | |
54 SetCtrlVal(Instance->AllanPanel, ALLANPANEL_DRIFT, Instance->Drift/Normalizer); | |
55 } | |
56 Instance->Mean = (Mean * (N - 1) + Freq) / N; | |
57 | |
58 /* compute allan deviation */ | |
59 for (int i = 0; i < ALLAN_MAXPOINTSNUMBER; i++) { | |
60 Instance->CurrentAverage[i] = (Instance->CurrentAverage[i]*Instance->NbCurrentAverage[i] + Freq) | |
61 /(Instance->NbCurrentAverage[i]+1); | |
62 Instance->NbCurrentAverage[i] +=1; | |
63 | |
64 if (Instance->NbCurrentAverage[i] >= pow(2,i) ) { | |
65 double CurrentMean = Instance->CurrentAverage[i]; | |
66 double LastMean = Instance->LastMean[i]; | |
67 N = Instance->BlocksNumber[i]; | |
68 N++; | |
69 Instance->CurrentAverage[i] = 0; | |
70 Instance->NbCurrentAverage[i] = 0; | |
71 if (N > 1) { | |
72 Instance->AllanVar[i] = (Instance->AllanVar[i]*(N-2) | |
73 +0.5*pow(CurrentMean-LastMean,2))/(N-1) ; | |
74 } else { // ie if N=1, which is realized for the first completed block | |
75 Instance->FirstMean[i] = CurrentMean; | |
76 } | |
77 Instance->LastMean[i] = CurrentMean; | |
78 Instance->BlocksNumber[i] = N; | |
79 } | |
80 } | |
81 | |
82 Allan_Display(Instance); | |
83 } | |
84 | |
85 | |
86 /* private */ | |
87 | |
88 static void Allan_Reset(Allan_Data *Instance) | |
89 { | |
90 memset(Instance->AllanVar, 0, sizeof(Instance->AllanVar)); | |
91 memset(Instance->FirstMean, 0, sizeof(Instance->FirstMean)); | |
92 memset(Instance->LastMean, 0, sizeof(Instance->LastMean)); | |
93 memset(Instance->BlocksNumber, 0, sizeof(Instance->BlocksNumber)); | |
94 memset(Instance->CurrentAverage, 0, sizeof(Instance->CurrentAverage)); | |
95 memset(Instance->NbCurrentAverage, 0, sizeof(Instance->NbCurrentAverage)); | |
96 Instance->Drift = 0; | |
97 Instance->Mean = 0; | |
98 } | |
99 | |
100 | |
101 static void Allan_Display(Allan_Data *Instance) | |
102 { | |
103 int i, N; | |
104 double X[ALLAN_MAXPOINTSNUMBER]; | |
105 double Y[ALLAN_MAXPOINTSNUMBER]; | |
106 double Normalizer = Instance->normalization; | |
107 double DriftTau, FirstFreq, LastFreq, Error; | |
108 int dedrift; | |
109 | |
110 GetCtrlVal(Instance->AllanPanel, ALLANPANEL_DEDRIFT, &dedrift); | |
111 | |
112 for (i = 0; i < ALLAN_MAXPOINTSNUMBER; i++) { | |
113 X[i] = pow(2, i); | |
114 if (dedrift) { | |
115 DriftTau = Instance->Drift * X[i]; | |
116 N = Instance->BlocksNumber[i]; | |
117 if (N>=2) { // if enough data to calculate AVAR for tau = 2^i*tau0, and therefore, AllanVar[i] is meaningful | |
118 FirstFreq = Instance->FirstMean[i]; | |
119 LastFreq = Instance->LastMean[i]; | |
120 Y[i] = sqrt(Instance->AllanVar[i]+DriftTau*(DriftTau/2-(LastFreq-FirstFreq)/(N-1)))/Normalizer; | |
121 // Not totaly sure it works... to be checked thoroughly | |
122 } | |
123 else { | |
124 Y[i] = 0; | |
125 } | |
126 } else { | |
127 Y[i] = sqrt(Instance->AllanVar[i])/Normalizer; | |
128 } | |
129 } | |
130 | |
131 DeleteGraphPlot(Instance->AllanPanel, ALLANPANEL_ALLANPLOT, -1, VAL_IMMEDIATE_DRAW); | |
132 PlotXY(Instance->AllanPanel, ALLANPANEL_ALLANPLOT, X, Y, ALLAN_MAXPOINTSNUMBER, | |
133 VAL_DOUBLE, VAL_DOUBLE, VAL_SCATTER, VAL_SOLID_SQUARE, VAL_SOLID, 1, DATAPOINT_COLOR); | |
134 | |
135 for (i = 0; i < ALLAN_MAXPOINTSNUMBER; i++) { | |
136 Error = 1/sqrt(Instance->BlocksNumber[i]); | |
137 PlotLine(Instance->AllanPanel, ALLANPANEL_ALLANPLOT, X[i], Y[i]*(1-Error), X[i], Y[i]*(1+Error), ERRORBAR_COLOR); | |
138 } | |
139 } | |
140 | |
141 | |
142 /* callbacks */ | |
143 | |
144 int CVICALLBACK Allan_CB_Reset(int panel, int control, int event, | |
145 void *callbackData, int eventData1, int eventData2) | |
146 { | |
147 switch(event) | |
148 { | |
149 case EVENT_COMMIT: | |
150 Allan_Data *data; | |
151 GetPanelAttribute(panel, ATTR_CALLBACK_DATA, &data); | |
152 Allan_Reset(data); | |
153 break; | |
154 } | |
43 return 0; | 155 return 0; |
44 } | 156 } |
45 | 157 |
46 | 158 |
47 | 159 int CVICALLBACK Allan_CB_ChangeYLim (int panel, int control, int event, |
48 // ******************** Member functions, callbacks (private) ******************************* | 160 void *callbackData, int eventData1, int eventData2) |
49 | 161 { |
50 | 162 switch (event) |
51 int CVICALLBACK Allan_CB_Reset(int panel, int control, int event, | 163 { |
52 void *callbackData, int eventData1, int eventData2) | 164 case EVENT_COMMIT: |
53 { | 165 int YMin, YMax; |
54 Allan_Data * Instance = NULL; | 166 GetCtrlVal(panel, ALLANPANEL_MIN, &YMin); |
55 | 167 GetCtrlVal(panel, ALLANPANEL_MAX, &YMax); |
56 switch(event) { | 168 if (YMin < YMax) { |
57 | 169 SetAxisScalingMode(panel, ALLANPANEL_ALLANPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, pow(10,(double)YMin), pow(10,(double)YMax) ); |
58 case EVENT_COMMIT: | 170 SetCtrlVal(panel, ALLANPANEL_CHECKBOX_AUTOSCALE, FALSE); |
59 GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &Instance); | 171 } |
60 Allan_Reset(Instance) ; | 172 break; |
61 break; | 173 } |
62 | |
63 case EVENT_RIGHT_CLICK: | |
64 | |
65 break; | |
66 } | |
67 | |
68 return 0; | 174 return 0; |
69 } | 175 } |
70 | 176 |
71 int CVICALLBACK Allan_CB_ChangeMax (int panel, int control, int event, | 177 |
178 int CVICALLBACK Allan_CB_ChangeAutoScale (int panel, int control, int event, | |
72 void *callbackData, int eventData1, int eventData2) | 179 void *callbackData, int eventData1, int eventData2) |
73 { | 180 { |
74 int YMin, YMax ; | 181 switch (event) |
75 | 182 { |
76 switch (event) | 183 case EVENT_COMMIT: |
77 { | 184 Allan_Data *data; |
78 case EVENT_COMMIT: | 185 GetPanelAttribute(panel, ATTR_CALLBACK_DATA, &data); |
79 GetCtrlVal(panel, ALLANPANEL_MIN, &YMin) ; | 186 GetCtrlVal(panel, control, &(data->normalization)); |
80 GetCtrlVal(panel, ALLANPANEL_MAX, &YMax) ; | 187 Allan_Display(data); |
81 if (YMin<YMax) { | 188 break; |
82 SetAxisScalingMode(panel, ALLANPANEL_ALLANPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, pow(10,(double)YMin), pow(10,(double)YMax) ) ; | 189 } |
83 SetCtrlVal(panel, ALLANPANEL_CHECKBOX_AUTOSCALE, FALSE) ; | |
84 } ; | |
85 break; | |
86 | |
87 case EVENT_RIGHT_CLICK: | |
88 | |
89 break; | |
90 } | |
91 return 0; | |
92 } | |
93 | |
94 int CVICALLBACK Allan_CB_ChangeMin (int panel, int control, int event, | |
95 void *callbackData, int eventData1, int eventData2) | |
96 { | |
97 int YMin, YMax ; | |
98 | |
99 switch (event) | |
100 { | |
101 case EVENT_COMMIT: | |
102 GetCtrlVal(panel, ALLANPANEL_MIN, &YMin) ; | |
103 GetCtrlVal(panel, ALLANPANEL_MAX, &YMax) ; | |
104 if (YMin<YMax ) { | |
105 SetAxisScalingMode(panel, ALLANPANEL_ALLANPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, pow(10,(double)YMin), pow(10,(double)YMax) ) ; | |
106 SetCtrlVal(panel, ALLANPANEL_CHECKBOX_AUTOSCALE, FALSE) ; | |
107 } ; | |
108 break; | |
109 | |
110 case EVENT_RIGHT_CLICK: | |
111 | |
112 break; | |
113 } | |
114 return 0; | |
115 } | |
116 | |
117 | |
118 int CVICALLBACK Allan_CB_ChangeAutoScale (int panel, int control, int event, | |
119 void *callbackData, int eventData1, int eventData2) | |
120 { | |
121 return 0; | 190 return 0; |
122 } | 191 } |
123 | 192 |
124 | 193 |
125 int CVICALLBACK Allan_CB_ChangeNormalizer (int panel, int control, int event, | 194 int CVICALLBACK Allan_CB_ChangeNormalization (int panel, int control, int event, |
126 void *callbackData, int eventData1, int eventData2) | 195 void *callbackData, int eventData1, int eventData2) |
127 { /* | 196 { |
128 bool AutoScale = FALSE; | 197 switch (event) |
129 int NotCare = 20000000 ; | 198 { |
130 double YMin = 10000000 , YMax = 64000000 ; | 199 case EVENT_COMMIT: |
131 | 200 Allan_Data *data; |
132 switch (event) | 201 GetPanelAttribute(panel, ATTR_CALLBACK_DATA, &data); |
133 { | 202 GetCtrlVal(panel, control, &(data->normalization)); |
134 case EVENT_COMMIT: | 203 Allan_Display(data); |
135 GetCtrlVal(panel, ALLANPANEL_CHECKBOX_AUTOSCALE, &AutoScale) ; | 204 break; |
136 if (AutoScale) { | 205 } |
137 SetAxisScalingMode(panel, ALLANPANEL_ALLANPLOT, VAL_LEFT_YAXIS, VAL_AUTOSCALE, YMin, YMax) ; | |
138 GetAxisScalingMode(panel, ALLANPANEL_ALLANPLOT,VAL_LEFT_YAXIS, &NotCare, &YMin, &YMax ) ; | |
139 SetCtrlVal(panel, ALLANPANEL_MIN, YMin); | |
140 SetCtrlVal(panel, ALLANPANEL_MAX, YMax); | |
141 } | |
142 else { | |
143 GetCtrlVal(panel, ALLANPANEL_MIN, &YMin); | |
144 GetCtrlVal(panel, ALLANPANEL_MAX, &YMax); | |
145 SetAxisScalingMode(panel, ALLANPANEL_ALLANPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, YMin, YMax) ; | |
146 } ; | |
147 break; | |
148 case EVENT_RIGHT_CLICK: | |
149 | |
150 break; | |
151 } */ | |
152 return 0; | 206 return 0; |
153 } | 207 } |
154 | 208 |
155 | 209 |
156 | |
157 // ******************** Member functions, public ***************************************** | |
158 | |
159 int Allan_Reset(Allan_Data * Instance) { | |
160 | |
161 int i ; | |
162 | |
163 for (i=0 ; i<ALLAN_MAXPOINTSNUMBER ; i++) { | |
164 Instance->AllanVar[i] = 0 ; | |
165 Instance->LastMean[i] = 0 ; | |
166 Instance->BlocksNumber[i] = 0 ; | |
167 Instance->CurrentAverage[i] = 0 ; | |
168 Instance->NbCurrentAverage[i] = 0 ; | |
169 } ; | |
170 | |
171 return 0 ; | |
172 | |
173 } | |
174 | |
175 | |
176 int Allan_AddFrequency(Allan_Data * Instance, double Freq) { | |
177 | |
178 int i, N; | |
179 double CurrentMean, LastMean, Drift, Mean, Normalizer ; | |
180 | |
181 N = Instance->BlocksNumber[0]+1 ; // the total number of points used, usefull to calculate drift rate | |
182 Mean = Instance->Mean ; | |
183 Drift = Instance->Drift ; | |
184 | |
185 GetCtrlVal(Instance->AllanPanel, ALLANPANEL_NORMALIZER, &Normalizer); | |
186 | |
187 if (N > 1) { // Drift measure needs at least 2 values ! | |
188 Instance->Drift = (Drift*(N-2) + 6*(Freq-Mean)/N)/(N+1) ; | |
189 SetCtrlVal(Instance->AllanPanel, ALLANPANEL_DRIFT, Instance->Drift/Normalizer ) ; | |
190 } | |
191 | |
192 // update mean value (usefull to calculate drift rate with linear regression incremental algorithm...) | |
193 Instance->Mean = (Mean*(N-1)+Freq)/N ; | |
194 | |
195 | |
196 for (i=0 ; i<ALLAN_MAXPOINTSNUMBER ; i++) { | |
197 Instance->CurrentAverage[i] = (Instance->CurrentAverage[i]*Instance->NbCurrentAverage[i] + Freq) | |
198 /(Instance->NbCurrentAverage[i]+1) ; | |
199 Instance->NbCurrentAverage[i] +=1 ; | |
200 | |
201 if (Instance->NbCurrentAverage[i] >= pow(2,i) ) { | |
202 | |
203 CurrentMean = Instance->CurrentAverage[i]; | |
204 LastMean = Instance->LastMean[i] ; | |
205 N = Instance->BlocksNumber[i] ; | |
206 N++ ; | |
207 Instance->CurrentAverage[i] = 0 ; | |
208 Instance->NbCurrentAverage[i] = 0 ; | |
209 if (N>1) { | |
210 Instance->AllanVar[i] = (Instance->AllanVar[i]*(N-2) | |
211 +0.5*pow(CurrentMean-LastMean,2))/(N-1) ; | |
212 } | |
213 else { // ie if N=1, which is realized for the first completed block | |
214 Instance->FirstMean[i] = CurrentMean ; | |
215 } ; | |
216 Instance->LastMean[i] = CurrentMean ; | |
217 Instance->BlocksNumber[i] = N ; | |
218 } ; | |
219 } ; | |
220 | |
221 Allan_Display(Instance, VAL_WHITE, VAL_BLUE) ; | |
222 | |
223 return 0 ; | |
224 } | |
225 | |
226 int Allan_Display (Allan_Data * Instance, int ColorPt, int ColorErrorBar){ | |
227 | |
228 int PointsNumber = ALLAN_MAXPOINTSNUMBER ; | |
229 int i, N ; | |
230 double X[ALLAN_MAXPOINTSNUMBER] ; | |
231 double Y[ALLAN_MAXPOINTSNUMBER] ; | |
232 double Normalizer, DriftTau, FirstFreq, LastFreq, Error ; | |
233 bool DeDrift ; | |
234 | |
235 GetCtrlVal(Instance->AllanPanel, ALLANPANEL_NORMALIZER, &Normalizer) ; | |
236 GetCtrlVal(Instance->AllanPanel, ALLANPANEL_DEDRIFT, &DeDrift) ; | |
237 | |
238 for (i=0 ; i<PointsNumber ; i++) { | |
239 X[i] = pow(2,i) ; | |
240 if (!DeDrift) { Y[i] = sqrt(Instance->AllanVar[i])/Normalizer ;} | |
241 else { | |
242 DriftTau = Instance->Drift*X[i] ; | |
243 N = Instance->BlocksNumber[i] ; | |
244 if (N>=2) { // if enough data to calculate AVAR for tau = 2^i*tau0, and therefore, AllanVar[i] is meaningful | |
245 FirstFreq = Instance->FirstMean[i] ; | |
246 LastFreq = Instance->LastMean[i] ; | |
247 Y[i] = sqrt(Instance->AllanVar[i]+DriftTau*(DriftTau/2-(LastFreq-FirstFreq)/(N-1)))/Normalizer ; | |
248 // Not totaly sure it works... to be checked thoroughly | |
249 } | |
250 else { Y[i] = 0 ; } ; | |
251 } ; | |
252 } ; | |
253 | |
254 DeleteGraphPlot(Instance->AllanPanel, ALLANPANEL_ALLANPLOT, -1, VAL_IMMEDIATE_DRAW) ; | |
255 PlotXY (Instance->AllanPanel, ALLANPANEL_ALLANPLOT, X, Y, PointsNumber, | |
256 VAL_DOUBLE, VAL_DOUBLE, VAL_SCATTER, VAL_SOLID_SQUARE, VAL_SOLID, 1, ColorPt); | |
257 | |
258 for (i=0 ; i<PointsNumber ; i++) { | |
259 Error = 1/sqrt(Instance->BlocksNumber[i]) ; | |
260 PlotLine (Instance->AllanPanel, ALLANPANEL_ALLANPLOT, X[i], Y[i]*(1-Error), X[i], Y[i]*(1+Error), ColorErrorBar); | |
261 } ; | |
262 | |
263 | |
264 return 0 ; | |
265 } | |
266 | |
267 int Allan_DisplayErrorBars (Allan_Data * Instance, int color){ | |
268 | |
269 int i; | |
270 double X[ALLAN_MAXPOINTSNUMBER] ; | |
271 double Val, Error, Normalizer; | |
272 | |
273 GetCtrlVal(Instance->AllanPanel, ALLANPANEL_NORMALIZER, &Normalizer) ; | |
274 for (i=0 ; i<ALLAN_MAXPOINTSNUMBER ; i++) { | |
275 X[i] = pow(2,i) ; | |
276 Val = sqrt(Instance->AllanVar[i])/Normalizer ; | |
277 Error = 1/sqrt(Instance->BlocksNumber[i]) ; | |
278 PlotLine (Instance->AllanPanel, ALLANPANEL_ALLANPLOT, X[i], Val*(1-Error), X[i], Val*(1+Error), color); | |
279 } ; | |
280 | |
281 return 0 ; | |
282 } | |
283 | |
284 int CVICALLBACK CB_GeneralAllanPanel (int panel, int event, void *callbackData, | 210 int CVICALLBACK CB_GeneralAllanPanel (int panel, int event, void *callbackData, |
285 int eventData1, int eventData2) | 211 int eventData1, int eventData2) |
286 { | 212 { |
287 Allan_Data * Instance = NULL; | 213 switch (event) |
288 | 214 { |
289 | |
290 switch (event) | |
291 { | |
292 case EVENT_GOT_FOCUS: | |
293 | |
294 break; | |
295 case EVENT_LOST_FOCUS: | |
296 | |
297 break; | |
298 case EVENT_CLOSE: | 215 case EVENT_CLOSE: |
299 GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &Instance); | 216 Allan_Data *data; |
300 Allan_ClosePanel(Instance) ; | 217 GetPanelAttribute(panel, ATTR_CALLBACK_DATA, &data); |
301 | 218 Allan_ClosePanel(data); |
302 break; | 219 break; |
303 } | 220 } |
304 return 0; | 221 return 0; |
305 } | 222 } |