changeset 137:792ac7151f0f

Fix Allan deviation linear drift contribution removal
author Daniele Nicolodi <daniele.nicolodi@obspm.fr>
date Wed, 22 Jan 2014 13:41:07 +0100
parents 7b9cf3d4346e
children 02044ad2749a
files Allan.c Allan.h
diffstat 2 files changed, 12 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/Allan.c	Wed Jan 22 12:29:58 2014 +0100
+++ b/Allan.c	Wed Jan 22 13:41:07 2014 +0100
@@ -68,8 +68,6 @@
 			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;
@@ -85,7 +83,6 @@
 static void Allan_Reset(Allan_Data *Instance)
 {
 	memset(Instance->AllanVar, 0, sizeof(Instance->AllanVar));
-	memset(Instance->FirstMean, 0, sizeof(Instance->FirstMean));
 	memset(Instance->LastMean, 0, sizeof(Instance->LastMean));
 	memset(Instance->BlocksNumber, 0, sizeof(Instance->BlocksNumber));
 	memset(Instance->CurrentAverage, 0, sizeof(Instance->CurrentAverage));
@@ -97,32 +94,29 @@
 	
 static void Allan_Display(Allan_Data *Instance)
 {
-	int i, N;
+	int i;
 	double X[ALLAN_NUM_DATAPOINTS];
 	double Y[ALLAN_NUM_DATAPOINTS];
-	double Normalizer = Instance->normalization;
-	double DriftTau, FirstFreq, LastFreq, Error;
+	double Error;
 	int dedrift;
 	
 	GetCtrlVal(Instance->AllanPanel, ALLANPANEL_DEDRIFT, &dedrift);
 	SetCtrlVal(Instance->AllanPanel, ALLANPANEL_DRIFT, Instance->Drift);
 	
 	for (i = 0; i < ALLAN_NUM_DATAPOINTS; i++) {
+		if (Instance->AllanVar[i] == 0.0)
+			break;
 		X[i] = pow(2, i);
+		/* remove  linear drift estimated contribution to the allan variance */
 		if (dedrift) {
-			DriftTau = Instance->Drift * X[i];
-			N = Instance->BlocksNumber[i];
-			if (N > 1) { // 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;
-			}
+			double corr = 0.5 * (Instance->Drift * X[i]) * (Instance->Drift * X[i]);
+			/* uncertainty in the estimate of the drift rate may over correct
+			   the estimated allan variance and result in a negative value. in
+			   this case we take the absolute value of the corrected value as
+			   the best estimator of the allan variance */
+			Y[i] = sqrt(fabs(Instance->AllanVar[i] - corr)) / Instance->normalization;
 		} else {
-			Y[i] = sqrt(Instance->AllanVar[i])/Normalizer;
+			Y[i] = sqrt(Instance->AllanVar[i]) / Instance->normalization;
 		}
 	}
 	
--- a/Allan.h	Wed Jan 22 12:29:58 2014 +0100
+++ b/Allan.h	Wed Jan 22 13:41:07 2014 +0100
@@ -11,7 +11,6 @@
 	int AllanPanel;									/* display panel handle */
 	double X[ALLAN_NUM_DATAPOINTS];
 	double AllanVar[ALLAN_NUM_DATAPOINTS];			/* Allan variance computed at tau = 2^(N tau0) */
-	double FirstMean[ALLAN_NUM_DATAPOINTS];			/* mean of the first block of 2^N data for which averaging was completed */
 	double LastMean[ALLAN_NUM_DATAPOINTS];			/* mean of the last block of 2^N data for which averaging was completed */
 	int BlocksNumber[ALLAN_NUM_DATAPOINTS];			/* number of 2^N data points blocks used for computing AVAR(2^(N tau0)) */
 	double CurrentAverage[ALLAN_NUM_DATAPOINTS];  	/* sum of the last P data points retrieved. P < 2^N */