Mercurial > hg > fxanalyse
view Allan.c @ 45:b47b97cfd050
Fix output frequency read back in DDS Fox driver
The FTW registry value was read back wrong due to an integer overflow in the
conversion from bytes string to double. This should fix the "jumps" seen in the
application of the frequency dedrifting.
author | Daniele Nicolodi <daniele.nicolodi@obspm.fr> |
---|---|
date | Wed, 10 Oct 2012 12:14:01 +0200 |
parents | d9aae7d7f2c6 |
children | 0e9f95525a8f |
line wrap: on
line source
#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; }