Search in sources :

Example 1 with IScannable

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;
}
Also used : IScannable(org.eclipse.scanning.api.IScannable) Findable(gda.factory.Findable) InterfaceProvider(gda.jython.InterfaceProvider) LoggerFactory(org.slf4j.LoggerFactory) ScannableWriter(gda.data.scan.datawriter.scannablewriter.ScannableWriter) JythonServer(gda.jython.JythonServer) HashMap(java.util.HashMap) IScannable(org.eclipse.scanning.api.IScannable) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Detector(gda.device.Detector) Map(java.util.Map) DeviceException(gda.device.DeviceException) Finder(gda.factory.Finder) IScannableDeviceService(org.eclipse.scanning.api.device.IScannableDeviceService) Logger(org.slf4j.Logger) Collection(java.util.Collection) Set(java.util.Set) ScanningException(org.eclipse.scanning.api.scan.ScanningException) Collectors(java.util.stream.Collectors) AbstractScannable(org.eclipse.scanning.api.AbstractScannable) ServiceHolder(gda.data.ServiceHolder) Scannable(gda.device.Scannable) List(java.util.List) IPosition(org.eclipse.scanning.api.points.IPosition) Optional(java.util.Optional) Collections(java.util.Collections) Detector(gda.device.Detector) HashMap(java.util.HashMap) ScanningException(org.eclipse.scanning.api.scan.ScanningException) IScannable(org.eclipse.scanning.api.IScannable) AbstractScannable(org.eclipse.scanning.api.AbstractScannable) Scannable(gda.device.Scannable)

Example 2 with 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));
            }
        }
    }
}
Also used : IScannable(org.eclipse.scanning.api.IScannable) Attribute(org.eclipse.dawnsci.analysis.api.tree.Attribute) NXobject(org.eclipse.dawnsci.nexus.NXobject) TransformationWriter(gda.data.scan.datawriter.scannablewriter.TransformationWriter) AbstractPosition(org.eclipse.scanning.api.points.AbstractPosition) ControllerRecord(gda.device.ControllerRecord) NXpositioner(org.eclipse.dawnsci.nexus.NXpositioner) DataNode(org.eclipse.dawnsci.analysis.api.tree.DataNode) NXinstrument(org.eclipse.dawnsci.nexus.NXinstrument) DummyScannable(gda.device.scannable.DummyScannable) Scannable(gda.device.Scannable) IScannable(org.eclipse.scanning.api.IScannable) DummyMultiFieldUnitsScannable(gda.device.scannable.DummyMultiFieldUnitsScannable) DummyUnitsScannable(gda.device.scannable.DummyUnitsScannable) IDataset(org.eclipse.january.dataset.IDataset) NXcollection(org.eclipse.dawnsci.nexus.NXcollection) ScannableMotion(gda.device.ScannableMotion) HashSet(java.util.HashSet)

Aggregations

Scannable (gda.device.Scannable)2 HashSet (java.util.HashSet)2 IScannable (org.eclipse.scanning.api.IScannable)2 ServiceHolder (gda.data.ServiceHolder)1 ScannableWriter (gda.data.scan.datawriter.scannablewriter.ScannableWriter)1 TransformationWriter (gda.data.scan.datawriter.scannablewriter.TransformationWriter)1 ControllerRecord (gda.device.ControllerRecord)1 Detector (gda.device.Detector)1 DeviceException (gda.device.DeviceException)1 ScannableMotion (gda.device.ScannableMotion)1 DummyMultiFieldUnitsScannable (gda.device.scannable.DummyMultiFieldUnitsScannable)1 DummyScannable (gda.device.scannable.DummyScannable)1 DummyUnitsScannable (gda.device.scannable.DummyUnitsScannable)1 Findable (gda.factory.Findable)1 Finder (gda.factory.Finder)1 InterfaceProvider (gda.jython.InterfaceProvider)1 JythonServer (gda.jython.JythonServer)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1