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;
+}