view Plot.c @ 67:0159abc1a9d8

Fix slope measurement For the update algorithm to work correclty the slope measurement must be updated before the mean measurement. Other code is affected by the same issue.
author Daniele Nicolodi <daniele.nicolodi@obspm.fr>
date Mon, 29 Oct 2012 14:48:08 +0100
parents 381da7b34cd8
children bd28161e5ac2
line wrap: on
line source


#include <ansi_c.h>
#include <userint.h>

#include "YLCStuff.h"
#include "FXAnalyse.h"

#include "FXPlot.h"   // Auto generated panel definitions and protypes
#include "Plot.h"	  // My own .h file, containing prototypes and definitions for the class Plot...



// ******************* Member functions : constructor and destructor **********************

int Plot_InitPanel(Plot_Data * Instance, char * title, double PlotMin, double PlotMax, void (*OnCloseFunc)(int) ) {
	
	if ((Instance->PlotPanel = LoadPanel (0, "FXPlot.uir", PLOTPANEL)) < 0)
	return -1;
	SetPanelAttribute(Instance->PlotPanel, ATTR_TITLE, title) ;  
	SetPanelAttribute (Instance->PlotPanel, ATTR_CALLBACK_DATA, (void *)Instance); // the panel callback therefore knows which data structure it is associated to 
	Instance->OnClosePanel = OnCloseFunc ;
	Instance->IndexPoint = 0 ;
	Instance->Mean = 0 ;
	Instance->Slope = 0;
	Instance->ADev = 0 ;
	Instance->Frequencies = calloc(MAXPOINTSNUMBER, sizeof(double)) ;
	DisplayPanel (Instance->PlotPanel);
	SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MIN, PlotMin) ;
	SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MAX, PlotMax) ;
	SetAxisScalingMode(Instance->PlotPanel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, PlotMin, PlotMax) ;
	return 0 ;
	}



int Plot_ClosePanel(Plot_Data * Instance) {
	free(Instance->Frequencies) ;
	Instance->OnClosePanel(Instance->PlotPanel) ;
	DiscardPanel (Instance->PlotPanel); 
	return 0;
	}
			
	

// ******************** Member functions, callbacks (private) *******************************

int CVICALLBACK CB_PlotEvent(int panel, int event, void *callbackData, int eventData1, int eventData2) {
	
	int VirtualKeyCode;
	int StepIndex;
	double Step;
	
	Plot_Data * Instance = NULL;
	
	switch (event)
	{
	case EVENT_CLOSE:
		GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &Instance);  
		Plot_ClosePanel(Instance) ;
		break;
	
	case EVENT_KEYPRESS:
		VirtualKeyCode = GetKeyPressEventVirtualKey(eventData2);
		switch (VirtualKeyCode)
		{
		case 2304: //ie right arrow
			GetCtrlIndex(panel, PLOTPANEL_SCALINGSTEP, &StepIndex);
			if (StepIndex<10){
				SetCtrlIndex(panel, PLOTPANEL_SCALINGSTEP, ++StepIndex) ;
				GetCtrlVal(panel, PLOTPANEL_SCALINGSTEP, &Step);
				SetCtrlAttribute(panel, PLOTPANEL_MIN, ATTR_INCR_VALUE, Step) ;
				SetCtrlAttribute(panel, PLOTPANEL_MAX, ATTR_INCR_VALUE, Step) ;
			};
			break;
		case 2048: //ie left arrow
			GetCtrlIndex(panel, PLOTPANEL_SCALINGSTEP, &StepIndex);
			if (StepIndex>0){
				SetCtrlIndex(panel, PLOTPANEL_SCALINGSTEP, --StepIndex) ;
				GetCtrlVal(panel, PLOTPANEL_SCALINGSTEP, &Step);
				SetCtrlAttribute(panel, PLOTPANEL_MIN, ATTR_INCR_VALUE, Step) ;
				SetCtrlAttribute(panel, PLOTPANEL_MAX, ATTR_INCR_VALUE, Step) ;
				};
			break;
		};
		break;
	}
	return 0;
}

