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 }