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..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 @@ -47,4 +47,20 @@ default void validate(T model) throws ValidationException, InstantiationExceptio default void setService(IValidatorService vservice) { } + + /** + * Same as Validation method above but returns any results sent back by validation. + * + * @param model + * @return + * @throws ValidationException + */ + 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.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.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.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 000000000..aa8bbe927 Binary files /dev/null and b/org.eclipse.scanning.device.ui/icons/report.png differ 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,14 +342,44 @@ 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); + + 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); } } + + 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/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 { + 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..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 @@ -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 ("validate".equals(methodName)) { + returnPvStructure = args; + } 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); + } 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/AcquisitionDevice.java b/org.eclipse.scanning.sequencer/src/org/eclipse/scanning/sequencer/AcquisitionDevice.java index 2e8993c08..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. @@ -404,15 +404,22 @@ private void processException(Exception ne) throws ScanningException { getBean().setMessage(ne.getMessage()); } + + private ScanInformation getScanInformation(int size) { + 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 scanInfo; + } private void fireStart(int size) throws Exception { - - ScanInformation info = new ScanInformation(); - info.setSize(size); - info.setRank(getScanRank(getModel().getPositionIterable())); - info.setScannableNames(getScannableNames(getModel().getPositionIterable())); - info.setFilePath(getModel().getFilePath()); - manager.addContext(info); + manager.addContext(getScanInformation(size)); // Setup the bean to sent getBean().setSize(size); 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 ba2de57c2..b855df437 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; @@ -111,7 +110,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); } } diff --git a/org.eclipse.scanning.server/src/org/eclipse/scanning/server/servlet/ScanProcess.java b/org.eclipse.scanning.server/src/org/eclipse/scanning/server/servlet/ScanProcess.java index cc4612d50..f484565a8 100644 --- a/org.eclipse.scanning.server/src/org/eclipse/scanning/server/servlet/ScanProcess.java +++ b/org.eclipse.scanning.server/src/org/eclipse/scanning/server/servlet/ScanProcess.java @@ -300,7 +300,12 @@ private IDeviceController createRunnableDevice(ScanBean bean, IPointGenerator 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; 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() {