use of org.eclipse.scanning.api.points.models.IScanPointGeneratorModel in project gda-core by openGDA.
the class PointGeneratorPathInfoCalculator method calculatePathInfo.
@Override
public PathInfo calculatePathInfo(PathInfoRequest request) throws PathInfoCalculationException {
IScanPointGeneratorModel scanPathModel = request.getScanPathModel();
try {
// Invokes ScanPointGenerator to create the points
IPointGenerator<CompoundModel> pointGenerator = getPointGeneratorService().createGenerator(scanPathModel, request.getScanRegion());
// Initialise with sensible starting values
int pointCount = 0;
double smallestXStep = Double.MAX_VALUE;
double smallestYStep = Double.MAX_VALUE;
double smallestAbsStep = Double.MAX_VALUE;
List<Double> xCoordinates = new ArrayList<>();
List<Double> yCoordinates = new ArrayList<>();
double lastX = Double.NaN;
double lastY = Double.NaN;
String xAxisName = getXAxisName(scanPathModel);
String yAxisName = getYAxisName(scanPathModel);
// - The smallest distance between two consecutive positions in 2D space
for (IPosition point : pointGenerator) {
pointCount++;
if (pointCount > 1) {
// Updates the smallest distance tracking variables if the distance
// between this point and the last is smaller than the smallest
// distance we've seen so far. Do this for x, y and 2D space.
double thisXStep = Math.abs(point.getValue(xAxisName) - lastX);
double thisYStep = Math.abs(point.getValue(yAxisName) - lastY);
double thisAbsStep = Math.sqrt(Math.pow(thisXStep, 2) + Math.pow(thisYStep, 2));
if (thisXStep > 0) {
smallestXStep = Math.min(smallestXStep, thisXStep);
}
if (thisYStep > 0) {
smallestYStep = Math.min(smallestYStep, thisYStep);
}
smallestAbsStep = Math.min(smallestAbsStep, thisAbsStep);
}
// Ensures no more than MAX_POINTS_IN_ROI points are inserted into
// the PathInfo. Still need to iterate through the rest of the points
// to accurately calculate step sizes and number of points.
lastX = point.getValue(xAxisName);
lastY = point.getValue(yAxisName);
if (xCoordinates.size() < request.getMaxPoints()) {
xCoordinates.add(Double.valueOf(lastX));
yCoordinates.add(Double.valueOf(lastY));
}
}
// outerAxisMultiplier is the product of the number of points
// in each outer axis. It defaults to 1 if there are no outer axes.
// It is multiplied by the number of points in the mapping scan
// e.g. if the mapping scan in x and y has 25 points and is
// also projected back through 10 points in z then there are
// 250 points in total.
int outerAxisMultiplier = calculateAllOuterPoints(request.getOuterScannables());
int totalPoints = outerAxisMultiplier * pointCount;
return PathInfo.builder().withSourceId(request.getSourceId()).withInnerPointCount(pointCount).withTotalPointCount(totalPoints).withSmallestXStep(smallestXStep).withSmallestYStep(smallestYStep).withSmallestAbsStep(smallestAbsStep).withxCoordinateList(xCoordinates).withyCoordinateList(yCoordinates).build();
} catch (GeneratorException e) {
throw new PathInfoCalculationException(e);
}
}
use of org.eclipse.scanning.api.points.models.IScanPointGeneratorModel in project gda-core by openGDA.
the class StandardsScanView method createScannableEditor.
/**
* Create the GUI elements to edit the energy scannable.<br>
* This consists of
* <ul>
* <li>the specification of the energy ranges</li>
* <li>a drop-down box to choose the edge</li>
* <li>a text box for the exposure time</li>
* <li>a check box to specify whether the energy steps should be run in reverse order</li>
* </ul>
* In general, the energy ranges should be set by choosing the edge, though they can also be edited directly.
*
* @param parent
* the parent composite to draw these controls on
*/
private void createScannableEditor(Composite parent) {
// Energy scannable
final Composite editorComposite = new Composite(parent, SWT.NONE);
GridDataFactory.swtDefaults().applyTo(editorComposite);
GridLayoutFactory.swtDefaults().numColumns(2).applyTo(editorComposite);
final StandardsScanConfig standardsScanConfig = PlatformUI.getWorkbench().getService(StandardsScanConfig.class);
if (standardsScanConfig == null) {
logger.error("Missing configuration for standards scan");
return;
}
// Scannable name
final String energyScannableName = standardsScanConfig.getScannableName();
final Label nameLabel = new Label(editorComposite, SWT.NONE);
nameLabel.setText(energyScannableName);
// Scan path editor to display & edit energy values
final IScanModelWrapper<IScanPointGeneratorModel> scannableWrapper = new ScanPathModelWrapper(energyScannableName, null, false);
scanPathEditor = new ScanPathEditor(editorComposite, SWT.NONE, scannableWrapper);
// Edge, exposure, reverse check box
final Composite edgeAndExposureComposite = new Composite(parent, SWT.NONE);
GridDataFactory.swtDefaults().applyTo(edgeAndExposureComposite);
GridLayoutFactory.swtDefaults().numColumns(4).applyTo(edgeAndExposureComposite);
// List of energy/edge combinations
final XanesEdgeCombo edgeCombo = new XanesEdgeCombo(edgeAndExposureComposite);
edgeCombo.addSelectionChangedListener(e -> {
final IScanPointGeneratorModel scanPathModel = createModelFromEdgeSelection(edgeCombo.getSelectedEnergy(), energyScannableName);
scanPathEditor.setScanPathModel(scanPathModel);
});
// Exposure time
final Label exposureTimeLabel = new Label(edgeAndExposureComposite, SWT.NONE);
GridDataFactory.swtDefaults().applyTo(exposureTimeLabel);
exposureTimeLabel.setText("Exposure time");
exposureTimeText = new Text(edgeAndExposureComposite, SWT.BORDER);
GridDataFactory.swtDefaults().hint(80, SWT.DEFAULT).applyTo(exposureTimeText);
// Reverse check box
reverseCheckBox = new Button(edgeAndExposureComposite, SWT.CHECK);
GridDataFactory.swtDefaults().applyTo(reverseCheckBox);
reverseCheckBox.setText("Reverse scan");
}
use of org.eclipse.scanning.api.points.models.IScanPointGeneratorModel in project gda-core by openGDA.
the class MappingExperimentView method loadPreviousState.
private void loadPreviousState(MPart part) {
// Restore mapping bean unless it has been set by another view
if (!mappingBeanProvider.isSetByView()) {
final String json = part.getPersistedState().get(STATE_KEY_MAPPING_BEAN_JSON);
if (json != null) {
logger.trace("Restoring the previous state of the mapping view.");
final IMarshallerService marshaller = injectionContext.get(IMarshallerService.class);
try {
setMappingBean(marshaller.unmarshal(json, MappingExperimentBean.class));
} catch (Exception e) {
logger.error("Failed to restore the previous state of the mapping view", e);
}
} else {
// If there is no state to restore, ensure that any default outer scannables are set
final IScanDefinition scanDefinition = mappingBeanProvider.getMappingExperimentBean().getScanDefinition();
if (scanDefinition == null) {
return;
}
final List<String> defaultOuterScannables = scanDefinition.getDefaultOuterScannables();
if (defaultOuterScannables.isEmpty()) {
return;
}
final List<IScanModelWrapper<IScanPointGeneratorModel>> scanModels = defaultOuterScannables.stream().map(scannable -> new ScanPathModelWrapper(scannable, null, false)).collect(Collectors.toList());
scanDefinition.setOuterScannables(scanModels);
}
}
}
use of org.eclipse.scanning.api.points.models.IScanPointGeneratorModel in project gda-core by openGDA.
the class ScanRequestConverter method checkMapModelAndUpdateMappingStage.
private IMapPathModel checkMapModelAndUpdateMappingStage(final CompoundModel compoundModel) {
final List<IScanPointGeneratorModel> models = compoundModel.getModels();
// check that the inner most model is an IMapPathModel, i.e. for a mapping scan
final IScanPointGeneratorModel innerModelObj = models.get(models.size() - 1);
if (!(innerModelObj instanceof IMapPathModel)) {
throw new IllegalArgumentException("The inner most model is not a map model. This is not mapping scan");
}
final IMapPathModel mapPath = (IMapPathModel) innerModelObj;
// update the mapping bean with axes in the mapping path
if (mappingStageInfo != null) {
mappingStageInfo.setPlotXAxisName(mapPath.getxAxisName());
mappingStageInfo.setPlotYAxisName(mapPath.getyAxisName());
}
return mapPath;
}
use of org.eclipse.scanning.api.points.models.IScanPointGeneratorModel in project gda-core by openGDA.
the class RegionAndPathSection method handleRegionAndPathEvent.
private void handleRegionAndPathEvent(String value) {
try {
final Gson gson = new Gson();
@SuppressWarnings("unchecked") final Map<String, Object> regionAndPathMap = gson.fromJson(value, HashMap.class);
// Change to region
final String region = (String) regionAndPathMap.get("region");
if (!StringUtils.isEmpty(region)) {
final IMappingScanRegionShape scanRegion = scanRegionMap.get(region);
if (scanRegion == null) {
throw new IllegalArgumentException("Invalid region " + region);
}
uiSync.syncExec(() -> controller.getRegionSelectorListener().handleRegionChange(scanRegion));
}
// Change to path
final String path = (String) regionAndPathMap.get("path");
if (!StringUtils.isEmpty(path)) {
// Get the available scan paths for the current region
final Map<String, IScanPointGeneratorModel> scanPathMap = controller.getScanPathListAndLinkPath().stream().collect(toMap(IScanPointGeneratorModel::getName, identity()));
final IScanPointGeneratorModel scanPath = scanPathMap.get(path);
if (scanPath == null) {
throw new IllegalArgumentException("No scan path corresponding to " + path);
}
uiSync.syncExec(() -> {
final IMappingScanRegionShape scanRegion = controller.getScanRegionShape();
controller.updateMappingBeanScanRegion(scanRegion, scanPath);
controller.getRegionSelectorListener().handleRegionChange(scanRegion);
});
}
// Changes to scan region properties
controller.getScanRegionShape().updateFromPropertiesMap(regionAndPathMap);
// Changes to scan path properties
controller.getScanPathModel().updateFromPropertiesMap(regionAndPathMap);
// Update GUI
uiSync.asyncExec(this::rebuildMappingSection);
} catch (Exception e) {
logger.error("Invalid region/path parameter: {}", value, e);
}
}
Aggregations