Mercurial > hg > fxanalyse
diff Allan.c @ 0:d9aae7d7f2c6
Import
author | Daniele Nicolodi <daniele.nicolodi@obspm.fr> |
---|---|
date | Tue, 03 Jul 2012 10:38:59 +0200 |
parents | |
children | 0e9f95525a8f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Allan.c Tue Jul 03 10:38:59 2012 +0200 @@ -0,0 +1,303 @@ +#include <ansi_c.h> +#include <userint.h> + +#include "YLCStuff.h" + +#include "FXAllan.h" // Auto generated panel definitions and protypes +#include "Allan.h" // My own .h file, containing prototypes and definitions for the class Allan... + + + +// ******************* Member functions : constructor and destructor ************************* + +int Allan_InitPanel(Allan_Data * Instance, char * title, double Normalizer, void (*OnCloseFunc)(int)) { + + int i ; + + if ((Instance->AllanPanel = LoadPanel (0, "FXAllan.uir", ALLANPANEL)) < 0) + return -1; + SetPanelAttribute(Instance->AllanPanel, ATTR_TITLE, title) ; + SetPanelAttribute (Instance->AllanPanel, ATTR_CALLBACK_DATA, (void *)Instance); // the panel callback therefore knows which data structure it is associated to + Instance->OnClosePanel = OnCloseFunc ; + for (i=0 ; i<ALLAN_MAXPOINTSNUMBER ; i++) { + Instance->AllanVar[i] = 0 ; + Instance->LastMean[i] = 0 ; + Instance->BlocksNumber[i] = 0 ; + Instance->CurrentAverage[i] = 0 ; + Instance->NbCurrentAverage[i] = 0 ; + } ; + Instance->Drift = 0 ; + DisplayPanel (Instance->AllanPanel); + SetCtrlVal(Instance->AllanPanel, ALLANPANEL_NORMALIZER, Normalizer) ; + return 0 ; + } + + + +int Allan_ClosePanel(Allan_Data * Instance) { + Instance->OnClosePanel(Instance->AllanPanel) ; + DiscardPanel (Instance->AllanPanel); + return 0; + } + + + +// ******************** Member functions, callbacks (private) ******************************* + + +int CVICALLBACK Allan_CB_Reset(int panel, int control, int event, + void *callbackData, int eventData1, int eventData2) +{ + int i ; + Allan_Data * Instance = NULL; + + switch(event) { + + case EVENT_COMMIT: + GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &Instance); + Allan_Reset(Instance) ; + break; + + case EVENT_RIGHT_CLICK: + + break; + } + + return 0; +} + +int CVICALLBACK Allan_CB_ChangeMax (int panel, int control, int event, + void *callbackData, int eventData1, int eventData2) +{ + int YMin, YMax ; + + switch (event) + { + case EVENT_COMMIT: + GetCtrlVal(panel, ALLANPANEL_MIN, &YMin) ; + GetCtrlVal(panel, ALLANPANEL_MAX, &YMax) ; + if (YMin<YMax) { + SetAxisScalingMode(panel, ALLANPANEL_ALLANPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, pow(10,(double)YMin), pow(10,(double)YMax) ) ; + SetCtrlVal(panel, ALLANPANEL_CHECKBOX_AUTOSCALE, FALSE) ; + } ; + break; + + case EVENT_RIGHT_CLICK: + + break; + } + return 0; +} + +int CVICALLBACK Allan_CB_ChangeMin (int panel, int control, int event, + void *callbackData, int eventData1, int eventData2) +{ + int YMin, YMax ; + + switch (event) + { + case EVENT_COMMIT: + GetCtrlVal(panel, ALLANPANEL_MIN, &YMin) ; + GetCtrlVal(panel, ALLANPANEL_MAX, &YMax) ; + if (YMin<YMax ) { + SetAxisScalingMode(panel, ALLANPANEL_ALLANPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, pow(10,(double)YMin), pow(10,(double)YMax) ) ; + SetCtrlVal(panel, ALLANPANEL_CHECKBOX_AUTOSCALE, FALSE) ; + } ; + break; + + case EVENT_RIGHT_CLICK: + + break; + } + return 0; +} + + +int CVICALLBACK Allan_CB_ChangeAutoScale (int panel, int control, int event, + void *callbackData, int eventData1, int eventData2) +{ + return 0; +} + + +int CVICALLBACK Allan_CB_ChangeNormalizer (int panel, int control, int event, + void *callbackData, int eventData1, int eventData2) +{ /* + bool AutoScale = FALSE; + int NotCare = 20000000 ; + double YMin = 10000000 , YMax = 64000000 ; + + switch (event) + { + case EVENT_COMMIT: + GetCtrlVal(panel, ALLANPANEL_CHECKBOX_AUTOSCALE, &AutoScale) ; + if (AutoScale) { + SetAxisScalingMode(panel, ALLANPANEL_ALLANPLOT, VAL_LEFT_YAXIS, VAL_AUTOSCALE, YMin, YMax) ; + GetAxisScalingMode(panel, ALLANPANEL_ALLANPLOT,VAL_LEFT_YAXIS, &NotCare, &YMin, &YMax ) ; + SetCtrlVal(panel, ALLANPANEL_MIN, YMin); + SetCtrlVal(panel, ALLANPANEL_MAX, YMax); + } + else { + GetCtrlVal(panel, ALLANPANEL_MIN, &YMin); + GetCtrlVal(panel, ALLANPANEL_MAX, &YMax); + SetAxisScalingMode(panel, ALLANPANEL_ALLANPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, YMin, YMax) ; + } ; + break; + case EVENT_RIGHT_CLICK: + + break; + } */ + return 0; +} + + + +// ******************** Member functions, public ***************************************** + +int Allan_Reset(Allan_Data * Instance) { + + int i ; + + for (i=0 ; i<ALLAN_MAXPOINTSNUMBER ; i++) { + Instance->AllanVar[i] = 0 ; + Instance->LastMean[i] = 0 ; + Instance->BlocksNumber[i] = 0 ; + Instance->CurrentAverage[i] = 0 ; + Instance->NbCurrentAverage[i] = 0 ; + } ; + + return 0 ; + +} + + +int Allan_AddFrequency(Allan_Data * Instance, double Freq) { + + int i, N; + double CurrentMean, LastMean, Drift, Mean, Normalizer ; + + N = Instance->BlocksNumber[0]+1 ; // the total number of points used, usefull to calculate drift rate + Mean = Instance->Mean ; + Drift = Instance->Drift ; + + GetCtrlVal(Instance->AllanPanel, ALLANPANEL_NORMALIZER, &Normalizer); + + if (N > 1) { // Drift measure needs at least 2 values ! + Instance->Drift = (Drift*(N-2) + 6*(Freq-Mean)/N)/(N+1) ; + SetCtrlVal(Instance->AllanPanel, ALLANPANEL_DRIFT, Instance->Drift/Normalizer ) ; + } + + // update mean value (usefull to calculate drift rate with linear regression incremental algorithm...) + Instance->Mean = (Mean*(N-1)+Freq)/N ; + + + for (i=0 ; i<ALLAN_MAXPOINTSNUMBER ; i++) { + Instance->CurrentAverage[i] = (Instance->CurrentAverage[i]*Instance->NbCurrentAverage[i] + Freq) + /(Instance->NbCurrentAverage[i]+1) ; + Instance->NbCurrentAverage[i] +=1 ; + + if (Instance->NbCurrentAverage[i] >= pow(2,i) ) { + + CurrentMean = Instance->CurrentAverage[i]; + LastMean = Instance->LastMean[i] ; + N = Instance->BlocksNumber[i] ; + N++ ; + Instance->CurrentAverage[i] = 0 ; + Instance->NbCurrentAverage[i] = 0 ; + if (N>1) { + Instance->AllanVar[i] = (Instance->AllanVar[i]*(N-2) + +0.5*pow(CurrentMean-LastMean,2))/(N-1) ; + } + else { // ie if N=1, which is realized for the first completed block + Instance->FirstMean[i] = CurrentMean ; + } ; + Instance->LastMean[i] = CurrentMean ; + Instance->BlocksNumber[i] = N ; + } ; + } ; + + Allan_Display(Instance, VAL_WHITE, VAL_BLUE) ; + + return 0 ; +} + +int Allan_Display (Allan_Data * Instance, int ColorPt, int ColorErrorBar){ + + int PointsNumber = ALLAN_MAXPOINTSNUMBER ; + int i, N ; + double X[ALLAN_MAXPOINTSNUMBER] ; + double Y[ALLAN_MAXPOINTSNUMBER] ; + double Normalizer, DriftTau, FirstFreq, LastFreq, Error ; + bool DeDrift ; + + GetCtrlVal(Instance->AllanPanel, ALLANPANEL_NORMALIZER, &Normalizer) ; + GetCtrlVal(Instance->AllanPanel, ALLANPANEL_DEDRIFT, &DeDrift) ; + + for (i=0 ; i<PointsNumber ; i++) { + X[i] = pow(2,i) ; + if (!DeDrift) { Y[i] = sqrt(Instance->AllanVar[i])/Normalizer ;} + else { + DriftTau = Instance->Drift*X[i] ; + N = Instance->BlocksNumber[i] ; + if (N>=2) { // if enough data to calculate AVAR for tau = 2^i*tau0, and therefore, AllanVar[i] is meaningful + FirstFreq = Instance->FirstMean[i] ; + LastFreq = Instance->LastMean[i] ; + Y[i] = sqrt(Instance->AllanVar[i]+DriftTau*(DriftTau/2-(LastFreq-FirstFreq)/(N-1)))/Normalizer ; + // Not totaly sure it works... to be checked thoroughly + } + else { Y[i] = 0 ; } ; + } ; + } ; + + DeleteGraphPlot(Instance->AllanPanel, ALLANPANEL_ALLANPLOT, -1, VAL_IMMEDIATE_DRAW) ; + PlotXY (Instance->AllanPanel, ALLANPANEL_ALLANPLOT, X, Y, PointsNumber, + VAL_DOUBLE, VAL_DOUBLE, VAL_SCATTER, VAL_SOLID_SQUARE, VAL_SOLID, 1, ColorPt); + + for (i=0 ; i<PointsNumber ; i++) { + Error = 1/sqrt(Instance->BlocksNumber[i]) ; + PlotLine (Instance->AllanPanel, ALLANPANEL_ALLANPLOT, X[i], Y[i]*(1-Error), X[i], Y[i]*(1+Error), ColorErrorBar); + } ; + + + return 0 ; +} + +int Allan_DisplayErrorBars (Allan_Data * Instance, int color){ + + int i; + double X[ALLAN_MAXPOINTSNUMBER] ; + double Val, Error, Normalizer; + + GetCtrlVal(Instance->AllanPanel, ALLANPANEL_NORMALIZER, &Normalizer) ; + for (i=0 ; i<ALLAN_MAXPOINTSNUMBER ; i++) { + X[i] = pow(2,i) ; + Val = sqrt(Instance->AllanVar[i])/Normalizer ; + Error = 1/sqrt(Instance->BlocksNumber[i]) ; + PlotLine (Instance->AllanPanel, ALLANPANEL_ALLANPLOT, X[i], Val*(1-Error), X[i], Val*(1+Error), color); + } ; + + return 0 ; +} + +int CVICALLBACK CB_GeneralAllanPanel (int panel, int event, void *callbackData, + int eventData1, int eventData2) +{ + Allan_Data * Instance = NULL; + + + switch (event) + { + case EVENT_GOT_FOCUS: + + break; + case EVENT_LOST_FOCUS: + + break; + case EVENT_CLOSE: + GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &Instance); + Allan_ClosePanel(Instance) ; + + break; + } + return 0; +}