use of org.eclipse.scanning.api.points.IPosition in project gda-core by openGDA.
the class ScannableNexusWrapper method setPosition.
@Override
public Object setPosition(Object value, IPosition scanPosition) throws ScanningException {
try {
final Scannable scannable = getScannable();
if (value != null) {
final int index = (scanPosition == null ? -1 : scanPosition.getIndex(getName()));
final IPosition position = new Scalar<Object>(getName(), index, value);
positionDelegate.firePositionWillPerform(position);
logger.debug("Moving scannable {} to position {} at {}", scannable.getName(), value, scanPosition);
scannable.moveTo(value);
positionDelegate.firePositionPerformed(getLevel(), position);
} else {
logger.debug("Ignoring request to move scannable {} to position {} at {}", scannable.getName(), value, scanPosition);
}
if (scanPosition != null && getScannableNexusDevice(false) != null) {
// It stops it being read again.
return getScannableNexusDevice(false).writePosition(value, scanPosition);
}
} catch (Exception e) {
throw new ScanningException("Could not set position of scannable " + getName(), e);
}
// new position.
return null;
}
use of org.eclipse.scanning.api.points.IPosition in project gda-core by openGDA.
the class HklAdapter method getAnglesForEachPoint.
private List<Map<String, Double>> getAnglesForEachPoint(List<IPosition> positions, Set<String> axisNames) {
Map<String, Double> current = getCurrentAnglePositions();
List<Map<String, Double>> allAnglePositions = new ArrayList<>();
for (IPosition pos : positions) {
Map<String, Double> thisPoint = new HashMap<>(current);
axisNames.stream().filter(current::containsKey).forEach(n -> thisPoint.put(n, pos.getValue(n)));
allAnglePositions.add(thisPoint);
}
return allAnglePositions;
}
use of org.eclipse.scanning.api.points.IPosition in project gda-core by openGDA.
the class ScanRequestFactory method createInterpolatedCompoundModel.
/**
* Implementation based on {@code org.eclipse.scanning.test.scan.nexus.MalcolmMultiScanTest}
*
* @param acquisitionTemplate
* @return
*/
private CompoundModel createInterpolatedCompoundModel(AcquisitionTemplate acquisitionTemplate) {
final var multiScanModel = new InterpolatedMultiScanModel();
// --- Preparation ---
// Each new multiscanModel must set this start position and image type
// --- Positions List ---
final List<IPosition> interpolationPositions = new ArrayList<>();
// --- Images Type ---
final List<ImageType> imageTypes = new ArrayList<>();
// --- Flat Positions ---
// Note - The shutter "close" position is added by the ScanningAcquisitionController
final IPosition flatPos = createPositionMap(getFlatCalibration().getPosition());
// --- Dark Positions ---
// Note - The shutter "close" position is added by the ScanningAcquisitionController
final IPosition darkPos = createPositionMap(getDarkCalibration().getPosition());
// --- Steps estimation
ScannableTrackDocument trackDocument = getScanpathDocument().getScannableTrackDocuments().get(0);
// darks and flats should be (step / 2) before the start of the main scan, and the same after
final double posBeforeMainScan = trackDocument.getStart() - trackDocument.calculatedStep() / 2;
final double posAfterMainScan = trackDocument.getStop() + trackDocument.calculatedStep() / 2;
// Flat Before Acquisition
if (getFlatCalibration().isBeforeAcquisition() && getFlatCalibration().getNumberExposures() > 0) {
var preScanFlats = getCalibrationModel(trackDocument.getScannable(), posBeforeMainScan, getFlatCalibration().getNumberExposures());
multiScanModel.addModel(preScanFlats);
addPosition(flatPos, interpolationPositions::add);
imageTypes.add(ImageType.FLAT);
}
// Dark Before Acquisition
if (getDarkCalibration().isBeforeAcquisition() && getDarkCalibration().getNumberExposures() > 0) {
var preScanDarks = getCalibrationModel(trackDocument.getScannable(), posBeforeMainScan, getDarkCalibration().getNumberExposures());
multiScanModel.addModel(preScanDarks);
addPosition(darkPos, interpolationPositions::add);
imageTypes.add(ImageType.DARK);
}
// Acquisition
addPosition(createStartPosition(), interpolationPositions::add);
multiScanModel.addModel(acquisitionTemplate.getIScanPointGeneratorModel());
imageTypes.add(ImageType.NORMAL);
// Flat After Acquisition
if (getFlatCalibration().isAfterAcquisition() && getFlatCalibration().getNumberExposures() > 0) {
var postScanFlats = getCalibrationModel(trackDocument.getScannable(), posAfterMainScan, getFlatCalibration().getNumberExposures());
multiScanModel.addModel(postScanFlats);
addPosition(flatPos, interpolationPositions::add);
imageTypes.add(ImageType.FLAT);
}
// Dark After Acquisition
if (getDarkCalibration().isAfterAcquisition() && getDarkCalibration().getNumberExposures() > 0) {
var posScanDarks = getCalibrationModel(trackDocument.getScannable(), posAfterMainScan, getDarkCalibration().getNumberExposures());
multiScanModel.addModel(posScanDarks);
addPosition(darkPos, interpolationPositions::add);
imageTypes.add(ImageType.DARK);
}
multiScanModel.setContinuous(Optional.ofNullable(getScanpathDocument().getMutators().containsKey(Mutator.CONTINUOUS)).orElse(false));
multiScanModel.setInterpolatedPositions(interpolationPositions);
multiScanModel.setImageTypes(imageTypes);
return new CompoundModel(multiScanModel);
}
use of org.eclipse.scanning.api.points.IPosition in project gda-core by openGDA.
the class ScannableNexusWrapperScanTest method checkNexusFile.
private void checkNexusFile(final IRunnableDevice<ScanModel> scanner, int... sizes) throws Exception {
final ScanModel scanModel = ((AbstractRunnableDevice<ScanModel>) scanner).getModel();
assertThat(scanner.getDeviceState(), is(DeviceState.ARMED));
final String filePath = ((AbstractRunnableDevice<ScanModel>) scanner).getModel().getFilePath();
final NexusFile nf = org.eclipse.dawnsci.nexus.ServiceHolder.getNexusFileFactory().newNexusFile(filePath);
nf.openToRead();
final TreeFile nexusTree = NexusUtils.loadNexusTree(nf);
final NXroot rootNode = (NXroot) nexusTree.getGroupNode();
final NXentry entry = rootNode.getEntry();
final NXinstrument instrument = entry.getInstrument();
final NXsample sample = entry.getSample();
// check the scan points have been written correctly
assertDiamondScanGroup(entry, false, false, sizes);
DataNode dataNode = null;
IDataset dataset = null;
int[] shape = null;
// check metadata scannables
checkMetadataScannables(scanModel, entry);
checkAttributeScannable(instrument);
checkBeamSizeScannable(sample);
final IPosition pos = scanModel.getPointGenerator().iterator().next();
final Collection<String> scannableNames = pos.getNames();
final String dataGroupName = scanModel.getDetectors().get(0).getName();
final NXdata nxData = entry.getData(dataGroupName);
assertThat(nxData, is(notNullValue()));
// Check axes
final List<String> expectedAxesNames = Stream.concat(scannableNames.stream().map(x -> x + NexusConstants.FIELD_SEPERATOR + FIELD_NAME_VALUE_SET), Arrays.asList("real", "imaginary").stream()).collect(Collectors.toList());
assertAxes(nxData, expectedAxesNames.toArray(new String[expectedAxesNames.size()]));
final int[] defaultDimensionMappings = IntStream.range(0, sizes.length).toArray();
int scannableIndex = -1;
for (final String scannableName : scannableNames) {
scannableIndex++;
NXpositioner positioner = instrument.getPositioner(scannableName);
final boolean inLocationMap = locationMap.containsKey(scannableName);
if (inLocationMap) {
final NXcollection scannablesCollection = (NXcollection) instrument.getGroupNode(COLLECTION_NAME_SCANNABLES);
assertThat(scannablesCollection, is(notNullValue()));
positioner = (NXpositioner) scannablesCollection.getGroupNode(scannableName);
}
assertThat(positioner, is(notNullValue()));
assertThat(positioner.getGroupNodeNames(), is(empty()));
assertThat(positioner.getNumberOfGroupNodes(), is(0));
assertThat(positioner.getAttributeNames(), containsInAnyOrder(NXCLASS, ATTR_NAME_GDA_SCANNABLE_NAME, ATTR_NAME_GDA_SCAN_ROLE));
assertThat(positioner.getNumberOfAttributes(), is(3));
assertThat(positioner.getAttrString(null, ATTR_NAME_GDA_SCANNABLE_NAME), is(equalTo(scannableName)));
assertThat(positioner.getAttrString(null, ATTR_NAME_GDA_SCAN_ROLE), is(equalTo(ScanRole.SCANNABLE.toString().toLowerCase())));
final Scannable legacyScannable = getScannable(scannableName);
final List<String> inputFieldNames = new ArrayList<>();
inputFieldNames.addAll(Arrays.asList(legacyScannable.getInputNames()));
inputFieldNames.addAll(Arrays.asList(legacyScannable.getExtraNames()));
final List<String> outputFieldNames = new ArrayList<>(inputFieldNames);
if (outputFieldNames.contains(scannableName)) {
outputFieldNames.set(outputFieldNames.indexOf(scannableName), NXpositioner.NX_VALUE);
}
// check the number of data nodes, num fields of legacy scannable + name + demand_value
final List<String> additionalDataNodeNames = Arrays.asList(NXpositioner.NX_NAME, FIELD_NAME_VALUE_SET, NXpositioner.NX_SOFT_LIMIT_MIN, NXpositioner.NX_SOFT_LIMIT_MAX);
final String[] expectedDataNodeNames = Stream.of(outputFieldNames, additionalDataNodeNames).flatMap(Collection::stream).toArray(String[]::new);
assertThat(positioner.getDataNodeNames(), containsInAnyOrder(expectedDataNodeNames));
assertThat(positioner.getNumberOfDataNodes(), is(expectedDataNodeNames.length));
assertThat(positioner.getNameScalar(), is(equalTo(scannableName)));
// Demand values should be 1D
dataNode = positioner.getDataNode(FIELD_NAME_VALUE_SET);
dataset = dataNode.getDataset().getSlice();
shape = dataset.getShape();
assertThat(shape.length, is(1));
assertThat(shape[0], is(sizes[scannableIndex]));
String nxDataFieldName = scannableName + NexusConstants.FIELD_SEPERATOR + FIELD_NAME_VALUE_SET;
assertThat(nxData.getDataNode(nxDataFieldName), is(sameInstance(dataNode)));
assertIndices(nxData, nxDataFieldName, scannableIndex);
assertTarget(nxData, nxDataFieldName, rootNode, "/entry/instrument/" + (inLocationMap ? COLLECTION_NAME_SCANNABLES + "/" : "") + scannableName + "/" + FIELD_NAME_VALUE_SET);
final String[] paths = locationMap.containsKey(scannableName) ? ((SingleScannableWriter) locationMap.get(scannableName)).getPaths() : null;
final String[] expectedUnits = getExpectedUnits(legacyScannable);
assertThat(positioner.getNameScalar(), is(equalTo(scannableName)));
final DataNode setValueDataNode = positioner.getDataNode(NXpositioner.NX_VALUE + "_set");
assertThat(setValueDataNode, is(notNullValue()));
dataset = setValueDataNode.getDataset().getSlice();
shape = dataset.getShape();
assertThat(shape, is(equalTo(new int[] { sizes[scannableIndex] })));
assertThat(positioner.getSoft_limit_minScalar(), is(equalTo(((ScannableMotion) legacyScannable).getLowerGdaLimits()[0])));
assertThat(positioner.getSoft_limit_maxScalar(), is(equalTo(((ScannableMotion) legacyScannable).getUpperGdaLimits()[0])));
for (int fieldIndex = 0; fieldIndex < outputFieldNames.size(); fieldIndex++) {
final String valueFieldName = outputFieldNames.get(fieldIndex);
dataNode = positioner.getDataNode(valueFieldName);
assertThat(valueFieldName, dataNode, is(notNullValue()));
assertThat(dataNode.getAttribute(ATTR_NAME_LOCAL_NAME), is(notNullValue()));
assertThat(valueFieldName, positioner.getAttrString(valueFieldName, ATTR_NAME_LOCAL_NAME), is(equalTo(scannableName + NexusConstants.FIELD_SEPERATOR + inputFieldNames.get(fieldIndex))));
assertThat(dataNode.getAttribute(ATTR_NAME_GDA_FIELD_NAME), is(notNullValue()));
assertThat(valueFieldName, positioner.getAttrString(valueFieldName, ATTR_NAME_GDA_FIELD_NAME), is(equalTo(inputFieldNames.get(fieldIndex))));
// Actual values should be scanD
dataset = dataNode.getDataset().getSlice();
shape = dataset.getShape();
assertThat(valueFieldName, shape, is(equalTo(sizes)));
if (fieldIndex == 0) {
// currently only the first field of a Scannable is linked to from an NXdata group,
// this is probably incorrect, see JIRA DAQ-311
nxDataFieldName = scannableName + NexusConstants.FIELD_SEPERATOR + valueFieldName;
assertThat(nxData.getDataNode(nxDataFieldName), is(sameInstance(dataNode)));
assertIndices(nxData, nxDataFieldName, defaultDimensionMappings);
assertTarget(nxData, nxDataFieldName, rootNode, "/entry/instrument/" + (inLocationMap ? COLLECTION_NAME_SCANNABLES + "/" : "") + scannableName + "/" + valueFieldName);
if (paths != null && paths.length > fieldIndex) {
// check the same datanode can also be found at the path for this fieldname in the location map
final DataNode expectedLinkedDataNode = NexusUtils.getDataNode(entry, paths[fieldIndex]);
assertThat(valueFieldName, expectedLinkedDataNode, is(sameInstance(dataNode)));
if (expectedUnits != null && expectedUnits.length > fieldIndex) {
// check the units attribute has been written according to the location map
final Attribute unitsAttribute = dataNode.getAttribute(ATTR_NAME_UNITS);
assertThat(unitsAttribute, is(notNullValue()));
assertThat(unitsAttribute.getFirstElement(), is(equalTo(expectedUnits[fieldIndex])));
}
}
}
}
}
}
use of org.eclipse.scanning.api.points.IPosition in project gda-core by openGDA.
the class ScannableNexusWrapperTest method testNullSetPosition_withScanPosition.
@Test
public void testNullSetPosition_withScanPosition() throws Exception {
// Note: nexus writing tested separately by ScannableNexusWrapperScanTest
// Arrange
final int scanIndex = 38;
IPositionListener posListener = mock(IPositionListener.class);
((IPositionListenable) scannable).addPositionListener(posListener);
final IPosition scanPosition = new Scalar<Double>("sax", scanIndex, null);
assertThat(scannable.getPosition(), is(equalTo(3.7)));
// Act
scannable.setPosition(null, scanPosition);
// Assert
assertThat(scannable.getPosition(), is(equalTo(3.7)));
((IPositionListenable) scannable).removePositionListener(posListener);
verifyZeroInteractions(posListener);
}
Aggregations