int CVICALLBACK Plot_CB_ChangeMax (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	double YMin, YMax ;

	switch (event)
		{
		case EVENT_COMMIT:
			GetCtrlVal(panel, PLOTPANEL_MIN, &YMin) ;
			GetCtrlVal(panel, PLOTPANEL_MAX, &YMax) ;
			if (YMin<YMax) {
				SetAxisScalingMode(panel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, YMin, YMax) ;
				SetCtrlVal(panel, PLOTPANEL_CHECKBOX_AUTOSCALE, FALSE) ; 
				} ;
			break;
		case EVENT_RIGHT_CLICK:

			break;
		}
	return 0;
}

int CVICALLBACK Plot_CB_ChangeMin (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	double YMin, YMax ;
	
	switch (event)
		{
		case EVENT_COMMIT:
				GetCtrlVal(panel, PLOTPANEL_MIN, &YMin) ;
				GetCtrlVal(panel, PLOTPANEL_MAX, &YMax) ;
				if (YMin<YMax ) {     
					SetAxisScalingMode(panel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, YMin, YMax) ;
					SetCtrlVal(panel, PLOTPANEL_CHECKBOX_AUTOSCALE, FALSE) ;
					} ;
			break;
		case EVENT_RIGHT_CLICK:

			break;
		}
	return 0;
}


int CVICALLBACK Plot_CB_ChangeAutoScale (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, PLOTPANEL_CHECKBOX_AUTOSCALE, &AutoScale) ;
			if (AutoScale) {
				SetAxisScalingMode(panel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_AUTOSCALE, YMin, YMax) ;
				GetAxisScalingMode(panel, PLOTPANEL_FREQPLOT,VAL_LEFT_YAXIS, &NotCare, &YMin, &YMax ) ;
				SetCtrlVal(panel, PLOTPANEL_MIN, YMin);
				SetCtrlVal(panel, PLOTPANEL_MAX, YMax);
				}
			else {
				GetCtrlVal(panel, PLOTPANEL_MIN, &YMin);
				GetCtrlVal(panel, PLOTPANEL_MAX, &YMax);
				SetAxisScalingMode(panel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, YMin, YMax) ;
				} ;
			break;
		case EVENT_RIGHT_CLICK:

			break;
		}
	return 0;
} 

int  CVICALLBACK Plot_CB_ChangeScalingStep(int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	double ScalingStep ;

	switch (event)
		{
		case EVENT_COMMIT:
			GetCtrlVal(panel, PLOTPANEL_SCALINGSTEP, &ScalingStep) ;
			SetCtrlAttribute(panel, PLOTPANEL_MIN, ATTR_INCR_VALUE, ScalingStep) ;
			SetCtrlAttribute(panel, PLOTPANEL_MAX, ATTR_INCR_VALUE, ScalingStep) ;
			break;
		case EVENT_RIGHT_CLICK:
			break;
		}
	return 0;
}


// ******************** Member functions, public *******************************************

