comparison Allan.c @ 0:d9aae7d7f2c6

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