view Plot.c @ 232:52f882f39c16

Implement correction proportional to frequency in dedrift code Reorganize code and options handling
author Daniele Nicolodi <daniele.nicolodi@obspm.fr>
date Mon, 27 Oct 2014 18:08:17 +0100
parents a3494d2806ee
children
line wrap: on
line source

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

#include "utils.h"
#include "FXPlot.h"
#include "Plot.h"

#define PLOT_LINE_COLOR VAL_RED 

void Plot_InitPanel(Plot_Data *Instance, const char *title, double ymin, double ymax, int parent, int control)
{
	if ((Instance->PlotPanel = LoadPanel (0, "FXPlot.uir", PLOTPANEL)) < 0)
		return;
	
	SetPanelAttribute(Instance->PlotPanel, ATTR_TITLE, title);  
	SetPanelAttribute(Instance->PlotPanel, ATTR_CALLBACK_DATA, (void *)Instance);
	Instance->active = TRUE;
	Instance->parent = parent;
	Instance->control = control;
	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, ymin);
	SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MAX, ymax);
	
	if ((ymin != 0.0) && (ymax != 0.0)) {
		/* manual scaling */
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MIN, ymin);
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MAX, ymax);
		SetAxisScalingMode(Instance->PlotPanel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, ymin, ymax);
	} else {
		/* auto scaling */
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_CHECKBOX_AUTOSCALE, TRUE);
		SetAxisScalingMode(Instance->PlotPanel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_AUTOSCALE, 0, 0);
	}
}


void Plot_ClosePanel(Plot_Data * Instance)
{
	Instance->active = FALSE;
	free(Instance->Frequencies);
	SetCtrlVal(Instance->parent, Instance->control, FALSE);
	DiscardPanel(Instance->PlotPanel); 
}


