use of org.eclipse.scanning.api.IScannable in project gda-core by openGDA.
the class ScannableDeviceConnectorService method getScannable.
@SuppressWarnings("unchecked")
@Override
public <T> IScannable<T> getScannable(String name) throws ScanningException {
boolean jythonScannable = false;
if (scannables == null)
scannables = new HashMap<>();
// first check whether an existing IScannable with this name in the cache, if so return it
if (scannables.containsKey(name)) {
IScannable<T> scannable = (IScannable<T>) scannables.get(name);
if (scannable == null)
throw new ScanningException("Cannot find scannable with name " + name);
return scannable;
}
// if not, see if we can find a gda.device.Scannable with this name using the Finder mechanism
Optional<Scannable> found = Finder.findOptionalOfType(name, Scannable.class);
Scannable scannable = found.filter(s -> !(s instanceof Detector)).orElse(null);
if (scannable == null) {
// if not, see if we can find a gda.device.Scannable with this name in the jython namespace
Object jythonObject = InterfaceProvider.getJythonNamespace().getFromJythonNamespace(name);
if (jythonObject instanceof Scannable && !(jythonObject instanceof Detector)) {
scannable = (Scannable) jythonObject;
jythonScannable = true;
}
}
// if we still haven't found the scannable, throw a ScanningException
if (scannable == null) {
throw new ScanningException("Cannot find scannable with name " + name);
}
// create a ScannableNexusWrapper wrapping the gda.device.Scannable
IScannable<T> iscannable = createScannableWrapper(name, scannable, jythonScannable);
// cache the IScannable for future use
scannables.put(name, iscannable);
return iscannable;
}
use of org.eclipse.scanning.api.IScannable in project gda-core by openGDA.
the class ScannableNexusWrapperScanTest method checkMetadataScannables.
private void checkMetadataScannables(final ScanModel scanModel, NXentry entry) throws Exception {
DataNode dataNode;
IDataset dataset;
final NXinstrument instrument = entry.getInstrument();
final Collection<IScannable<?>> perScan = scanModel.getMonitorsPerScan();
final Set<String> metadataScannableNames = perScan.stream().map(INameable::getName).collect(Collectors.toSet());
final Set<String> expectedMetadataScannableNames = new HashSet<>(legacyMetadataScannables);
Set<String> scannableNamesToCheck = new HashSet<>(expectedMetadataScannableNames);
do {
final Set<String> addedScannableNames = new HashSet<>();
for (final String metadataScannableName : scannableNamesToCheck) {
final Collection<String> reqdScannableNames = locationMap.get(metadataScannableName).getPrerequisiteScannableNames();
if (reqdScannableNames != null && !reqdScannableNames.isEmpty()) {
for (final String reqdScannableName : reqdScannableNames) {
if (!expectedMetadataScannableNames.contains(reqdScannableName)) {
expectedMetadataScannableNames.add(reqdScannableName);
addedScannableNames.add(reqdScannableName);
}
}
}
}
scannableNamesToCheck = addedScannableNames;
} while (!scannableNamesToCheck.isEmpty());
// check the metadata scannables specified in the legacy spring config are present
final List<String> scannableNames = ((AbstractPosition) scanModel.getPointGenerator().iterator().next()).getNames();
for (final String legacyMetadataScannableName : expectedMetadataScannableNames) {
assertThat(legacyMetadataScannableName, metadataScannableNames.contains(legacyMetadataScannableName) || scannableNames.contains(legacyMetadataScannableName), is(true));
}
// check each metadata scannable has been written correctly
for (final String metadataScannableName : metadataScannableNames) {
final Scannable scannable = Finder.find(metadataScannableName);
if (scannable.getScanMetadataAttribute(Scannable.ATTR_NEXUS_CATEGORY) != null) {
// the nexus object for a scannable with a nexus category won't be under NXinstrument
continue;
}
final NXobject nexusObject;
if (locationMap.containsKey(metadataScannableName)) {
// if there is an entry in the location map for this group, the nexus object
// should have been added to a collection called 'scannables'
assertThat(instrument.getGroupNode(metadataScannableName), is(nullValue()));
final NXcollection scannablesCollection = (NXcollection) instrument.getGroupNode(COLLECTION_NAME_SCANNABLES);
assertThat(scannablesCollection, is(notNullValue()));
nexusObject = (NXobject) scannablesCollection.getGroupNode(metadataScannableName);
} else {
nexusObject = (NXobject) instrument.getGroupNode(metadataScannableName);
}
// Check that the nexus object is of the expected base class
assertThat(nexusObject, is(notNullValue()));
assertThat(nexusObject.getNexusBaseClass(), is(getExpectedNexusBaseClass(scannable)));
assertThat(nexusObject.getGroupNodeNames(), is(empty()));
assertThat(nexusObject.getNumberOfGroupNodes(), is(0));
assertThat(nexusObject.getAttributeNames(), containsInAnyOrder(NXCLASS, ATTR_NAME_GDA_SCANNABLE_NAME, ATTR_NAME_GDA_SCAN_ROLE));
assertThat(nexusObject.getNumberOfAttributes(), is(3));
assertThat(nexusObject.getAttrString(null, ATTR_NAME_GDA_SCANNABLE_NAME), is(equalTo(metadataScannableName)));
assertThat(nexusObject.getAttrString(null, ATTR_NAME_GDA_SCAN_ROLE), is(equalTo(ScanRole.MONITOR_PER_SCAN.toString().toLowerCase())));
final String[] valueFieldNames = ArrayUtils.addAll(scannable.getInputNames(), scannable.getExtraNames());
if (nexusObject.getNexusBaseClass() == NexusBaseClass.NX_POSITIONER && scannable.getInputNames().length > 0) {
valueFieldNames[0] = NXpositioner.NX_VALUE;
}
final Set<String> expectedDataNodeNames = new HashSet<>();
expectedDataNodeNames.addAll(scannable.getScanMetadataAttributeNames());
expectedDataNodeNames.removeAll(Arrays.asList(Scannable.ATTR_NX_CLASS, Scannable.ATTR_NEXUS_CATEGORY));
expectedDataNodeNames.addAll(Arrays.asList(NXpositioner.NX_NAME));
expectedDataNodeNames.addAll(Arrays.asList(valueFieldNames));
if (hasLimits(scannable))
expectedDataNodeNames.addAll(Arrays.asList(NXpositioner.NX_SOFT_LIMIT_MIN, NXpositioner.NX_SOFT_LIMIT_MAX));
final Optional<String> expectedPvName = Optional.of(scannable).filter(ControllerRecord.class::isInstance).map(ControllerRecord.class::cast).map(ControllerRecord::getControllerRecordName);
expectedPvName.ifPresent(pvName -> expectedDataNodeNames.add(NXpositioner.NX_CONTROLLER_RECORD));
assertThat(nexusObject.getDataNodeNames(), containsInAnyOrder(expectedDataNodeNames.toArray()));
assertThat(nexusObject.getNumberOfDataNodes(), is(expectedDataNodeNames.size()));
assertThat(nexusObject.getString(NXpositioner.NX_NAME), is(equalTo(metadataScannableName)));
if (nexusObject instanceof NXpositioner) {
final NXpositioner positioner = (NXpositioner) nexusObject;
if (hasLimits(scannable)) {
assertThat(positioner.getSoft_limit_minScalar(), is(equalTo(((ScannableMotion) scannable).getLowerGdaLimits()[0])));
assertThat(positioner.getSoft_limit_maxScalar(), is(equalTo(((ScannableMotion) scannable).getUpperGdaLimits()[0])));
}
if (expectedPvName.isPresent()) {
assertThat(positioner.getController_recordScalar(), is(equalTo(expectedPvName.get())));
}
}
final Object[] positionArray = getPositionArray(scannable);
final String[] paths = locationMap.containsKey(metadataScannableName) ? ((SingleScannableWriter) locationMap.get(metadataScannableName)).getPaths() : null;
final String[] expectedUnits = getExpectedUnits(scannable);
final Collection<String> prerequisiteScannableNames = Collections.emptyList();
// check each field is written both inside the nexus object for the metadata scannable
for (int fieldIndex = 0; fieldIndex < valueFieldNames.length; fieldIndex++) {
final String valueFieldName = valueFieldNames[fieldIndex];
dataNode = nexusObject.getDataNode(valueFieldName);
assertThat(dataNode, is(notNullValue()));
dataset = dataNode.getDataset().getSlice();
assertThat(dataset.getRank(), is(0));
assertThat(dataset.getObject(), is(equalTo(positionArray[fieldIndex])));
if (paths != null && paths.length > fieldIndex) {
// and to the location referred to by the location map
final DataNode expectedLinkedDataNode = NexusUtils.getDataNode(entry, paths[fieldIndex]);
if (metadataScannableName.equals("sax") || metadataScannableName.equals("say")) {
// special case, datasets in location map overwritten with
// lazy writable dataset by salong and saperp
assertThat(expectedLinkedDataNode, is(notNullValue()));
} else {
assertThat(expectedLinkedDataNode, is(sameInstance(dataNode)));
if (expectedUnits != null && expectedUnits.length > fieldIndex && StringUtils.isNotBlank(expectedUnits[fieldIndex])) {
final Attribute unitsAttribute = dataNode.getAttribute(ATTR_NAME_UNITS);
assertThat(unitsAttribute, is(notNullValue()));
assertThat(unitsAttribute.getFirstElement(), is(equalTo(expectedUnits[fieldIndex])));
}
}
}
}
if (locationMap.get(metadataScannableName) instanceof TransformationWriter) {
checkTransformationsAtributes(nexusObject, valueFieldNames, (TransformationWriter) locationMap.get(metadataScannableName));
}
if (prerequisiteScannableNames != null) {
for (final String prerequisiteScannableName : prerequisiteScannableNames) {
assertThat(metadataScannableNames, contains(prerequisiteScannableName));
}
}
}
}
Aggregations