int Plot_AddFrequency(Plot_Data * Instance, double Freq) {

	double YMin = 10000000, YMax = 64000000, Mean = 0, ADev = 0 , Slope = 0 , Drift = 0 ;
	bool AutoScale, DeDrift ;
	int N = 0, NotCare ;

	// Retrieve previous values for mean, adev and slope
	Mean  = Instance->Mean ;
	Slope = Instance->Slope;
	ADev  = Instance->ADev; 
	
	// Correct Freq with drift (feed forward) if dedrift is on
	GetCtrlVal(Instance->PlotPanel, PLOTPANEL_CHECKBOX_DEDRIFT, &DeDrift) ;
	if(DeDrift) {
		GetCtrlVal(Instance->PlotPanel, PLOTPANEL_DEDRIFT, &Drift) ;
		Freq -= ((double) Instance->IndexPoint)*Drift ;
		} ;
	
	// Add Freq to graph plot
	Instance->Frequencies[Instance->IndexPoint++] = Freq ;
	N = Instance->IndexPoint ; // N is now the new number of points in the graph
	
	
	if (N > 1) {   // ADEV and SLOPE need at least 2 values !
		Instance->Slope = (Slope*(N-2) + 6*(Freq-Mean)/N)/(N+1) ;
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_SLOPE, Instance->Slope ) ;
		Instance->ADev = sqrt( ( ADev*ADev*(N-2) + 0.5*pow(Freq-Instance->Frequencies[N-2],2) ) / (N-1) ) ;
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_ADEV, Instance->ADev ) ;  	
		} ;
	Instance->Mean = (Mean*(N-1)+Freq)/N ; 
	SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MEAN, Instance->Mean);
	
	if (N > MAXPOINTSNUMBER - 2) { // If too many points recorded, restart new plot with new values of Mean, Slope and Adev
		Instance->IndexPoint = 0;
		Instance->Mean = 0;
		Instance->Slope = 0;
		Instance->ADev = 0;
		SetCtrlVal(Instance->PlotPanel,PLOTPANEL_MEAN, 0.) ;
		SetCtrlVal(Instance->PlotPanel,PLOTPANEL_SLOPE, 0.) ;
		SetCtrlVal(Instance->PlotPanel,PLOTPANEL_ADEV, 0.) ;
		} ;
	
	DeleteGraphPlot(Instance->PlotPanel, PLOTPANEL_FREQPLOT, -1,VAL_IMMEDIATE_DRAW) ;
	PlotY(Instance->PlotPanel, PLOTPANEL_FREQPLOT, Instance->Frequencies, Instance->IndexPoint, VAL_DOUBLE, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_BLUE) ; 
	GetCtrlVal(Instance->PlotPanel, PLOTPANEL_CHECKBOX_AUTOSCALE, &AutoScale) ;
	if (AutoScale) {
		GetAxisScalingMode(Instance->PlotPanel, PLOTPANEL_FREQPLOT,VAL_LEFT_YAXIS, &NotCare, &YMin, &YMax ) ;
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MIN, YMin);
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MAX, YMax);
		} ;
	return 0 ;
	}




int CVICALLBACK Plot_CB_Reset (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	Plot_Data * Instance = NULL;
	
	switch (event)
		{
		case EVENT_COMMIT:
			GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &Instance);
			Instance->IndexPoint = 0 ;
			Instance->Mean = 0 ;
			Instance->Slope = 0;
			Instance->ADev = 0 ;
			
			break;
		}
	return 0;
}


int CVICALLBACK Plot_CB_GetDrift (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	Plot_Data * Instance = NULL;
	bool DeDrift ;
	double Drift ;
	
	switch (event)
		{
		case EVENT_COMMIT:
			
			//Instance = ThisPlot(panel) ;
			GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &Instance);  
			GetCtrlVal(panel, PLOTPANEL_CHECKBOX_DEDRIFT, &DeDrift) ;
			
			if (!DeDrift) {
				SetCtrlVal(panel,PLOTPANEL_DEDRIFT,Instance->Slope) ;
				}
			else {
				GetCtrlVal(panel, PLOTPANEL_DEDRIFT, &Drift) ;
				Drift += Instance->Slope ;
				SetCtrlVal(panel, PLOTPANEL_DEDRIFT, Drift) ;
				
				Instance->IndexPoint = 0 ;
				Instance->Mean = 0 ;
				Instance->Slope = 0 ;
				Instance->ADev = 0 ;
				
				} ;
			
			
			break;
		}
	return 0;
}

int CVICALLBACK Plot_CB_ChangeDrift (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	bool DeDrift ;
	Plot_Data * Instance = NULL;
	
	switch (event)
		{
		case EVENT_COMMIT:
			GetCtrlVal(panel, PLOTPANEL_CHECKBOX_DEDRIFT, &DeDrift) ;
			if(DeDrift) { 
				
				//Instance = ThisPlot(panel) ;
				GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &Instance);  
			
				Instance->IndexPoint = 0 ;
				Instance->Mean = 0 ;
				Instance->Slope = 0 ;
				Instance->ADev = 0 ;
				
				} ;		

			break;
		}
	return 0;
}