use of org.eclipse.scanning.api.event.scan.ScanRequest in project gda-core by openGDA.
the class MScanSubmitter method buildAndSubmitScanRequest.
/**
* Takes the supplied MScan array, validates it and then builds a {@link CompoundModel} that represents
* the command. This is then submitted to the scanning queue as a blocking call. Currently supports detectors
* based on the {@link Detector} interface with a matching {@link IRunnableDevice} representation. This has always
* been the case as for Jython to pick up the type of a detector it must be {@link Findable} and
* {@link IRunnableDevice} based object are not yet added to the Jython Namespace.
*
* @param args The array of objects constituting the command supplied by jython. This should only contain
* {@link Scannable}s, {@link Number}s and {@link IMScanElementEnum}s or their subclasses, if any
* other objects are present, the validation will reject the command.
* @param block If true indicates that the scan submission should be a blocking call.
*
* @throws IllegalArgumentException if the validation step fails or if the clause resolution is unsuccessful
* ScanningException if the {@link IRunnableDevice} corresponding to a {@link Detector} cannot be found
* or its {@link IDetectorModel} is null
*/
public void buildAndSubmitScanRequest(final Object[] args, final boolean block) throws Exception {
throwIf(args == null, "The scan request array is null");
LOGGER.info("MScan command received {}", Arrays.toString(args));
final ScanClausesResolver resolver = standardiseAndValidateCommand(args);
// First check for run from Nexus option
IClauseElementProcessor initialProc = withNullProcessorCheck(processors.get(0));
if (initialProc instanceof ReRunFromFileElementProcessor) {
initialProc.process(null, processors, 0);
try {
final String filepath = initialProc.getElementValue();
printToJython(Map.of("Loading scan from ", Paths.get(filepath).getFileName()));
final Optional<ScanRequest> scanRequest = ScanRequestBuilder.buildFromNexusFile(filepath);
submitFromFile(scanRequest.orElseThrow(), block);
} catch (Exception e) {
printToJython(Map.of("Exception: ", e.getMessage()));
}
return;
}
final CompoundModel scanModel = new CompoundModel();
// Find the distinct clauses within the MScan command and return a list of the list of
// typed processors for each clause.
final List<List<IClauseElementProcessor>> processorsByClause = resolver.resolveScanClauses();
throwIf(processorsByClause.isEmpty() || processorsByClause.contains(null), "clause resolution returned an empty or invalid list of processors by clause");
final ClausesContext context = new ClausesContext(runnableDeviceService);
// {@link Detectors} and {@link Monitors} or {@link IRunnableDevice}s
for (final List<IClauseElementProcessor> clauseProcessors : processorsByClause) {
throwIf(clauseProcessors.isEmpty() || clauseProcessors.contains(null), "clause resolution returned an empty or invalid processor list for a clause");
context.wipe();
initialProc = withNullProcessorCheck(clauseProcessors.get(0));
// and so that processor must be switched.
for (int index = 0; index < clauseProcessors.size(); index++) {
if (context.isClauseProcessed()) {
break;
}
// Handle single element Detector or Monitor clauses
if (clauseProcessors.size() == 1) {
throwIf(!context.isScanPathSeen() && !clauseProcessors.get(0).isStatic(), "No scan path defined - SPEC style scans not yet supported");
if (initialProc instanceof ScannableElementProcessor) {
clauseProcessors.set(0, new ScannableReadoutElementProcessor((Scannable) initialProc.getElement()));
}
}
clauseProcessors.get(index).process(context, clauseProcessors, index);
}
// this needs to be added to the CompoundModel for the entire mscan
if (!context.isDetectorClauseSeen()) {
context.addPathDefinitionToCompoundModel(scanModel);
}
}
// Populate the {@link ScanRequest} with the assembled objects
ScanRequest scanRequest = new ScanRequest();
scanRequest.setCompoundModel(scanModel);
scanRequest.setDetectors(context.getDetectorMap());
scanRequest.setMonitorNamesPerPoint(context.getMonitorsPerPoint());
scanRequest.setTemplateFilePaths(context.getTemplates());
scanRequest.setMonitorNamesPerScan(context.getPerScanMonitors());
scanRequest.setProcessingRequest(context.getProcessorRequest());
if (context.getSampleMetadata() != null) {
scanRequest.addScanMetadata(context.getSampleMetadata());
}
submit(scanRequest, block, null);
}
use of org.eclipse.scanning.api.event.scan.ScanRequest in project gda-core by openGDA.
the class QueuePreventingScanSubmitterTest method getTestScanBean.
private ScanBean getTestScanBean() throws UnknownHostException {
IScanPointGeneratorModel model = mock(IScanPointGeneratorModel.class);
CompoundModel compoundModel = mock(CompoundModel.class);
when(compoundModel.getModels()).thenReturn(Arrays.asList(model));
ScanRequest scanRequest = mock(ScanRequest.class);
doReturn(compoundModel).when(scanRequest).getCompoundModel();
ScanBean bean = new ScanBean(scanRequest);
bean.setName("test scan");
return bean;
}
use of org.eclipse.scanning.api.event.scan.ScanRequest in project gda-core by openGDA.
the class TimeSeriesScanView method createScanBean.
private ScanBean createScanBean() {
final IMalcolmModel malcolmModel = malcolmModelEditor.getModel();
final String malcolmDeviceName = malcolmModel.getName();
final ScanRequest scanRequest = new ScanRequest();
// add the malcolm model to the scan request
final Map<String, IDetectorModel> detectors = new HashMap<>();
detectors.put(malcolmDeviceName, malcolmModel);
scanRequest.setDetectors(detectors);
// extract the models from the outer scannables
final List<IScanPointGeneratorModel> pointsModels = outerScannablesBlock.getOuterScannables().stream().filter(IScanModelWrapper<IScanPointGeneratorModel>::isIncludeInScan).map(IScanModelWrapper<IScanPointGeneratorModel>::getModel).collect(toCollection(ArrayList::new));
final int numSteps = numStepsSpinner.getSelection();
pointsModels.add(new StaticModel(numSteps));
scanRequest.setCompoundModel(new CompoundModel(pointsModels));
final ScanBean scanBean = new ScanBean(scanRequest);
scanBean.setName(String.format("%s - Time Series", malcolmDeviceName));
return scanBean;
}
use of org.eclipse.scanning.api.event.scan.ScanRequest in project gda-core by openGDA.
the class TomographySubmitScanSection method submitScan.
@Override
protected void submitScan() {
// Read parameters from file
try (BufferedReader reader = Files.newBufferedReader(CALIBRATION_FILE_PATH)) {
final IScriptService scriptService = getService(IScriptService.class);
final IMarshallerService marshallerService = getService(IMarshallerService.class);
final IMappingExperimentBean mappingBean = getMappingBean();
final TomographyCalibrationData calibrationParams = marshallerService.unmarshal(reader.readLine(), TomographyCalibrationData.class);
final ScanRequest scanRequest = getScanRequest(mappingBean);
final TomographyParams tomoParams = new TomographyParams();
tomoParams.setTomographyCalibration(calibrationParams);
tomoParams.setProcessingFiles(getProcessingFilesAs(mappingBean));
tomoParams.setVisitId(InterfaceProvider.getBatonStateProvider().getBatonHolder().getVisitID());
populateScriptService(scriptService, marshallerService, scanRequest, tomoParams);
} catch (Exception e) {
handleException(getClientMessage(TOMO_CALIBRATE_SUBMIT_ERROR), e);
return;
}
Async.execute(() -> runScript(tomoScanScript, "tomography scanning script"));
}
use of org.eclipse.scanning.api.event.scan.ScanRequest in project gda-core by openGDA.
the class XanesSubmitScanSection method submitScan.
@Override
protected void submitScan() {
final IScriptService scriptService = getService(IScriptService.class);
final ScanRequest scanRequest = getScanRequest(getMappingBean());
final XanesEdgeParametersSection paramsSection = getMappingView().getSection(XanesEdgeParametersSection.class);
final XanesEdgeParameters xanesEdgeParameters = paramsSection.getScanParameters();
if (xanesEdgeParameters.isEnforcedShape()) {
final CompoundModel newModel = new CompoundModel(scanRequest.getCompoundModel());
final List<IScanPointGeneratorModel> models = newModel.getModels();
final List<IScanPointGeneratorModel> enforcedShapes = new ArrayList<>(models.size());
for (IScanPointGeneratorModel model : models) {
enforcedShapes.add(enforce(model));
}
newModel.setModels(enforcedShapes);
scanRequest.setCompoundModel(newModel);
}
xanesEdgeParameters.setVisitId(InterfaceProvider.getBatonStateProvider().getBatonHolder().getVisitID());
// Add XANES parameters as metadata to the ScanRequest, so they appear in the Nexus file
final ScanMetadata xanesMetadata = new ScanMetadata(MetadataType.ENTRY);
xanesMetadata.addField("tracking_method", xanesEdgeParameters.getTrackingMethod());
xanesMetadata.addField("visit_id", xanesEdgeParameters.getVisitId());
final LinesToTrackEntry linesToTrackEntry = xanesEdgeParameters.getLinesToTrack();
if (linesToTrackEntry == null || linesToTrackEntry.getLine() == null || linesToTrackEntry.getLine().isEmpty()) {
// The entry for a blank "lines to track" contains an unmodifiable Collection, which causes problems in
// marshalling, so make sure it is set null.
xanesEdgeParameters.setLinesToTrack(null);
xanesMetadata.addField("line", "None");
} else {
xanesMetadata.addField("line", linesToTrackEntry.getLine());
xanesMetadata.addField("file_paths", new ArrayList<String>(linesToTrackEntry.getFilePaths()));
}
final List<ScanMetadata> scanMetadata = new ArrayList<>(scanRequest.getScanMetadata());
scanMetadata.add(xanesMetadata);
scanRequest.setScanMetadata(scanMetadata);
try {
final IMarshallerService marshallerService = getService(IMarshallerService.class);
scriptService.setNamedValue(VAR_NAME_SCAN_REQUEST_JSON, marshallerService.marshal(scanRequest));
scriptService.setNamedValue(VAR_NAME_XANES_EDGE_PARAMS_JSON, marshallerService.marshal(xanesEdgeParameters));
} catch (Exception e) {
logger.error("Scan submission failed", e);
MessageDialog.openError(getShell(), "Error Submitting Scan", "The scan could not be submitted. See the error log for more details.");
return;
}
Async.execute(() -> runScript(scriptFilePath, "XANES scanning script"));
}
Aggregations