use of org.diirt.vtype.VStatistics in project org.csstudio.display.builder by kasemir.
the class ValueFormatter method format.
/**
* @return Value formatted into columns
*/
public String format(final VType value) {
final VTypeFormat format_for_this_value;
if (value instanceof VString || value instanceof VStringArray)
format_for_this_value = new StringVTypeFormat();
else {
if (Double.isNaN(VTypeHelper.toDouble(value))) {
if (min_max_column)
return Messages.Export_NoValueMarker + Messages.Export_Delimiter + Messages.Export_NoValueMarker + Messages.Export_Delimiter + Messages.Export_NoValueMarker;
else
return Messages.Export_NoValueMarker;
}
format_for_this_value = format;
}
final VStatistics stats = (value instanceof VStatistics) ? (VStatistics) value : null;
final StringBuilder buf = new StringBuilder();
if (stats != null)
// Show only the average, since min/max handled separately
format_for_this_value.format(stats.getAverage(), stats, buf);
else
format_for_this_value.format(value, buf);
// Optional min, max
if (min_max_column) {
buf.append(Messages.Export_Delimiter);
if (stats != null) {
// Turn min..max into negative & positive error
buf.append(stats.getAverage() - stats.getMin());
buf.append(Messages.Export_Delimiter);
buf.append(stats.getMax() - stats.getAverage());
} else {
buf.append(0);
buf.append(Messages.Export_Delimiter);
buf.append(0);
}
}
return buf.toString();
}
use of org.diirt.vtype.VStatistics in project org.csstudio.display.builder by kasemir.
the class FormulaItem method compute.
/**
* Evaluate formula for each input sample
* <p>
* Iterates over the input samples in a manner of spreadsheet or
* staircase-interpolation: An input with a time stamp is valid
* until there's a sample with a greater time stamp.
*/
private void compute() {
final List<PlotSample> result = new ArrayList<PlotSample>();
final Display display = ValueFactory.displayNone();
try {
// Prevent changes to formula & inputs
synchronized (this) {
// 'Current' value for each input or null when no more
// In computation loop, values is actually moved to the _next_
// value
final VType[] values = new VType[inputs.length];
// 'Current' numeric min/val/max of values
final double[] min = new double[inputs.length];
final double[] val = new double[inputs.length];
final double[] max = new double[inputs.length];
// Determine first sample for each input
boolean more_input = false;
for (int i = 0; i < values.length; i++) {
// Initially, none have any data
min[i] = val[i] = max[i] = Double.NaN;
// Is there an initial value for any input?
values[i] = inputs[i].first();
if (values[i] != null)
more_input = true;
}
// Compute result for each 'line in the spreadsheet'
Instant time;
while (more_input) {
// Find oldest time stamp of all the inputs
time = null;
for (int i = 0; i < values.length; i++) {
if (values[i] == null)
continue;
final Instant sample_time = VTypeHelper.getTimestamp(values[i]);
if (time == null || sample_time.compareTo(time) < 0)
time = sample_time;
}
if (time == null) {
// No input left with any data
more_input = false;
break;
}
// 'time' now defines the current spreadsheet line.
// Set min/max/val to sample from each input for that time.
// This might move values[i] resp. the inputs' iterators
// to the 'next' sample
boolean have_min_max = true;
for (int i = 0; i < values.length; i++) {
if (// No more data
values[i] == null) {
min[i] = val[i] = max[i] = Double.NaN;
have_min_max = false;
} else if (VTypeHelper.getTimestamp(values[i]).compareTo(time) <= 0) {
// Input is valid before-and-up-to 'time'
if (values[i] instanceof VStatistics) {
final VStatistics mmv = (VStatistics) values[i];
min[i] = mmv.getMin();
val[i] = mmv.getAverage();
max[i] = mmv.getMax();
} else {
min[i] = max[i] = Double.NaN;
val[i] = VTypeHelper.toDouble(values[i]);
// Use NaN for any non-number
if (Double.isInfinite(val[i]))
val[i] = Double.NaN;
have_min_max = false;
}
// Move to next input sample
values[i] = inputs[i].next();
} else {
// Just update the have_min_max flag
if (Double.isNaN(min[i]) || Double.isNaN(max[i]))
have_min_max = false;
}
}
// Set variables[] from val to get res_val
for (int i = 0; i < values.length; i++) variables[i].setValue(val[i]);
// Evaluate formula for these inputs
final double res_val = formula.eval();
final VType value;
if (have_min_max) {
// Set variables[] from min
for (int i = 0; i < values.length; i++) variables[i].setValue(min[i]);
final double res_min = formula.eval();
// Set variables[] from max
for (int i = 0; i < values.length; i++) variables[i].setValue(max[i]);
final double res_max = formula.eval();
value = new ArchiveVStatistics(time, AlarmSeverity.NONE, Messages.Formula, display, res_val, res_min, res_max, 0.0, 1);
} else {
// No min/max.
if (Double.isNaN(res_val))
value = new ArchiveVNumber(time, AlarmSeverity.INVALID, Messages.Formula, display, res_val);
else
value = new ArchiveVNumber(time, AlarmSeverity.NONE, ArchiveVType.STATUS_OK, display, res_val);
}
result.add(new PlotSample(Messages.Formula, value));
}
}
} catch (Exception ex) {
logger.log(Level.WARNING, "Error computing " + this, ex);
}
// Update PlotSamples
samples.set(result);
}
use of org.diirt.vtype.VStatistics in project org.csstudio.display.builder by kasemir.
the class SampleView method doCreatePartControl.
/**
* {@inheritDoc}
*/
@Override
protected void doCreatePartControl(final Composite parent) {
final GridLayout layout = new GridLayout(3, false);
parent.setLayout(layout);
// Item: pvs [Refresh]
Label l = new Label(parent, 0);
l.setText(Messages.SampleView_Item);
l.setLayoutData(new GridData());
items = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
items.setLayoutData(new GridData(SWT.FILL, 0, true, false));
items.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(final SelectionEvent e) {
widgetDefaultSelected(e);
}
@Override
public void widgetDefaultSelected(final SelectionEvent e) {
// Configure table to display samples of the selected model item
if (items.getSelectionIndex() == 0) {
sample_table.setInput(null);
return;
}
// / Skip initial "Select item" entry
final int selected = items.getSelectionIndex() - 1;
int index = 0;
for (ModelItem item : model.getItems()) {
if (index == selected) {
sample_table.setInput(item);
return;
}
++index;
}
Activator.getLogger().log(Level.WARNING, "Invalid item index " + selected);
}
});
final Button refresh = new Button(parent, SWT.PUSH);
refresh.setText(Messages.SampleView_Refresh);
refresh.setToolTipText(Messages.SampleView_RefreshTT);
refresh.setLayoutData(new GridData());
refresh.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
// Trigger GUI update
update(false);
}
});
// Sample Table
// TableColumnLayout requires this to be in its own container
final Composite table_parent = new Composite(parent, 0);
table_parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, layout.numColumns, 1));
final TableColumnLayout table_layout = new MinSizeTableColumnLayout(10);
table_parent.setLayout(table_layout);
sample_table = new TableViewer(table_parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION | SWT.VIRTUAL);
sample_table.setContentProvider(new SampleTableContentProvider());
final Table table = sample_table.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
// Time column
TableViewerColumn col = TableHelper.createColumn(table_layout, sample_table, Messages.TimeColumn, 90, 100);
col.setLabelProvider(new CellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
final PlotSample sample = (PlotSample) cell.getElement();
cell.setText(TimestampHelper.format(sample.getPosition()));
}
});
// Value column
col = TableHelper.createColumn(table_layout, sample_table, Messages.ValueColumn, 50, 100);
col.setLabelProvider(new CellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
final PlotSample sample = (PlotSample) cell.getElement();
cell.setText(format.format(sample.getVType()));
}
@Override
public String getToolTipText(Object element) {
final PlotSample sample = (PlotSample) element;
final VType value = sample.getVType();
// Show numbers in their 'natural' format which may differ from the Display settings
if (value instanceof VStatistics) {
final VStatistics mmd = (VStatistics) value;
return NLS.bind(Messages.SampleView_MinMaxValueTT, new String[] { Double.toString(mmd.getAverage()), Double.toString(mmd.getMin()), Double.toString(mmd.getMax()) });
} else if (value instanceof VNumber) {
final VNumber dbl = (VNumber) value;
return Double.toString(dbl.getValue().doubleValue());
} else
return VTypeHelper.toString(value);
}
});
// Severity column
col = TableHelper.createColumn(table_layout, sample_table, Messages.SeverityColumn, 90, 50);
col.setLabelProvider(new CellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
final PlotSample sample = (PlotSample) cell.getElement();
final VType value = sample.getVType();
final AlarmSeverity severity = VTypeHelper.getSeverity(value);
cell.setText(severity.toString());
if (severity == AlarmSeverity.NONE) {
cell.setBackground(null);
return;
}
final Display display = cell.getControl().getDisplay();
if (severity == AlarmSeverity.MAJOR)
cell.setBackground(display.getSystemColor(SWT.COLOR_RED));
else if (severity == AlarmSeverity.MINOR)
cell.setBackground(display.getSystemColor(SWT.COLOR_YELLOW));
else
cell.setBackground(display.getSystemColor(SWT.COLOR_GRAY));
}
});
// Status column
col = TableHelper.createColumn(table_layout, sample_table, Messages.StatusColumn, 90, 50);
col.setLabelProvider(new CellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
final PlotSample sample = (PlotSample) cell.getElement();
final VType value = sample.getVType();
cell.setText(VTypeHelper.getMessage(value));
}
});
// Sample Source column
col = TableHelper.createColumn(table_layout, sample_table, Messages.SampleView_Source, 90, 10);
col.setLabelProvider(new CellLabelProvider() {
@Override
public void update(final ViewerCell cell) {
final PlotSample sample = (PlotSample) cell.getElement();
cell.setText(sample.getSource());
}
});
ColumnViewerToolTipSupport.enableFor(sample_table);
// Be ignorant of any change of the current model after this view
// is disposed.
parent.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
if (model != null)
model.removeListener(model_listener);
}
});
}
Aggregations