/*- * Copyright © 2009 Diamond Light Source Ltd., Science and Technology * Facilities Council * * This file is part of GDA. * * GDA is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License version 3 as published by the Free * Software Foundation. * * GDA is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with GDA. If not, see <http://www.gnu.org/licenses/>. */ package gda.gui.scanplot; import java.util.Arrays; import java.util.List; import java.util.Vector; import gda.TestHelpers; import gda.device.Scannable; import gda.device.scannable.DummyScannable; import gda.factory.Factory; import gda.factory.Finder; import gda.scan.IScanDataPoint; import gda.scan.IScanStepId; import gda.scan.LocalStepId; import gda.scan.ScanDataPoint; import gda.scan.ScanDataPointClient; import gda.scan.ScanDataPointServer; import gda.scan.ScanDataPointVar; import gda.util.simpleServlet.FindableSimpleServlet; /** * * first sets of lines is a nested scan the first scannable has 3 positions, the second 2 positions * and the 3rd 100, so there are 6 combinations of first and second scannables. * There are 2 extra scannables being monitored so the total number of lines per combination is 4 * making 4*6 lines = 24. * So x is the 3rd scannable * second set of lines is simple a scan of x with Y being read at each point so the additional * number of lines is 1 * * following sets of lines are repeats of the first and second. * * An example of using this class is XYPlotViewTest: * * ScanDataPointHandlerTester addDataQueue = new ScanDataPointHandlerTester(this); for(int i=0; i< 3; i++){ File f = new File(scratchFolder + File.separator + Integer.toString(i)+".nxs"); gda.util.FileUtil.copy(testdataFile, f); addDataQueue.startAddingData(f.getAbsolutePath()); while( addDataQueue.isAddingData()){ delay(1000); } switch(i){ case 0: 'test' results */ public class ScanDataPointHandlerTester implements Runnable { private final ScanDataPointHandler scanPlot; private final int size; private boolean killed = false; private Thread thread = null; private Boolean addData = false; private Object obj = new Object(); private String currentFileName; int numberOfRestarts = 1; /** * @param scanPlot */ public ScanDataPointHandlerTester(ScanDataPointHandler scanPlot) { this.scanPlot = scanPlot; this.size = 100; Factory testFactory = TestHelpers.createTestFactory("ScanDataPointHandlerTester"); FindableSimpleServlet ss = new FindableSimpleServlet(); ss.setName(ScanDataPointClient.SCAN_DATA_STORE); testFactory.addFindable(ss); Finder.getInstance().addFactory(testFactory); } /** * @param currentFileName */ public void startAddingData(String currentFileName) { this.currentFileName = currentFileName; synchronized (obj) { addData = true; if (thread == null) { thread = uk.ac.gda.util.ThreadManager.getThread(this); thread.start(); } obj.notifyAll(); } } /** * */ public void stopAddingData() { synchronized (obj) { addData = false; obj.notifyAll(); } } /** * */ public void dispose() { killed = true; } @SuppressWarnings("null") @Override public void run() { boolean childScan = false; Integer pointNumber = 0; int[] xLoops = null; Integer numYs = null; Integer xCounters[] = null; DummyScannable xScannables[]=null; DummyScannable yScannables[]=null; Integer totalPointsWithChild = 1; Vector<Scannable> scannables = null; while (!killed) { try { boolean addDataNow = false; synchronized (obj) { addDataNow = addData; if (!addDataNow) { obj.wait(); numberOfRestarts++; pointNumber = 0; } } if (addDataNow) { if (pointNumber == 0) { childScan = numberOfRestarts % 2 == 1; xLoops = childScan ? new int[] { 3, 2, size } : new int[] { size }; numYs = childScan ? 2 : 1; xCounters = new Integer[xLoops.length]; xScannables = new DummyScannable[xLoops.length]; yScannables = new DummyScannable[numYs]; totalPointsWithChild = 1; for (int i = 0; i < xLoops.length; i++) { totalPointsWithChild *= xLoops[i]; } Arrays.fill(xCounters, 0); scannables = new Vector<Scannable>(); String name = ""; Double xVal = (double) pointNumber; for (int i = 0; i < xLoops.length; i++) { name += "X"; xScannables[i] = new DummyScannable(name + Integer.toString(i), xCounters[i]); scannables.add(xScannables[i]); } name = ""; for (int i = 0; i < numYs; i++) { name += "Y"; Double yVal = (((double) i + 1) / 5.0) * Math.sin(Math.PI * ((xVal + numberOfRestarts * 20) / 180)); yScannables[i] = new DummyScannable(name + Integer.toString(i), yVal); scannables.add(yScannables[i] ); } } ScanDataPoint scanDataPoint = new ScanDataPoint(); scanDataPoint.setUniqueName("scanName" + numberOfRestarts); if (scannables != null) { // do the getPosition/readout here as work should not be done inside the SDP. // This should be the only place these methods are called in the scan. for (Scannable scannable : scannables) { scanDataPoint.addScannable(scannable); scanDataPoint.addScannablePosition(scannable.getPosition(),scannable.getOutputFormat()); } } scanDataPoint.setHasChild(childScan); scanDataPoint.setCurrentPointNumber(pointNumber); scanDataPoint.setNumberOfPoints(childScan ? totalPointsWithChild : xLoops[0]); scanDataPoint.setInstrument("instrument"); scanDataPoint.setCommand("blah blah"); scanDataPoint.setScanIdentifier(numberOfRestarts); scanDataPoint.setCurrentFilename(currentFileName); scanDataPoint.setNumberOfChildScans(childScan ? xLoops.length-1 : 0); if( childScan ){ List<IScanStepId> scanStepIds = new Vector<IScanStepId>(); for( int i=0; i< xCounters.length;i++){ scanStepIds.add( new LocalStepId(Integer.toString(i) + "=" + xCounters[i].toString() + ",")); } scanDataPoint.setStepIds(scanStepIds); } scanDataPoint.setScanDimensions(xLoops); { ScanDataPointVar var = ScanDataPointServer.getToken(scanDataPoint); IScanDataPoint pt = ScanDataPointClient.convertToken(var); scanPlot.handlePoint(pt); } Thread.sleep(50); pointNumber++; boolean atEnd = false; if (scanDataPoint.getHasChild()) { for (int i = xLoops.length - 1; i >= 0; i--) { xCounters[i]++; if (xCounters[i] == xLoops[i]) { // reset to 0 add 1 to previous for (int j = i; j < xLoops.length; j++) { xCounters[j] = 0; } if (i == 0) { atEnd = true; break; } // go to next } else { break; } } } else { xCounters[0]++; if (xCounters[0] == xLoops[0]) atEnd = true; for (int i = 1; i < xLoops.length; i++) { xCounters[i]++; } } for(int i=0; i< xLoops.length; i++){ if (xScannables[i]!=null) xScannables[i].asynchronousMoveTo(xCounters[i]); } Double xVal = (double) pointNumber; for (int i = 0; i < numYs; i++) { Double yVal = (((double) i + 1) / 5.0) * Math.sin(Math.PI * ((xVal + numberOfRestarts * 20) / 180)); if (yScannables[i]!=null) yScannables[i].asynchronousMoveTo(yVal); } if (atEnd) { pointNumber = 0; // numberOfRestarts++; addData = false; } } } catch (Throwable th) { th.printStackTrace(); } } } public boolean isAddingData(){ return addData; } }