From 8f9c8df9e7d847e1880b059faf1f1ef511dba863 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Fri, 24 Feb 2017 10:31:25 +0000 Subject: [PATCH 1/4] Created a Validation Results view http://jira.diamond.ac.uk/browse/DAQ-463 --- .../org/eclipse/scanning/api/IValidator.java | 14 + .../scanning/api/device/DeviceResponse.java | 2 + .../scanning/api/event/scan/DeviceAction.java | 7 +- .../scanning/api/malcolm/IMalcolmDevice.java | 10 +- .../api/malcolm/message/MalcolmMessage.java | 13 + .../connector/epics/EpicsV4MessageMapper.java | 3 + .../META-INF/MANIFEST.MF | 3 +- .../icons/report.png | Bin 0 -> 493 bytes org.eclipse.scanning.device.ui/plugin.xml | 7 + .../device/ui/device/DetectorView.java | 60 ++++- .../device/ui/points/ValidateResults.java | 34 +++ .../device/ui/points/ValidateResultsView.java | 239 ++++++++++++++++++ .../ui/view/DelegatingSelectionProvider.java | 2 +- .../event/remote/_RunnableDevice.java | 13 + .../example/malcolm/ExampleMalcolmDevice.java | 26 +- .../malcolm/core/AbstractMalcolmDevice.java | 2 +- .../scanning/malcolm/core/MalcolmDevice.java | 14 +- .../scanning/sequencer/SubscanModerator.java | 2 +- .../nexus/MalcolmNexusScanFileManager.java | 2 +- 19 files changed, 424 insertions(+), 29 deletions(-) create mode 100644 org.eclipse.scanning.device.ui/icons/report.png create mode 100644 org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ValidateResults.java create mode 100644 org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ValidateResultsView.java diff --git a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/IValidator.java b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/IValidator.java index 00c5f029d..8fef0ad84 100644 --- a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/IValidator.java +++ b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/IValidator.java @@ -47,4 +47,18 @@ default void validate(T model) throws ValidationException, InstantiationExceptio default void setService(IValidatorService vservice) { } + + /** + * Same as Validaiton method above but returns any results sent back by validation. + * + * @param model + * @return + * @throws ValidationException + * @throws InstantiationException + * @throws IllegalAccessException + */ + default Object validateWithReturn(T model) throws ValidationException, InstantiationException, IllegalAccessException { + validate(model); + return null; // They should implement a validation which throws an exception + } } diff --git a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/device/DeviceResponse.java b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/device/DeviceResponse.java index aca359b41..7db0109ab 100644 --- a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/device/DeviceResponse.java +++ b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/device/DeviceResponse.java @@ -178,6 +178,8 @@ private static void processRunnables(DeviceRequest request, IRunnableDeviceServi tdevice.terminate(action.to()); } else if (action==DeviceAction.VALIDATE) { device.validate(request.getDeviceModel()); + } else if (action==DeviceAction.VALIDATEWITHRETURN) { + request.setDeviceValue(device.validateWithReturn(request.getDeviceModel())); } else if (action==DeviceAction.CONFIGURE) { device.configure(request.getDeviceModel()); } else if (action==DeviceAction.RUN) { diff --git a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/event/scan/DeviceAction.java b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/event/scan/DeviceAction.java index c29deea1b..72f4716bb 100644 --- a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/event/scan/DeviceAction.java +++ b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/event/scan/DeviceAction.java @@ -47,7 +47,12 @@ public enum DeviceAction { /** * Disable device, stopping all activity. */ - DISABLE; + DISABLE, + + /** + * Validate, with an expectation that the result will be returned + */ + VALIDATEWITHRETURN; public static DeviceAction as(TerminationPreference pref) { switch(pref) { diff --git a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/malcolm/IMalcolmDevice.java b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/malcolm/IMalcolmDevice.java index 9a949dee2..881eba16a 100644 --- a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/malcolm/IMalcolmDevice.java +++ b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/malcolm/IMalcolmDevice.java @@ -17,6 +17,7 @@ import org.eclipse.scanning.api.device.IAttributableDevice; import org.eclipse.scanning.api.device.IRunnableEventDevice; import org.eclipse.scanning.api.points.IPointGenerator; +import org.eclipse.scanning.api.scan.ScanningException; /** @@ -67,17 +68,12 @@ public interface IMalcolmDevice extends IRunnableEventDevice, IMalcolmEven */ public boolean isLocked() throws MalcolmDeviceException ; - /** - * Gets the value of an attribute on the device - */ - public A getAttributeValue(String attribute) throws MalcolmDeviceException; - /** * Returns the axes that this malcolm device can move. * @return - * @throws MalcolmDeviceException + * @throws ScanningException */ - public Set getAxesToMove() throws MalcolmDeviceException; + public Set getAxesToMove() throws ScanningException; /** * Set the point generator for the malcolm device. diff --git a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/malcolm/message/MalcolmMessage.java b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/malcolm/message/MalcolmMessage.java index 318d52241..42eee8ac9 100644 --- a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/malcolm/message/MalcolmMessage.java +++ b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/malcolm/message/MalcolmMessage.java @@ -36,6 +36,7 @@ public class MalcolmMessage { private String message; private Object arguments; private Object value; + private Object rawValue; public Type getType() { return type; @@ -69,6 +70,7 @@ public int hashCode() { result = prime * result + ((param == null) ? 0 : param.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode()); result = prime * result + ((value == null) ? 0 : value.hashCode()); + result = prime * result + ((rawValue == null) ? 0 : rawValue.hashCode()); return result; } @@ -115,6 +117,11 @@ public boolean equals(Object obj) { return false; } else if (!value.equals(other.value)) return false; + if (rawValue == null) { + if (other.rawValue != null) + return false; + } else if (!rawValue.equals(other.rawValue)) + return false; return true; } public Object getArguments() { @@ -162,4 +169,10 @@ public String getEndpoint() { public void setEndpoint(String endPoint) { this.endpoint = endPoint; } + public Object getRawValue() { + return rawValue; + } + public void setRawValue(Object rawValue) { + this.rawValue = rawValue; + } } diff --git a/org.eclipse.scanning.connector.epics/src/org/eclipse/scanning/connector/epics/EpicsV4MessageMapper.java b/org.eclipse.scanning.connector.epics/src/org/eclipse/scanning/connector/epics/EpicsV4MessageMapper.java index 1c4cd0faf..2d42ef783 100644 --- a/org.eclipse.scanning.connector.epics/src/org/eclipse/scanning/connector/epics/EpicsV4MessageMapper.java +++ b/org.eclipse.scanning.connector.epics/src/org/eclipse/scanning/connector/epics/EpicsV4MessageMapper.java @@ -163,6 +163,7 @@ public MalcolmMessage convertCallPVStructureToMalcolmMessage(PVStructure structu result.setType(Type.RETURN); result.setEndpoint(message.getEndpoint()); result.setId(message.getId()); + result.setRawValue(structure.toString()); if (structure.getStructure().getID().startsWith(ERROR_TYPE)) { result.setType(Type.ERROR); @@ -182,6 +183,7 @@ public MalcolmMessage convertSubscribeUpdatePVStructureToMalcolmMessage(PVStruct result.setType(Type.UPDATE); result.setEndpoint(message.getEndpoint()); result.setId(message.getId()); + result.setRawValue(structure.toString()); Object returnedObject = getEndpointObjectFromPVStructure(structure, message.getEndpoint()); @@ -196,6 +198,7 @@ public MalcolmMessage convertGetPVStructureToMalcolmMessage(PVStructure structur result.setType(Type.RETURN); result.setEndpoint(message.getEndpoint()); result.setId(message.getId()); + result.setRawValue(structure.toString()); if (structure.getStructure().getID().startsWith(ERROR_TYPE)) { result.setType(Type.ERROR); diff --git a/org.eclipse.scanning.device.ui/META-INF/MANIFEST.MF b/org.eclipse.scanning.device.ui/META-INF/MANIFEST.MF index 95ba99849..f306cb71f 100644 --- a/org.eclipse.scanning.device.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.scanning.device.ui/META-INF/MANIFEST.MF @@ -16,7 +16,8 @@ Require-Bundle: org.eclipse.ui;bundle-version="3.107.0", org.eclipse.dawnsci.analysis.dataset;bundle-version="1.0.0", org.eclipse.richbeans.widgets.file;bundle-version="1.0.0", org.eclipse.scanning.api;bundle-version="1.0.0", - org.eclipse.richbeans.annot;bundle-version="1.0.0" + org.eclipse.richbeans.annot;bundle-version="1.0.0", + org.eclipse.scanning.event.ui;bundle-version="1.0.0" Import-Package: org.osgi.framework;version="1.8.0", org.osgi.service.event;version="1.3.1", org.slf4j;version="1.7.2" diff --git a/org.eclipse.scanning.device.ui/icons/report.png b/org.eclipse.scanning.device.ui/icons/report.png new file mode 100644 index 0000000000000000000000000000000000000000..aa8bbe927c1eb7a2cc5fa29983466680bebe6f1c GIT binary patch literal 493 zcmV?HEro3PS8=0b(H_miqkjvK*fo%Ne5b;unTH4DT6qfUIXAV>m$$ jfEq>$0EO~rfB*vk=-5p8Qb9hP00000NkvXXu0mjf)~VTZ literal 0 HcmV?d00001 diff --git a/org.eclipse.scanning.device.ui/plugin.xml b/org.eclipse.scanning.device.ui/plugin.xml index 29463911a..9db243d4c 100644 --- a/org.eclipse.scanning.device.ui/plugin.xml +++ b/org.eclipse.scanning.device.ui/plugin.xml @@ -39,6 +39,13 @@ id="org.eclipse.scanning.device.ui.scan.executeView" name="Run"> + + iconMap; - + private DelegatingSelectionProvider selectionProvider; + // Services private IRunnableDeviceService dservice; @@ -122,7 +131,8 @@ public void createPartControl(Composite parent) { } viewer.setInput(new Object()); - getSite().setSelectionProvider(viewer); + selectionProvider = new DelegatingSelectionProvider(viewer); + getSite().setSelectionProvider(selectionProvider); createActions(); initializeToolBar(); @@ -332,12 +342,58 @@ protected void configure() { try { IRunnableDevice device = dservice.getRunnableDevice(info.getName()); Object model = info.getModel(); + + // Pass null to 'clear' the validation results view + selectionProvider.fireSelection(new StructuredSelection(new ValidateResults(info.getName(), null))); + + Object validateReturn = device.validateWithReturn(model); + + ValidateResults validateResults = new ValidateResults(info.getName(), validateReturn); + + try { + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + try { + if (PageUtil.getPage().findView(ValidateResultsView.ID) == null) { + IViewPart viewPart = PageUtil.getPage().showView(ValidateResultsView.ID); + if (viewPart instanceof ValidateResultsView) { + ValidateResultsView validateResultsView = (ValidateResultsView)viewPart; + validateResultsView.update(validateResults); + } + } else { + PageUtil.getPage().showView(ValidateResultsView.ID); + } + } catch (PartInitException e) { + e.printStackTrace(); + } + } + } + ); + } catch (Exception e) { + logger.warn("Unable to show validate results view", e); + } + + selectionProvider.fireSelection(new StructuredSelection(validateResults)); + device.configure(model); } catch (ScanningException ne) { ErrorDialog.openError(getViewSite().getShell(), "Configure Failed", "The configure of '"+info.getName()+"' failed", new Status(IStatus.ERROR, "org.eclipse.scanning.device.ui", ne.getMessage(), ne)); logger.error("Cannot configure '"+info.getName()+"'", ne); + } catch (ValidationException ne) { + ErrorDialog.openError(getViewSite().getShell(), "Configure Failed", "The configure of '"+info.getName()+"' failed", + new Status(IStatus.ERROR, "org.eclipse.scanning.device.ui", ne.getMessage(), ne)); + logger.error("Cannot configure '"+info.getName()+"'", ne); + } catch (InstantiationException ne) { + ErrorDialog.openError(getViewSite().getShell(), "Configure Failed", "The configure of '"+info.getName()+"' failed", + new Status(IStatus.ERROR, "org.eclipse.scanning.device.ui", ne.getMessage(), ne)); + logger.error("Cannot configure '"+info.getName()+"'", ne); + } catch (IllegalAccessException ne) { + ErrorDialog.openError(getViewSite().getShell(), "Configure Failed", "The configure of '"+info.getName()+"' failed", + new Status(IStatus.ERROR, "org.eclipse.scanning.device.ui", ne.getMessage(), ne)); + logger.error("Cannot configure '"+info.getName()+"'", ne); } } diff --git a/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ValidateResults.java b/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ValidateResults.java new file mode 100644 index 000000000..524052433 --- /dev/null +++ b/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ValidateResults.java @@ -0,0 +1,34 @@ +package org.eclipse.scanning.device.ui.points; + +/** + * Class to contain validation results for display in the UI + * + * @author Matt Taylor + * + */ +public class ValidateResults { + private String deviceName; + private Object results; + + public ValidateResults(String deviceName, Object results) { + this.deviceName = deviceName; + this.results = results; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public Object getResults() { + return results; + } + + public void setResults(Object results) { + this.results = results; + } + +} diff --git a/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ValidateResultsView.java b/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ValidateResultsView.java new file mode 100644 index 000000000..ef1406b4e --- /dev/null +++ b/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ValidateResultsView.java @@ -0,0 +1,239 @@ +package org.eclipse.scanning.device.ui.points; + +import java.util.Date; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IContributionManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StyledString; +import org.eclipse.jface.viewers.StyledString.Styler; +import org.eclipse.scanning.device.ui.Activator; +import org.eclipse.scanning.device.ui.ScanningPerspective; +import org.eclipse.scanning.device.ui.util.PageUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.TextStyle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.part.ViewPart; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * A view which attempts to pick up selection events + * from calling validate on a device, and display the + * results of the validation to a user + * + * @author Matt Taylor + * + */ +public class ValidateResultsView extends ViewPart implements ISelectionListener { + + public static final String ID = "org.eclipse.scanning.device.ui.scan.validateResultsView"; //$NON-NLS-1$ + private static final Logger logger = LoggerFactory.getLogger(ValidateResultsView.class); + + // UI + private StyledText text; + + public ValidateResultsView() { + PageUtil.getPage(getSite()).addSelectionListener(this); + } + + /** + * Create contents of the view part. + * @param parent + */ + @Override + public void createPartControl(Composite parent) { + + Composite container = new Composite(parent, SWT.NONE); + container.setLayout(new GridLayout(1, false)); + + this.text = new StyledText(container, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + text.setBackground(text.getDisplay().getSystemColor(SWT.COLOR_WHITE)); + text.getParent().layout(new Control[]{text}); + + // We force the scan view to exist. It might be the one to return the compound model + // that we will use. + ScanningPerspective.createKeyPlayers(); + + createActions(); + } + + /** + * Create the actions + */ + private void createActions() { + final IContributionManager man = getViewSite().getActionBars().getToolBarManager(); + + final Action restart = new Action("Clear", Activator.getImageDescriptor("icons/layers-stack.png")) { + public void run() { + clear(); + } + }; + man.add(restart); + + final MenuManager menuMan = new MenuManager(); + menuMan.add(restart); + + text.setMenu(menuMan.createContextMenu(text)); + } + + @Override + public void dispose() { + if (PageUtil.getPage(getSite())!=null) PageUtil.getPage(getSite()).removeSelectionListener(this); + super.dispose(); + } + + private void clear() { + setThreadSafeText(text, new StyledString("")); + } + + @Override + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + if (selection instanceof IStructuredSelection) { + Object ob = ((IStructuredSelection)selection).getFirstElement(); + + if (ob instanceof ValidateResults) { + ValidateResults validationResults = (ValidateResults)ob; + update(validationResults); + } + + } + } + + /** + * Method for updating the display with the validation results + * @param results the ValidationResults object + */ + public void update(ValidateResults results) { + if (results == null) return; + + try { + + StyledString styledString = new StyledString(); + + styledString.append("Results received from '"); + styledString.append(results.getDeviceName(), FontStyler.BOLD); + styledString.append("' at "); + styledString.append(new Date(System.currentTimeMillis()).toString(), StyledString.COUNTER_STYLER); + styledString.append("\n"); + + styledString.append(appendResultsToStyledString(results)); + + setThreadSafeText(text, styledString); + return; + + } catch (Exception ne) { + logger.error("Cannot create validation results", ne); + if (ne.getMessage()!=null) { + setThreadSafeText(text, ne.getMessage()); + } else { + setThreadSafeText(text, ne.toString()); + } + } + } + + /** + * Turn the results into a styled string for display to user, highlighting key values + * @param results The ValidationResults + * @return a StyledString to display on the view + */ + private StyledString appendResultsToStyledString(ValidateResults results) { + StyledString styledString = new StyledString(); + if (results.getResults() != null) { + if (results.getResults() instanceof String) { + // Parse out key information from the raw PVStructure string + String resultString = (String)results.getResults(); + + styledString.append(resultString); + + int durationIndex = resultString.indexOf("double duration"); + if (durationIndex != -1) { + int indexOfNewLine = resultString.substring(durationIndex).indexOf("\n"); + if (indexOfNewLine == -1) { + indexOfNewLine = resultString.substring(durationIndex).length() - 1; + } + styledString.setStyle(durationIndex + "double".length(), indexOfNewLine - "double".length(), FontStyler.BOLD); + } + + int axesToMoveIndex = resultString.indexOf("string[] axesToMove"); + if (axesToMoveIndex != -1) { + int indexOfNewLine = resultString.substring(axesToMoveIndex).indexOf("\n"); + if (indexOfNewLine == -1) { + indexOfNewLine = resultString.substring(axesToMoveIndex).length(); + } + styledString.setStyle(axesToMoveIndex + "string[]".length(), indexOfNewLine - "string[]".length(), FontStyler.BOLD); + } + + } else { + // not a string, just print out the results object + styledString.append(results.getResults().toString()); + } + } + + return styledString; + + } + + /** + * Set the text of the display from a String object + * @param text The StyledText object on the display to set + * @param string The text with which to set the display to + */ + private void setThreadSafeText(StyledText text, String string) { + setThreadSafeText(text, new StyledString(string)); + } + + /** + * Set the text of the display from a StyledString object + * @param text The StyledText object on the display to set + * @param styledString The text with which to set the display to in StyledString format + */ + private void setThreadSafeText(StyledText text, StyledString styledString) { + if (text.isDisposed()) return; + text.getDisplay().syncExec(new Runnable() { + public void run() { + if (text.isDisposed()) return; + text.setText(styledString.toString()); + text.setStyleRanges(styledString.getStyleRanges()); + } + }); + } + + @Override + public void setFocus() { + if (text!=null && !text.isDisposed()) text.setFocus(); + } + + /** + * Class for styling text for display on the view + * @author vtu42223 + * + */ + private static class FontStyler extends Styler { + + public static final Styler BOLD = new FontStyler(new Font(null, "Dialog", 10, SWT.BOLD)); + + private Font font; + + public FontStyler(Font toSet) { + this.font = toSet; + } + + @Override + public void applyStyles(TextStyle textStyle) { + textStyle.font = font; + } + } + +} diff --git a/org.eclipse.scanning.event.ui/src/org/eclipse/scanning/event/ui/view/DelegatingSelectionProvider.java b/org.eclipse.scanning.event.ui/src/org/eclipse/scanning/event/ui/view/DelegatingSelectionProvider.java index 1f597689e..60576c955 100644 --- a/org.eclipse.scanning.event.ui/src/org/eclipse/scanning/event/ui/view/DelegatingSelectionProvider.java +++ b/org.eclipse.scanning.event.ui/src/org/eclipse/scanning/event/ui/view/DelegatingSelectionProvider.java @@ -20,7 +20,7 @@ import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableViewer; -class DelegatingSelectionProvider implements ISelectionProvider, ISelectionChangedListener { +public class DelegatingSelectionProvider implements ISelectionProvider, ISelectionChangedListener { private Set listeners; private ISelectionProvider wrapped; diff --git a/org.eclipse.scanning.event/src/org/eclipse/scanning/event/remote/_RunnableDevice.java b/org.eclipse.scanning.event/src/org/eclipse/scanning/event/remote/_RunnableDevice.java index 33622d2cc..bf1a5b459 100644 --- a/org.eclipse.scanning.event/src/org/eclipse/scanning/event/remote/_RunnableDevice.java +++ b/org.eclipse.scanning.event/src/org/eclipse/scanning/event/remote/_RunnableDevice.java @@ -102,6 +102,19 @@ public void validate(M model) throws ValidationException { } } + @Override + public Object validateWithReturn(M model) throws ValidationException { + try { + DeviceRequest res = requester.post(new DeviceRequest(info.getName(), DeviceAction.VALIDATEWITHRETURN, model)); + res.checkException(); + return res.getDeviceValue(); + } catch (ValidationException ve) { + throw ve; + } catch (Exception ne) { + throw new ValidationException(ne); + } + } + @SuppressWarnings("unchecked") @Override public DeviceState getDeviceState() throws ScanningException { diff --git a/org.eclipse.scanning.example/src/org/eclipse/scanning/example/malcolm/ExampleMalcolmDevice.java b/org.eclipse.scanning.example/src/org/eclipse/scanning/example/malcolm/ExampleMalcolmDevice.java index e00daa5bb..6ad787c19 100644 --- a/org.eclipse.scanning.example/src/org/eclipse/scanning/example/malcolm/ExampleMalcolmDevice.java +++ b/org.eclipse.scanning.example/src/org/eclipse/scanning/example/malcolm/ExampleMalcolmDevice.java @@ -146,26 +146,30 @@ public void request(PVStructure args, RPCResponseCallback callback) return; } - if (methodName.equals("configure")) { + + Structure mapStructure = fieldCreate.createFieldBuilder(). + setId("malcolm:core/Map:1.0"). + createStructure(); + PVStructure returnPvStructure = pvDataCreate.createPVStructure(mapStructure); + + if (methodName.equals("validate")) { + returnPvStructure = args; + } else if (methodName.equals("configure")) { pvRecord.getPVStructure().getSubField(PVString.class, "state.value").put("CONFIGURING"); } else if (methodName.equals("run")) { pvRecord.getPVStructure().getSubField(PVString.class, "state.value").put("RUNNING"); + try { + Thread.sleep(2000); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } } - try { - Thread.sleep(2000); - } catch (InterruptedException e1) { - e1.printStackTrace(); - } pvRecord.getPVStructure().getSubField(PVString.class, "state.value").put("READY"); - Structure mapStructure = fieldCreate.createFieldBuilder(). - setId("malcolm:core/Map:1.0"). - createStructure(); - pvRecord.releaseControl(); - callback.requestDone(statusOk, pvDataCreate.createPVStructure(mapStructure)); + callback.requestDone(statusOk, returnPvStructure); return; } diff --git a/org.eclipse.scanning.malcolm.core/src/org/eclipse/scanning/malcolm/core/AbstractMalcolmDevice.java b/org.eclipse.scanning.malcolm.core/src/org/eclipse/scanning/malcolm/core/AbstractMalcolmDevice.java index d004da3a2..507ed2e18 100644 --- a/org.eclipse.scanning.malcolm.core/src/org/eclipse/scanning/malcolm/core/AbstractMalcolmDevice.java +++ b/org.eclipse.scanning.malcolm.core/src/org/eclipse/scanning/malcolm/core/AbstractMalcolmDevice.java @@ -175,7 +175,7 @@ protected void sendEvent(MalcolmEventBean event) throws Exception { } @Override - public Set getAxesToMove() throws MalcolmDeviceException { + public Set getAxesToMove() throws ScanningException { String[] axesToMove = (String[]) getAttributeValue(ATTRIBUTE_NAME_AXES_TO_MOVE); return new HashSet<>(Arrays.asList(axesToMove)); } diff --git a/org.eclipse.scanning.malcolm.core/src/org/eclipse/scanning/malcolm/core/MalcolmDevice.java b/org.eclipse.scanning.malcolm.core/src/org/eclipse/scanning/malcolm/core/MalcolmDevice.java index 7b9c7a152..27fca5a88 100644 --- a/org.eclipse.scanning.malcolm.core/src/org/eclipse/scanning/malcolm/core/MalcolmDevice.java +++ b/org.eclipse.scanning.malcolm.core/src/org/eclipse/scanning/malcolm/core/MalcolmDevice.java @@ -379,22 +379,30 @@ public boolean isDeviceBusy() throws MalcolmDeviceException { @Override public void validate(M params) throws ValidationException { + validateWithReturn(params); + } + + @Override + public Object validateWithReturn(M params) throws ValidationException { if (Boolean.getBoolean("org.eclipse.scanning.malcolm.skipvalidation")) { logger.warn("Skipping Malcolm Validate"); - return; + return null; } final EpicsMalcolmModel epicsModel = createEpicsMalcolmModel(params); - + MalcolmMessage reply = null; try { final MalcolmMessage msg = connectionDelegate.createCallMessage("validate", epicsModel); - final MalcolmMessage reply = connector.send(this, msg); + reply = connector.send(this, msg); if (reply.getType()==Type.ERROR) { throw new ValidationException("Error from Malcolm Device Connection: " + reply.getMessage()); } + } catch (MalcolmDeviceException mde) { throw new ValidationException(mde); } + + return reply.getRawValue(); } @Override diff --git a/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/SubscanModerator.java b/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/SubscanModerator.java index 84bb1138b..17627a0e6 100644 --- a/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/SubscanModerator.java +++ b/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/SubscanModerator.java @@ -132,7 +132,7 @@ private void moderate(Iterable generator, List> de this.outerIterable = gservice.createCompoundGenerator(compoundModel.clone(outer)); } - private List getAxes(List> detectors) throws MalcolmDeviceException { + private List getAxes(List> detectors) throws ScanningException { List ret = new ArrayList<>(); for (IRunnableDevice device : detectors) { // TODO Deal with the axes of other subscan devices as they arise. diff --git a/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/nexus/MalcolmNexusScanFileManager.java b/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/nexus/MalcolmNexusScanFileManager.java index 7d042c416..1f34abd04 100644 --- a/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/nexus/MalcolmNexusScanFileManager.java +++ b/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/nexus/MalcolmNexusScanFileManager.java @@ -111,7 +111,7 @@ private Set getMalcolmControlledAxes() throws ScanningException { private Set getAxesToMove(IRunnableDevice device) { try { return ((IMalcolmDevice) device).getAxesToMove(); - } catch (MalcolmDeviceException e) { + } catch (ScanningException e) { throw new RuntimeException(e); } } From 15a1b2e430ff62917529c237ae6d04c327f89a48 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Fri, 24 Feb 2017 11:32:07 +0000 Subject: [PATCH 2/4] SonarQube fixes http://jira.diamond.ac.uk/browse/DAQ-463 --- .../org/eclipse/scanning/api/IValidator.java | 12 +-- .../device/ui/device/DetectorView.java | 56 +++++-------- .../device/ui/points/ValidateResultsView.java | 83 ++++++++++++------- .../example/malcolm/ExampleMalcolmDevice.java | 6 +- .../nexus/MalcolmNexusScanFileManager.java | 1 - 5 files changed, 85 insertions(+), 73 deletions(-) diff --git a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/IValidator.java b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/IValidator.java index 8fef0ad84..ccd59f747 100644 --- a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/IValidator.java +++ b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/IValidator.java @@ -49,16 +49,18 @@ default void setService(IValidatorService vservice) { } /** - * Same as Validaiton method above but returns any results sent back by validation. + * Same as Validation method above but returns any results sent back by validation. * * @param model * @return * @throws ValidationException - * @throws InstantiationException - * @throws IllegalAccessException */ - default Object validateWithReturn(T model) throws ValidationException, InstantiationException, IllegalAccessException { - validate(model); + default Object validateWithReturn(T model) throws ValidationException { + try { + validate(model); + } catch (InstantiationException | IllegalAccessException e) { + throw new ValidationException(e); + } return null; // They should implement a validation which throws an exception } } diff --git a/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/device/DetectorView.java b/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/device/DetectorView.java index e1479d4f4..a8e42fd2a 100644 --- a/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/device/DetectorView.java +++ b/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/device/DetectorView.java @@ -350,52 +350,36 @@ protected void configure() { ValidateResults validateResults = new ValidateResults(info.getName(), validateReturn); - try { - PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - try { - if (PageUtil.getPage().findView(ValidateResultsView.ID) == null) { - IViewPart viewPart = PageUtil.getPage().showView(ValidateResultsView.ID); - if (viewPart instanceof ValidateResultsView) { - ValidateResultsView validateResultsView = (ValidateResultsView)viewPart; - validateResultsView.update(validateResults); - } - } else { - PageUtil.getPage().showView(ValidateResultsView.ID); - } - } catch (PartInitException e) { - e.printStackTrace(); - } - } - } - ); - } catch (Exception e) { - logger.warn("Unable to show validate results view", e); - } + showValidationResultsView(validateResults); selectionProvider.fireSelection(new StructuredSelection(validateResults)); device.configure(model); - } catch (ScanningException ne) { + } catch (ScanningException|ValidationException ne) { ErrorDialog.openError(getViewSite().getShell(), "Configure Failed", "The configure of '"+info.getName()+"' failed", new Status(IStatus.ERROR, "org.eclipse.scanning.device.ui", ne.getMessage(), ne)); logger.error("Cannot configure '"+info.getName()+"'", ne); - } catch (ValidationException ne) { - ErrorDialog.openError(getViewSite().getShell(), "Configure Failed", "The configure of '"+info.getName()+"' failed", - new Status(IStatus.ERROR, "org.eclipse.scanning.device.ui", ne.getMessage(), ne)); - logger.error("Cannot configure '"+info.getName()+"'", ne); - } catch (InstantiationException ne) { - ErrorDialog.openError(getViewSite().getShell(), "Configure Failed", "The configure of '"+info.getName()+"' failed", - new Status(IStatus.ERROR, "org.eclipse.scanning.device.ui", ne.getMessage(), ne)); - logger.error("Cannot configure '"+info.getName()+"'", ne); - } catch (IllegalAccessException ne) { - ErrorDialog.openError(getViewSite().getShell(), "Configure Failed", "The configure of '"+info.getName()+"' failed", - new Status(IStatus.ERROR, "org.eclipse.scanning.device.ui", ne.getMessage(), ne)); - logger.error("Cannot configure '"+info.getName()+"'", ne); } } + + private void showValidationResultsView(ValidateResults validateResults) { + PlatformUI.getWorkbench().getDisplay().asyncExec(() -> { + try { + if (PageUtil.getPage().findView(ValidateResultsView.ID) == null) { + IViewPart viewPart = PageUtil.getPage().showView(ValidateResultsView.ID); + if (viewPart instanceof ValidateResultsView) { + ValidateResultsView validateResultsView = (ValidateResultsView)viewPart; + validateResultsView.update(validateResults); + } + } else { + PageUtil.getPage().showView(ValidateResultsView.ID); + } + } catch (PartInitException e) { + logger.warn("Unable to show validate results view " + e); + } + }); + } private DeviceInformation getSelection() { if (viewer.getSelection() == null || viewer.getSelection().isEmpty()) return null; diff --git a/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ValidateResultsView.java b/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ValidateResultsView.java index ef1406b4e..a8b858c66 100644 --- a/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ValidateResultsView.java +++ b/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ValidateResultsView.java @@ -90,7 +90,9 @@ public void run() { @Override public void dispose() { - if (PageUtil.getPage(getSite())!=null) PageUtil.getPage(getSite()).removeSelectionListener(this); + if (PageUtil.getPage(getSite())!=null) { + PageUtil.getPage(getSite()).removeSelectionListener(this); + } super.dispose(); } @@ -116,7 +118,9 @@ public void selectionChanged(IWorkbenchPart part, ISelection selection) { * @param results the ValidationResults object */ public void update(ValidateResults results) { - if (results == null) return; + if (results == null) { + return; + } try { @@ -152,28 +156,15 @@ private StyledString appendResultsToStyledString(ValidateResults results) { StyledString styledString = new StyledString(); if (results.getResults() != null) { if (results.getResults() instanceof String) { - // Parse out key information from the raw PVStructure string + // Print out all the results from the raw PVStructure string, but style key information String resultString = (String)results.getResults(); - styledString.append(resultString); - int durationIndex = resultString.indexOf("double duration"); - if (durationIndex != -1) { - int indexOfNewLine = resultString.substring(durationIndex).indexOf("\n"); - if (indexOfNewLine == -1) { - indexOfNewLine = resultString.substring(durationIndex).length() - 1; - } - styledString.setStyle(durationIndex + "double".length(), indexOfNewLine - "double".length(), FontStyler.BOLD); - } + // Style the duration + adjustStyleOfDuration(styledString, resultString); - int axesToMoveIndex = resultString.indexOf("string[] axesToMove"); - if (axesToMoveIndex != -1) { - int indexOfNewLine = resultString.substring(axesToMoveIndex).indexOf("\n"); - if (indexOfNewLine == -1) { - indexOfNewLine = resultString.substring(axesToMoveIndex).length(); - } - styledString.setStyle(axesToMoveIndex + "string[]".length(), indexOfNewLine - "string[]".length(), FontStyler.BOLD); - } + // Style the axes to move + adjustStyleOfAxesToMove(styledString, resultString); } else { // not a string, just print out the results object @@ -184,6 +175,38 @@ private StyledString appendResultsToStyledString(ValidateResults results) { return styledString; } + + /** + * Adjust the style of the duration section of the styled string if it has one + * @param styledString + * @param resultString + */ + private void adjustStyleOfDuration(StyledString styledString, String resultString) { + int durationIndex = resultString.indexOf("double duration"); + if (durationIndex != -1) { + int indexOfNewLine = resultString.substring(durationIndex).indexOf('\n'); + if (indexOfNewLine == -1) { + indexOfNewLine = resultString.substring(durationIndex).length() - 1; + } + styledString.setStyle(durationIndex + "double".length(), indexOfNewLine - "double".length(), FontStyler.BOLD); + } + } + + /** + * Adjust the style of the AxesToMove section of the styled string if it has one + * @param styledString + * @param resultString + */ + private void adjustStyleOfAxesToMove(StyledString styledString, String resultString) { + int axesToMoveIndex = resultString.indexOf("string[] axesToMove"); + if (axesToMoveIndex != -1) { + int indexOfNewLine = resultString.substring(axesToMoveIndex).indexOf('\n'); + if (indexOfNewLine == -1) { + indexOfNewLine = resultString.substring(axesToMoveIndex).length(); + } + styledString.setStyle(axesToMoveIndex + "string[]".length(), indexOfNewLine - "string[]".length(), FontStyler.BOLD); + } + } /** * Set the text of the display from a String object @@ -200,19 +223,23 @@ private void setThreadSafeText(StyledText text, String string) { * @param styledString The text with which to set the display to in StyledString format */ private void setThreadSafeText(StyledText text, StyledString styledString) { - if (text.isDisposed()) return; - text.getDisplay().syncExec(new Runnable() { - public void run() { - if (text.isDisposed()) return; - text.setText(styledString.toString()); - text.setStyleRanges(styledString.getStyleRanges()); - } + if (text.isDisposed()) { + return; + } + text.getDisplay().syncExec(() -> { + if (text.isDisposed()) { + return; + } + text.setText(styledString.toString()); + text.setStyleRanges(styledString.getStyleRanges()); }); } @Override public void setFocus() { - if (text!=null && !text.isDisposed()) text.setFocus(); + if (text!=null && !text.isDisposed()) { + text.setFocus(); + } } /** diff --git a/org.eclipse.scanning.example/src/org/eclipse/scanning/example/malcolm/ExampleMalcolmDevice.java b/org.eclipse.scanning.example/src/org/eclipse/scanning/example/malcolm/ExampleMalcolmDevice.java index 6ad787c19..874f759af 100644 --- a/org.eclipse.scanning.example/src/org/eclipse/scanning/example/malcolm/ExampleMalcolmDevice.java +++ b/org.eclipse.scanning.example/src/org/eclipse/scanning/example/malcolm/ExampleMalcolmDevice.java @@ -152,11 +152,11 @@ public void request(PVStructure args, RPCResponseCallback callback) createStructure(); PVStructure returnPvStructure = pvDataCreate.createPVStructure(mapStructure); - if (methodName.equals("validate")) { + if ("validate".equals(methodName)) { returnPvStructure = args; - } else if (methodName.equals("configure")) { + } else if ("configure".equals(methodName)) { pvRecord.getPVStructure().getSubField(PVString.class, "state.value").put("CONFIGURING"); - } else if (methodName.equals("run")) { + } else if ("run".equals(methodName)) { pvRecord.getPVStructure().getSubField(PVString.class, "state.value").put("RUNNING"); try { Thread.sleep(2000); diff --git a/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/nexus/MalcolmNexusScanFileManager.java b/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/nexus/MalcolmNexusScanFileManager.java index 1f34abd04..ad276ebce 100644 --- a/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/nexus/MalcolmNexusScanFileManager.java +++ b/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/nexus/MalcolmNexusScanFileManager.java @@ -26,7 +26,6 @@ import org.eclipse.scanning.api.device.AbstractRunnableDevice; import org.eclipse.scanning.api.device.IRunnableDevice; import org.eclipse.scanning.api.malcolm.IMalcolmDevice; -import org.eclipse.scanning.api.malcolm.MalcolmDeviceException; import org.eclipse.scanning.api.scan.ScanningException; import org.eclipse.scanning.api.scan.models.ScanModel; import org.eclipse.scanning.sequencer.ServiceHolder; From 837628f959609fc10ccf6e7732f5d365ac1d7c70 Mon Sep 17 00:00:00 2001 From: Matthew Dickie Date: Thu, 23 Feb 2017 17:33:41 +0000 Subject: [PATCH 3/4] [DAQ-474]: share ScanInformation between ScanProcess and AcquisitionDevice --- .../scanning/api/scan/ScanEstimator.java | 8 +++---- .../scanning/api/scan/ScanInformation.java | 7 +++++++ .../scanning/api/scan/models/ScanModel.java | 11 ++++++++++ .../device/ui/points/ExecuteView.java | 2 +- .../scanning/sequencer/AcquisitionDevice.java | 21 ++++++++++++------- .../scanning/server/servlet/ScanProcess.java | 16 +++++++------- 6 files changed, 45 insertions(+), 20 deletions(-) diff --git a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/scan/ScanEstimator.java b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/scan/ScanEstimator.java index 1ebc2ea45..82efed1ff 100644 --- a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/scan/ScanEstimator.java +++ b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/scan/ScanEstimator.java @@ -53,7 +53,7 @@ public class ScanEstimator { /** * Estimated time of scan */ - private final long scanTime; + private final long estimatedScanTime; /** * @@ -112,7 +112,7 @@ public ScanEstimator(IPointGenerator gen, Map detectors, long this.size = getEstimatedSize(gen); this.rank = gen.iterator().next().getScanRank(); // The rank of the scan is constant this.timePerPoint = timePerPoint; - this.scanTime = size*timePerPoint; + this.estimatedScanTime = size*timePerPoint; } private int getEstimatedSize(IPointGenerator gen) throws GeneratorException { @@ -140,8 +140,8 @@ public void setTimePerPoint(long timePerPoint) { this.timePerPoint = timePerPoint; } - public long getScanTime() { - return scanTime; + public long getEstimatedScanTime() { + return estimatedScanTime; } public int getRank() { diff --git a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/scan/ScanInformation.java b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/scan/ScanInformation.java index 1626f3e66..c05050e35 100644 --- a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/scan/ScanInformation.java +++ b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/scan/ScanInformation.java @@ -34,6 +34,7 @@ public class ScanInformation { private transient ScanEstimator estimator; private int[] shape; private ScanMode scanMode; + private long estimatedScanTime; public ScanInformation() { @@ -127,6 +128,12 @@ public int[] getShape() { shape = estimator!=null ? estimator.getShape() : null; return shape; } + + public long getEstimatedScanTime() { + if (estimatedScanTime > 0) return estimatedScanTime; + estimatedScanTime = estimator != null ? estimator.getEstimatedScanTime() : 0; + return estimatedScanTime; + } public void setShape(int[] shape) { this.shape = shape; diff --git a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/scan/models/ScanModel.java b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/scan/models/ScanModel.java index e044404c3..d4a71fa86 100644 --- a/org.eclipse.scanning.api/src/org/eclipse/scanning/api/scan/models/ScanModel.java +++ b/org.eclipse.scanning.api/src/org/eclipse/scanning/api/scan/models/ScanModel.java @@ -22,6 +22,7 @@ import org.eclipse.scanning.api.device.IRunnableDevice; import org.eclipse.scanning.api.event.scan.ScanBean; import org.eclipse.scanning.api.points.IPosition; +import org.eclipse.scanning.api.scan.ScanInformation; /** * A Model describing a scan to be performed. @@ -80,6 +81,8 @@ public class ScanModel { */ private List annotationParticipants; + private ScanInformation scanInformation; + public ScanModel() { this(null); } @@ -240,4 +243,12 @@ public void setAnnotationParticipants(List annotationParticipants) { this.annotationParticipants = annotationParticipants; } + public ScanInformation getScanInformation() { + return scanInformation; + } + + public void setScanInformation(ScanInformation scanInformation) { + this.scanInformation = scanInformation; + } + } diff --git a/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ExecuteView.java b/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ExecuteView.java index ad711aee6..0546e816f 100644 --- a/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ExecuteView.java +++ b/org.eclipse.scanning.device.ui/src/org/eclipse/scanning/device/ui/points/ExecuteView.java @@ -509,7 +509,7 @@ private void update(IProgressMonitor monitor) { try { final ScanEstimator estimator = new ScanEstimator(ServiceHolder.getGeneratorService(), req); - long time = estimator.getScanTime(); + long time = estimator.getEstimatedScanTime(); Format format = (time scanModel.setScanMetadata(req.getScanMetadata()); scanModel.setBean(bean); - configureDetectors(req.getDetectors(), scanModel, estimator, generator); + ScanInformation scanInfo = new ScanInformation(estimator); + scanInfo.setFilePath(bean.getFilePath()); + scanInfo.setScannableNames(getScannableNames(generator)); + scanModel.setScanInformation(scanInfo); + + configureDetectors(req.getDetectors(), scanModel, generator); IPausableDevice device = (IPausableDevice) Services.getRunnableDeviceService().createRunnableDevice(scanModel, publisher, false); IDeviceController controller = Services.getWatchdogService().create(device); @@ -318,17 +323,12 @@ private IDeviceController createRunnableDevice(ScanBean bean, IPointGenerator } } - private void configureDetectors(Map dmodels, ScanModel model, ScanEstimator estimator, IPointGenerator generator) throws Exception { - - ScanInformation info = new ScanInformation(estimator); - info.setFilePath(model.getFilePath()); - info.setScannableNames(getScannableNames(model.getPositionIterable())); - + private void configureDetectors(Map dmodels, ScanModel model, IPointGenerator generator) throws Exception { for (IRunnableDevice device : model.getDetectors()) { AnnotationManager manager = new AnnotationManager(Activator.createResolver()); manager.addDevices(device); - manager.addContext(info); + manager.addContext(model.getScanInformation()); @SuppressWarnings("unchecked") IRunnableDevice odevice = (IRunnableDevice)device; From 6c9b20cd89e48dd416317a827a78a50b9c740f1e Mon Sep 17 00:00:00 2001 From: Matthew Dickie Date: Fri, 24 Feb 2017 14:17:01 +0000 Subject: [PATCH 4/4] [DAQ-474] set bean size to total scan size (not outer), incl. test --- .../scanning/sequencer/AcquisitionDevice.java | 18 +++++++++--------- .../test/scan/nexus/MalcolmScanTest.java | 9 +++++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/AcquisitionDevice.java b/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/AcquisitionDevice.java index cb3aee3c0..115d237b1 100644 --- a/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/AcquisitionDevice.java +++ b/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/AcquisitionDevice.java @@ -227,7 +227,7 @@ public void run(IPosition parent) throws ScanningException, InterruptedException // Sometimes logic is needed to implement collision avoidance // Set the size and declare a count - fireStart(location.getOuterSize()); + fireStart(location.getTotalSize()); // We allow monitors which can block a position until a setpoint is // reached or add an extra record to the NeXus file. @@ -406,16 +406,16 @@ private void processException(Exception ne) throws ScanningException { } private ScanInformation getScanInformation(int size) { - ScanInformation scanInformation = getModel().getScanInformation(); - if (scanInformation == null) { - ScanInformation info = new ScanInformation(); - info.setSize(size); - info.setRank(getScanRank(getModel().getPositionIterable())); - info.setScannableNames(getScannableNames(getModel().getPositionIterable())); - info.setFilePath(getModel().getFilePath()); + ScanInformation scanInfo = getModel().getScanInformation(); + if (scanInfo == null) { + scanInfo = new ScanInformation(); + scanInfo.setSize(size); + scanInfo.setRank(getScanRank(getModel().getPositionIterable())); + scanInfo.setScannableNames(getScannableNames(getModel().getPositionIterable())); + scanInfo.setFilePath(getModel().getFilePath()); } - return scanInformation; + return scanInfo; } private void fireStart(int size) throws Exception { diff --git a/org.eclipse.scanning.test/src/org/eclipse/scanning/test/scan/nexus/MalcolmScanTest.java b/org.eclipse.scanning.test/src/org/eclipse/scanning/test/scan/nexus/MalcolmScanTest.java index 47f9b9eab..cf382c0bd 100644 --- a/org.eclipse.scanning.test/src/org/eclipse/scanning/test/scan/nexus/MalcolmScanTest.java +++ b/org.eclipse.scanning.test/src/org/eclipse/scanning/test/scan/nexus/MalcolmScanTest.java @@ -56,6 +56,7 @@ import org.eclipse.scanning.api.device.IRunnableDevice; import org.eclipse.scanning.api.device.IRunnableEventDevice; import org.eclipse.scanning.api.event.scan.DeviceState; +import org.eclipse.scanning.api.event.scan.ScanBean; import org.eclipse.scanning.api.points.GeneratorException; import org.eclipse.scanning.api.points.IPointGenerator; import org.eclipse.scanning.api.points.IPosition; @@ -176,12 +177,20 @@ private void testMalcolmScan(int... shape) throws Exception { IRunnableDevice scanner = createMalcolmGridScan(malcolmDevice, output, shape); // Outer scan of another scannable, for instance temp. scanner.run(null); + checkSize(scanner, shape); checkFiles(); // Check we reached ready (it will normally throw an exception on error) assertEquals(DeviceState.READY, scanner.getDeviceState()); checkNexusFile(scanner, shape); // Step model is +1 on the size + } + private void checkSize(IRunnableDevice scanner, int[] shape) { + @SuppressWarnings("unchecked") + ScanBean bean = ((AbstractRunnableDevice) scanner).getBean(); + int expectedSize = Arrays.stream(shape).reduce(1, (x, y) -> x * y); + System.err.println("Expected size = " + expectedSize + ", shape = " + Arrays.toString(shape)); + assertEquals(expectedSize, bean.getSize()); } private void checkFiles() {