use of org.eclipse.scanning.api.points.AbstractPosition 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