void Plot_AddFrequency(Plot_Data * Instance, double Freq)
{
	double Drift = 0;
	int DeDrift;
	int N = 0;

	double Mean  = Instance->Mean;
	double Slope = Instance->Slope;
	double 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;
	
	if (N > 1) {
		/* adev and slope computation need at least 2 data points */
		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 too many points recorded restart */
	if (N > MAXPOINTSNUMBER - 2) {
		Instance->IndexPoint = 0;
		Instance->Mean = 0;
		Instance->Slope = 0;
		Instance->ADev = 0;
		SetCtrlVal(Instance->PlotPanel,PLOTPANEL_MEAN, 0.0);
		SetCtrlVal(Instance->PlotPanel,PLOTPANEL_SLOPE, 0.0);
		SetCtrlVal(Instance->PlotPanel,PLOTPANEL_ADEV, 0.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, PLOT_LINE_COLOR);
	
	int autoscale;
	GetCtrlVal(Instance->PlotPanel, PLOTPANEL_CHECKBOX_AUTOSCALE, &autoscale);
	if (autoscale) {
		/* update plot limits */
		double ymin, ymax;
		GetAxisScalingMode(Instance->PlotPanel, PLOTPANEL_FREQPLOT,VAL_LEFT_YAXIS, NULL, &ymin, &ymax);
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MIN, ymin);
		SetCtrlVal(Instance->PlotPanel, PLOTPANEL_MAX, ymax);
		/* adjust control limits */
		SetCtrlAttribute(Instance->PlotPanel, PLOTPANEL_MIN, ATTR_MAX_VALUE, ymax);
		SetCtrlAttribute(Instance->PlotPanel, PLOTPANEL_MAX, ATTR_MIN_VALUE, ymin);
	}
}


/* callbacks */

int CVICALLBACK CB_PlotEvent(int panel, int event,
		void *callbackData, int eventData1, int eventData2)
{
	switch (event)
	{
		case EVENT_CLOSE:
			Plot_Data *data;
			GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &data);
			Plot_ClosePanel(data);
			break;
	
		case EVENT_KEYPRESS:
			int keycode = GetKeyPressEventVirtualKey(eventData2);
			int index;
			double step;
			switch (keycode)
			{
				case 2304: /* right arrow */
					GetCtrlIndex(panel, PLOTPANEL_SCALINGSTEP, &index);
					if (index < 10) {
						SetCtrlIndex(panel, PLOTPANEL_SCALINGSTEP, ++index);
						GetCtrlVal(panel, PLOTPANEL_SCALINGSTEP, &step);
						SetCtrlAttribute(panel, PLOTPANEL_MIN, ATTR_INCR_VALUE, step);
						SetCtrlAttribute(panel, PLOTPANEL_MAX, ATTR_INCR_VALUE, step);
					}
					break;
				case 2048: /* left arrow */
					GetCtrlIndex(panel, PLOTPANEL_SCALINGSTEP, &index);
					if (index > 0) {
						SetCtrlIndex(panel, PLOTPANEL_SCALINGSTEP, --index);
						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_ChangeYLim (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);
			/* adjust control limits */
			SetCtrlAttribute(panel, PLOTPANEL_MIN, ATTR_MAX_VALUE, ymax);
			SetCtrlAttribute(panel, PLOTPANEL_MAX, ATTR_MIN_VALUE, ymin);
			/* disable autoscaling */
			SetCtrlVal(panel, PLOTPANEL_CHECKBOX_AUTOSCALE, FALSE);
			SetAxisScalingMode(panel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, ymin, ymax);
			break;
	}
	return 0;
}


int CVICALLBACK Plot_CB_ChangeAutoScale (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	int autoscale = FALSE;
	double ymin, ymax;
	
	switch (event)
	{
		case EVENT_COMMIT:
			GetCtrlVal(panel, PLOTPANEL_CHECKBOX_AUTOSCALE, &autoscale);
			if (autoscale) {
				SetAxisScalingMode(panel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_AUTOSCALE, 0, 0);
				GetAxisScalingMode(panel, PLOTPANEL_FREQPLOT,VAL_LEFT_YAXIS, NULL, &ymin, &ymax);
				SetCtrlVal(panel, PLOTPANEL_MIN, ymin);
				SetCtrlVal(panel, PLOTPANEL_MAX, ymax);
				/* adjust control limits */
				SetCtrlAttribute(panel, PLOTPANEL_MIN, ATTR_MAX_VALUE, ymax);
				SetCtrlAttribute(panel, PLOTPANEL_MAX, ATTR_MIN_VALUE, ymin);
			} else {
				GetCtrlVal(panel, PLOTPANEL_MIN, &ymin);
				GetCtrlVal(panel, PLOTPANEL_MAX, &ymax);
				SetAxisScalingMode(panel, PLOTPANEL_FREQPLOT, VAL_LEFT_YAXIS, VAL_MANUAL, ymin, ymax);
			}
			break;
	}
	return 0;
} 


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

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


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


int CVICALLBACK Plot_CB_GetDrift (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	Plot_Data *data;
	int dedrift;
	double drift;
	
	switch (event)
	{
		case EVENT_COMMIT:
			GetPanelAttribute(panel, ATTR_CALLBACK_DATA, &data);  
			GetCtrlVal(panel, PLOTPANEL_CHECKBOX_DEDRIFT, &dedrift);
			if (dedrift) {
				GetCtrlVal(panel, PLOTPANEL_DEDRIFT, &drift);
				drift += data->Slope;
				SetCtrlVal(panel, PLOTPANEL_DEDRIFT, drift);
				data->IndexPoint = 0;
				data->Mean = 0;
				data->Slope = 0;
				data->ADev = 0;
			} else
				SetCtrlVal(panel,PLOTPANEL_DEDRIFT, data->Slope);
			break;
	}
	return 0;
}


int CVICALLBACK Plot_CB_ChangeDrift (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	int dedrift;
	Plot_Data *data;
	
	switch (event)
	{
		case EVENT_COMMIT:
			GetCtrlVal(panel, PLOTPANEL_CHECKBOX_DEDRIFT, &dedrift);
			if (dedrift) {
				GetPanelAttribute (panel, ATTR_CALLBACK_DATA, &data);
				data->IndexPoint = 0;
				data->Mean = 0;
				data->Slope = 0;
				data->ADev = 0;
			}
			break;
	}
	return 0;
}