Now all action related methods should work ...

This commit is contained in:
2013-07-29 11:18:20 +02:00
parent 4a59731669
commit bc0763a22c
7 changed files with 582 additions and 387 deletions

View File

@@ -9,7 +9,7 @@
<dependency>
<groupId>ch.psi</groupId>
<artifactId>jcae</artifactId>
<version>2.1.9</version>
<version>2.1.10</version>
</dependency>
<!-- Plotting library -->
<dependency>

View File

@@ -18,30 +18,65 @@
*/
package ch.psi.fda.aq;
import java.util.Map;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import ch.psi.jcae.ChannelDescriptor;
import ch.psi.jcae.ChannelException;
import ch.psi.jcae.ChannelService;
/**
* @author ebner
*
*/
public class AcquisitionEngineNG {
private ScriptEngine engine;
public AcquisitionEngineNG() {
private static final Logger logger = Logger.getLogger(AcquisitionEngineNG.class.getName());
private ChannelService cservice;
public AcquisitionEngineNG(ChannelService cservice) {
this.cservice = cservice;
// Workaround for Jython memory leak
// http://blog.hillbrecht.de/2009/07/11/jython-memory-leakout-of-memory-problem/
System.setProperty("python.options.internalTablesImpl", "weak");
// Create new script engine
this.engine = new ScriptEngineManager().getEngineByName("python");
}
public void execute(String script){
public void execute(Map<String, ?> resourceDescriptors, String script){
try {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");
// Set logger
engine.put("logger", logger);
// Retrieve and set resources
for(String k: resourceDescriptors.keySet()){
if(resourceDescriptors.get(k) instanceof ChannelDescriptor){
ChannelDescriptor<?> descriptor = (ChannelDescriptor<?>)resourceDescriptors.get(k);
try {
engine.put(k, cservice.createChannel(descriptor));
} catch (ChannelException | InterruptedException | TimeoutException e) {
throw new RuntimeException("Unable to create resource for channel: "+descriptor.getName(),e);
}
}
else if(resourceDescriptors.get(k) instanceof ShellDescriptor){
engine.put(k, new ShellResource());
}
else{
throw new RuntimeException("Resource type not supported: "+resourceDescriptors.get(k).getClass().getName());
}
}
// Execute script
engine.eval(script);
} catch (ScriptException e) {
throw new RuntimeException("Action failed while executing the Jython script",e);
}

View File

@@ -19,100 +19,100 @@
package ch.psi.fda.aq;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Logger;
import ch.psi.fda.core.Actor;
import ch.psi.fda.core.actions.ChannelAccessCondition;
import ch.psi.fda.core.actions.ChannelAccessConditionAnd;
import ch.psi.fda.core.actions.ChannelAccessConditionOr;
import ch.psi.fda.core.actions.ChannelAccessConditionRegex;
import ch.psi.fda.core.actions.ChannelAccessPut;
import ch.psi.fda.core.actions.Delay;
import ch.psi.fda.core.actors.ChannelAccessFunctionActuator;
import ch.psi.fda.core.actors.ChannelAccessLinearActuator;
import ch.psi.fda.core.actors.ChannelAccessTableActuator;
import ch.psi.fda.core.actors.ComplexActuator;
import ch.psi.fda.core.actors.JythonFunction;
import ch.psi.fda.core.actors.PseudoActuatorSensor;
import ch.psi.fda.core.scripting.JythonParameterMappingChannel;
import ch.psi.fda.core.sensors.ChannelAccessDoubleSensor;
import ch.psi.fda.model.v1.Action;
import ch.psi.fda.model.v1.ArrayPositioner;
import ch.psi.fda.model.v1.ChannelAction;
import ch.psi.fda.model.v1.ChannelParameterMapping;
import ch.psi.fda.model.v1.Configuration;
import ch.psi.fda.model.v1.ContinuousDimension;
import ch.psi.fda.model.v1.Dimension;
import ch.psi.fda.model.v1.DiscreteStepDimension;
import ch.psi.fda.model.v1.DiscreteStepPositioner;
import ch.psi.fda.model.v1.FunctionPositioner;
import ch.psi.fda.model.v1.LinearPositioner;
import ch.psi.fda.model.v1.PseudoPositioner;
import ch.psi.fda.model.v1.Region;
import ch.psi.fda.model.v1.RegionPositioner;
import ch.psi.fda.model.v1.Scan;
import ch.psi.fda.model.v1.ScriptAction;
import ch.psi.fda.model.v1.ShellAction;
import ch.psi.jcae.ChannelDescriptor;
import ch.psi.jcae.util.ComparatorAND;
import ch.psi.jcae.util.ComparatorOR;
import ch.psi.jcae.util.ComparatorREGEX;
/**
* @author ebner
*
*
*/
public class ScanMapperNG {
private static final Logger logger = Logger.getLogger(ScanMapperNG.class.getName());
private static final String INDENT = " ";
private StringBuilder script = new StringBuilder();
private Set<String> imports = new HashSet<>();
private String indentation="";
public void map(Configuration configuration){
private Map<String, Object> resourceDescriptors = new HashMap<>();
private String indentation = "";
public void map(Configuration configuration) {
Scan scan = configuration.getScan();
mapActions(scan.getPreAction());
// Bring the dimensions into the correct order and then map them
// Bring the dimensions into the correct order and then map them
// to the script
List<Dimension> dimensions = new ArrayList<>();
int size = scan.getDimension().size();
for(int i=size-1; i>=0; i--){
for (int i = size - 1; i >= 0; i--) {
dimensions.add(scan.getDimension().get(i));
}
// Continuous dimensions are always at the very end
if(scan.getCdimension()!=null){
if (scan.getCdimension() != null) {
dimensions.add(scan.getCdimension());
}
mapDimensions(dimensions, 0);
// map
// map
mapActions(scan.getPostAction());
// TODO CONSIDER TO PROVIDE RESOURCE MAP AND SCRIPT IN ONE OBJECT AS RETURN TYPE
// TODO CONSIDER TO PROVIDE RESOURCE MAP AND SCRIPT IN ONE OBJECT AS
// RETURN TYPE
// WOULD MAKE MORE SENSE
}
/**
* Get the generated script
*
* @return
*/
public String getScript(){
StringBuilder scriptlines= new StringBuilder();
for(String s: imports){
scriptlines.append("import "+s+"\n");
public String getScript() {
StringBuilder scriptlines = new StringBuilder();
for (String s : imports) {
scriptlines.append(s + "\n");
}
scriptlines.append(script);
return scriptlines.toString();
}
/**
* Get map of required resources
* @return
*/
public Map<String, Object> getResourceDescriptors(){
return resourceDescriptors;
}
private void mapDimensions(List<Dimension> dimensions, int index) {
if(dimensions.size()<1){
logger.info("There are no dimensions to map");
return;
}
Dimension dimension = dimensions.get(index);
if (dimension instanceof DiscreteStepDimension) {
DiscreteStepDimension d = (DiscreteStepDimension) dimension;
@@ -125,12 +125,12 @@ public class ScanMapperNG {
mapActions(d.getAction());
// TODO map guard and sensors
// Next dimension
if((index+1)<dimensions.size()){
mapDimensions(dimensions, (index+1));
if ((index + 1) < dimensions.size()) {
mapDimensions(dimensions, (index + 1));
}
indentation = indentation.replaceFirst(INDENT, ""); // decrease
// indentation
mapActions(d.getPostAction());
@@ -140,351 +140,370 @@ public class ScanMapperNG {
}
}
private void mapActions(List<Action> actions){
for(Action action: actions){
if(action instanceof ChannelAction){
private void mapActions(List<Action> actions) {
for (Action action : actions) {
if (action instanceof ChannelAction) {
ChannelAction ca = (ChannelAction) action;
Class<?> type = String.class;
long waitTimeout=1800000; // Max wait timeout is 30 minutes
if(ca.getTimeout()!=null){
waitTimeout = ca.getTimeout().longValue()*1000; // wait timeout is currently in seconds
}
ca.getTimeout();
switch (ca.getType()) {
case "Integer":
type = Integer.class;
break;
case "Double":
type = Double.class;
break;
}
String var = getChannelResourceVariable(ca.getChannel(), type, false);
switch (ca.getOperation()) {
case "put":
if(ca.getTimeout()==null){
script.append(var+".setValue("+getPythonValue(ca.getValue(), type)+")\n");
} else {
imports.add("from java.util.concurrent import TimeUnit");
script.append(var+".setValueAsync("+getPythonValue(ca.getValue(), type)+").get("+ca.getTimeout()+", TimeUnit.MILLISECONDS)\n");
}
break;
case "putq":
script.append(var+".setValueAsync("+getPythonValue(ca.getValue(), type)+")\n");
break;
case "wait":
script.append(var+".waitForValue("+getPythonValue(ca.getValue(), type)+", "+waitTimeout+")\n");
break;
case "waitREGEX":
imports.add("from"+ComparatorREGEX.class.getPackage().getName()+" import "+ComparatorREGEX.class.getName());
script.append(var+".waitForValue("+getPythonValue(ca.getValue(), type)+", "+ComparatorREGEX.class.getName()+"() "+waitTimeout+")\n");
break;
case "waitOR":
imports.add("from"+ComparatorOR.class.getPackage().getName()+" import "+ComparatorOR.class.getName());
script.append(var+".waitForValue("+getPythonValue(ca.getValue(), type)+", "+ComparatorOR.class.getName()+"() "+waitTimeout+")\n");
break;
case "waitAND":
imports.add("from"+ComparatorAND.class.getPackage().getName()+" import "+ComparatorAND.class.getName());
script.append(var+".waitForValue("+getPythonValue(ca.getValue(), type)+", "+ComparatorAND.class.getName()+"() "+waitTimeout+")\n");
break;
default:
logger.warning("Operation - "+ca.getOperation()+" - is not supported");
// TODO Eventually throw exception - have two modes one logging, one exception?
break;
}
}
else if(action instanceof ShellAction){
ShellAction saction = (ShellAction) action;
// TODO Need to indicate that shell resource is required
script.append(indentation+String.format("shell.execute('%s', %d, %s)\n", saction.getCommand(), saction.getExitValue(), saction.isCheckExitValue()));
}
else if(action instanceof ScriptAction){
ScriptAction saction = (ScriptAction) action;
// TODO Need to indicate that that mapped resources are required
// Read script line by line and prepend the current indentation level
String[] lines = saction.getScript().split(System.getProperty("line.separator"));
for(String s:lines){
script.append(indentation+s);
// If delay is specified wait specified time
if (ca.getDelay() != null) {
imports.add("import time");
script.append("time.sleep(" + (ca.getDelay()) + ")\n");
}
script.append(indentation+"\n");
} else if (action instanceof ShellAction) {
ShellAction saction = (ShellAction) action;
resourceDescriptors.put("shell", new ShellDescriptor());
// TODO Need to indicate that shell resource is required
script.append(indentation + String.format("shell.execute('%s', %d, %s)\n", saction.getCommand(), saction.getExitValue(), saction.isCheckExitValue()?"True":"False"));
} else if (action instanceof ScriptAction) {
ScriptAction saction = (ScriptAction) action;
// TODO Need to indicate that that mapped resources are required
// Read script line by line and prepend the current indentation
// level
String[] lines = saction.getScript().split(System.getProperty("line.separator"));
for (String s : lines) {
script.append(indentation + s);
}
script.append(indentation + "\n");
}
}
}
public void mapPositioners(List<DiscreteStepPositioner> positioners) {
// for (DiscreteStepPositioner p : positioners) {
//
// if (p.getSettlingTime() > stime) {
// stime = p.getSettlingTime();
// }
//
// if (p instanceof LinearPositioner) {
// LinearPositioner lp = (LinearPositioner) p;
// ChannelAccessLinearActuator<?> a;
// if (lp.getType().equals("String")) {
// a = new ChannelAccessLinearActuator<String>(cservice, lp.getName(), lp.getDone(), lp.getDoneValue(), lp.getDoneDelay(), lp.getStart(), lp.getEnd(), lp.getStepSize(), moveTimeout);
// } else if (lp.getType().equals("Double")) {
// a = new ChannelAccessLinearActuator<Double>(cservice, lp.getName(), lp.getDone(), Double.parseDouble(lp.getDoneValue()), lp.getDoneDelay(), lp.getStart(), lp.getEnd(),
// lp.getStepSize(), moveTimeout);
// } else {
// // Default
// a = new ChannelAccessLinearActuator<Integer>(cservice, lp.getName(), lp.getDone(), Integer.parseInt(lp.getDoneValue()), lp.getDoneDelay(), lp.getStart(), lp.getEnd(),
// lp.getStepSize(), moveTimeout);
// }
//
// a.setAsynchronous(lp.isAsynchronous());
// Actor actuator = a;
//
// aLoop.getActors().add(actuator);
//
// // Add a sensor for the readback
// String name = lp.getReadback();
// if (name == null) {
// name = lp.getName();
// }
// ChannelAccessDoubleSensor sensor = new ChannelAccessDoubleSensor(cservice, lp.getId(), name);
// aLoop.getSensors().add(sensor);
// } else if (p instanceof FunctionPositioner) {
// FunctionPositioner lp = (FunctionPositioner) p;
//
// // Create function object
// JythonFunction function = mapFunction(lp.getFunction());
//
// // Create actuator
// ChannelAccessFunctionActuator<?> a;
// if (lp.getType().equals("String")) {
// a = new ChannelAccessFunctionActuator<String>(cservice, lp.getName(), lp.getDone(), lp.getDoneValue(), lp.getDoneDelay(), function, lp.getStart(), lp.getEnd(), lp.getStepSize(),
// moveTimeout);
// } else if (lp.getType().equals("Double")) {
// a = new ChannelAccessFunctionActuator<Double>(cservice, lp.getName(), lp.getDone(), Double.parseDouble(lp.getDoneValue()), lp.getDoneDelay(), function, lp.getStart(), lp.getEnd(),
// lp.getStepSize(), moveTimeout);
// } else {
// // Default
// a = new ChannelAccessFunctionActuator<Integer>(cservice, lp.getName(), lp.getDone(), Integer.parseInt(lp.getDoneValue()), lp.getDoneDelay(), function, lp.getStart(), lp.getEnd(),
// lp.getStepSize(), moveTimeout);
// }
//
// a.setAsynchronous(lp.isAsynchronous());
// Actor actuator = a;
//
// aLoop.getActors().add(actuator);
//
// // Add a sensor for the readback
// String name = lp.getReadback();
// if (name == null) {
// name = lp.getName();
// }
// ChannelAccessDoubleSensor sensor = new ChannelAccessDoubleSensor(cservice, lp.getId(), name);
// aLoop.getSensors().add(sensor);
// } else if (p instanceof ArrayPositioner) {
// ArrayPositioner ap = (ArrayPositioner) p;
// String[] positions = (ap.getPositions().trim()).split(" +");
// double[] table = new double[positions.length];
// for (int i = 0; i < positions.length; i++) {
// table[i] = Double.parseDouble(positions[i]);
// }
//
// ChannelAccessTableActuator<?> a;
// if (p.getType().equals("String")) {
// a = new ChannelAccessTableActuator<String>(cservice, p.getName(), p.getDone(), p.getDoneValue(), p.getDoneDelay(), table, moveTimeout);
// } else if (p.getType().equals("Double")) {
// a = new ChannelAccessTableActuator<Double>(cservice, p.getName(), p.getDone(), Double.parseDouble(p.getDoneValue()), p.getDoneDelay(), table, moveTimeout);
// } else {
// // Default
// a = new ChannelAccessTableActuator<Integer>(cservice, p.getName(), p.getDone(), Integer.parseInt(p.getDoneValue()), p.getDoneDelay(), table, moveTimeout);
// }
//
// a.setAsynchronous(p.isAsynchronous());
// Actor actuator = a;
//
// aLoop.getActors().add(actuator);
//
// // Add a sensor for the readback
// String name = ap.getReadback();
// if (name == null) {
// name = ap.getName();
// }
// ChannelAccessDoubleSensor sensor = new ChannelAccessDoubleSensor(cservice, ap.getId(), name);
// aLoop.getSensors().add(sensor);
// } else if (p instanceof RegionPositioner) {
// RegionPositioner rp = (RegionPositioner) p;
//
// ComplexActuator actuator = new ComplexActuator();
// /*
// * Regions are translated into a complex actor consisting of a
// * LinearActuator If consecutive regions are overlapping, i.e.
// * end point of region a equals the start point of region b then
// * the start point for the LinearActuator of region b is changes
// * to its next step (start+/-stepSize depending on whether end
// * position of the region is > or < start of the region)
// */
// Region lastRegion = null;
// for (Region r : rp.getRegion()) {
// // Normal region
// if (r.getFunction() == null) {
//
// // Check whether regions are consecutive
// double start = r.getStart();
// if (lastRegion != null && start == lastRegion.getEnd()) { // TODO
// // verify
// // whether
// // double
// // comparison
// // is
// // ok
// if (r.getStart() < r.getEnd()) {
// start = start + r.getStepSize();
// } else {
// start = start - r.getStepSize();
// }
// }
//
// // Create actuator
// ChannelAccessLinearActuator<?> act;
// if (rp.getType().equals("String")) {
// act = new ChannelAccessLinearActuator<String>(cservice, rp.getName(), rp.getDone(), rp.getDoneValue(), rp.getDoneDelay(), start, r.getEnd(), r.getStepSize(), moveTimeout);
// } else if (rp.getType().equals("Double")) {
// act = new ChannelAccessLinearActuator<Double>(cservice, rp.getName(), rp.getDone(), Double.parseDouble(rp.getDoneValue()), rp.getDoneDelay(), start, r.getEnd(),
// r.getStepSize(), moveTimeout);
// } else {
// // Default
// act = new ChannelAccessLinearActuator<Integer>(cservice, rp.getName(), rp.getDone(), Integer.parseInt(rp.getDoneValue()), rp.getDoneDelay(), start, r.getEnd(),
// r.getStepSize(), moveTimeout);
// }
//
// act.setAsynchronous(rp.isAsynchronous());
// Actor a = act;
//
// ComplexActuator ca = new ComplexActuator();
// ca.getActors().add(a);
// ca.getPreActions().addAll(mapActions(r.getPreAction()));
// actuator.getActors().add(ca);
// lastRegion = r;
// } else {
// // Function based region
//
// // Cannot check whether the regions are consecutive as
// // the function
// // used might change the start value to something else
// // [THIS LIMITATION NEEDS TO BE SOMEHOW RESOLVED IN THE
// // NEXT VERSIONS]
// JythonFunction function = mapFunction(r.getFunction());
// ChannelAccessFunctionActuator<?> act;
// if (rp.getType().equals("String")) {
// act = new ChannelAccessFunctionActuator<String>(cservice, rp.getName(), rp.getDone(), rp.getDoneValue(), rp.getDoneDelay(), function, r.getStart(), r.getEnd(),
// r.getStepSize(), moveTimeout);
// } else if (rp.getType().equals("Double")) {
// act = new ChannelAccessFunctionActuator<Double>(cservice, rp.getName(), rp.getDone(), Double.parseDouble(rp.getDoneValue()), rp.getDoneDelay(), function, r.getStart(),
// r.getEnd(), r.getStepSize(), moveTimeout);
// } else {
// // Default
// act = new ChannelAccessFunctionActuator<Integer>(cservice, rp.getName(), rp.getDone(), Integer.parseInt(rp.getDoneValue()), rp.getDoneDelay(), function, r.getStart(),
// r.getEnd(), r.getStepSize(), moveTimeout);
// }
//
// act.setAsynchronous(rp.isAsynchronous());
// Actor a = act;
//
// ComplexActuator ca = new ComplexActuator();
// ca.getActors().add(a);
// ca.getPreActions().addAll(mapActions(r.getPreAction()));
// actuator.getActors().add(ca);
// lastRegion = r;
// }
// }
// aLoop.getActors().add(actuator);
//
// // Add a sensor for the readback
// String name = rp.getReadback();
// if (name == null) {
// name = rp.getName();
// }
// ChannelAccessDoubleSensor sensor = new ChannelAccessDoubleSensor(cservice, rp.getId(), name);
// aLoop.getSensors().add(sensor);
// } else if (p instanceof PseudoPositioner) {
// PseudoPositioner pp = (PseudoPositioner) p;
// PseudoActuatorSensor actorSensor = new PseudoActuatorSensor(pp.getId(), pp.getCounts());
//
// // Register as actor
// aLoop.getActors().add(actorSensor);
//
// // Register as sensor
// aLoop.getSensors().add(actorSensor);
// } else {
// // Not supported
// logger.warning("Mapping for " + p.getClass().getName() + " not available");
// }
// }
// for (DiscreteStepPositioner p : positioners) {
//
// if (p.getSettlingTime() > stime) {
// stime = p.getSettlingTime();
// }
//
// if (p instanceof LinearPositioner) {
// LinearPositioner lp = (LinearPositioner) p;
// ChannelAccessLinearActuator<?> a;
// if (lp.getType().equals("String")) {
// a = new ChannelAccessLinearActuator<String>(cservice, lp.getName(),
// lp.getDone(), lp.getDoneValue(), lp.getDoneDelay(), lp.getStart(),
// lp.getEnd(), lp.getStepSize(), moveTimeout);
// } else if (lp.getType().equals("Double")) {
// a = new ChannelAccessLinearActuator<Double>(cservice, lp.getName(),
// lp.getDone(), Double.parseDouble(lp.getDoneValue()),
// lp.getDoneDelay(), lp.getStart(), lp.getEnd(),
// lp.getStepSize(), moveTimeout);
// } else {
// // Default
// a = new ChannelAccessLinearActuator<Integer>(cservice, lp.getName(),
// lp.getDone(), Integer.parseInt(lp.getDoneValue()), lp.getDoneDelay(),
// lp.getStart(), lp.getEnd(),
// lp.getStepSize(), moveTimeout);
// }
//
// a.setAsynchronous(lp.isAsynchronous());
// Actor actuator = a;
//
// aLoop.getActors().add(actuator);
//
// // Add a sensor for the readback
// String name = lp.getReadback();
// if (name == null) {
// name = lp.getName();
// }
// ChannelAccessDoubleSensor sensor = new
// ChannelAccessDoubleSensor(cservice, lp.getId(), name);
// aLoop.getSensors().add(sensor);
// } else if (p instanceof FunctionPositioner) {
// FunctionPositioner lp = (FunctionPositioner) p;
//
// // Create function object
// JythonFunction function = mapFunction(lp.getFunction());
//
// // Create actuator
// ChannelAccessFunctionActuator<?> a;
// if (lp.getType().equals("String")) {
// a = new ChannelAccessFunctionActuator<String>(cservice, lp.getName(),
// lp.getDone(), lp.getDoneValue(), lp.getDoneDelay(), function,
// lp.getStart(), lp.getEnd(), lp.getStepSize(),
// moveTimeout);
// } else if (lp.getType().equals("Double")) {
// a = new ChannelAccessFunctionActuator<Double>(cservice, lp.getName(),
// lp.getDone(), Double.parseDouble(lp.getDoneValue()),
// lp.getDoneDelay(), function, lp.getStart(), lp.getEnd(),
// lp.getStepSize(), moveTimeout);
// } else {
// // Default
// a = new ChannelAccessFunctionActuator<Integer>(cservice,
// lp.getName(), lp.getDone(), Integer.parseInt(lp.getDoneValue()),
// lp.getDoneDelay(), function, lp.getStart(), lp.getEnd(),
// lp.getStepSize(), moveTimeout);
// }
//
// a.setAsynchronous(lp.isAsynchronous());
// Actor actuator = a;
//
// aLoop.getActors().add(actuator);
//
// // Add a sensor for the readback
// String name = lp.getReadback();
// if (name == null) {
// name = lp.getName();
// }
// ChannelAccessDoubleSensor sensor = new
// ChannelAccessDoubleSensor(cservice, lp.getId(), name);
// aLoop.getSensors().add(sensor);
// } else if (p instanceof ArrayPositioner) {
// ArrayPositioner ap = (ArrayPositioner) p;
// String[] positions = (ap.getPositions().trim()).split(" +");
// double[] table = new double[positions.length];
// for (int i = 0; i < positions.length; i++) {
// table[i] = Double.parseDouble(positions[i]);
// }
//
// ChannelAccessTableActuator<?> a;
// if (p.getType().equals("String")) {
// a = new ChannelAccessTableActuator<String>(cservice, p.getName(),
// p.getDone(), p.getDoneValue(), p.getDoneDelay(), table, moveTimeout);
// } else if (p.getType().equals("Double")) {
// a = new ChannelAccessTableActuator<Double>(cservice, p.getName(),
// p.getDone(), Double.parseDouble(p.getDoneValue()), p.getDoneDelay(),
// table, moveTimeout);
// } else {
// // Default
// a = new ChannelAccessTableActuator<Integer>(cservice, p.getName(),
// p.getDone(), Integer.parseInt(p.getDoneValue()), p.getDoneDelay(),
// table, moveTimeout);
// }
//
// a.setAsynchronous(p.isAsynchronous());
// Actor actuator = a;
//
// aLoop.getActors().add(actuator);
//
// // Add a sensor for the readback
// String name = ap.getReadback();
// if (name == null) {
// name = ap.getName();
// }
// ChannelAccessDoubleSensor sensor = new
// ChannelAccessDoubleSensor(cservice, ap.getId(), name);
// aLoop.getSensors().add(sensor);
// } else if (p instanceof RegionPositioner) {
// RegionPositioner rp = (RegionPositioner) p;
//
// ComplexActuator actuator = new ComplexActuator();
// /*
// * Regions are translated into a complex actor consisting of a
// * LinearActuator If consecutive regions are overlapping, i.e.
// * end point of region a equals the start point of region b then
// * the start point for the LinearActuator of region b is changes
// * to its next step (start+/-stepSize depending on whether end
// * position of the region is > or < start of the region)
// */
// Region lastRegion = null;
// for (Region r : rp.getRegion()) {
// // Normal region
// if (r.getFunction() == null) {
//
// // Check whether regions are consecutive
// double start = r.getStart();
// if (lastRegion != null && start == lastRegion.getEnd()) { // TODO
// // verify
// // whether
// // double
// // comparison
// // is
// // ok
// if (r.getStart() < r.getEnd()) {
// start = start + r.getStepSize();
// } else {
// start = start - r.getStepSize();
// }
// }
//
// // Create actuator
// ChannelAccessLinearActuator<?> act;
// if (rp.getType().equals("String")) {
// act = new ChannelAccessLinearActuator<String>(cservice, rp.getName(),
// rp.getDone(), rp.getDoneValue(), rp.getDoneDelay(), start,
// r.getEnd(), r.getStepSize(), moveTimeout);
// } else if (rp.getType().equals("Double")) {
// act = new ChannelAccessLinearActuator<Double>(cservice, rp.getName(),
// rp.getDone(), Double.parseDouble(rp.getDoneValue()),
// rp.getDoneDelay(), start, r.getEnd(),
// r.getStepSize(), moveTimeout);
// } else {
// // Default
// act = new ChannelAccessLinearActuator<Integer>(cservice,
// rp.getName(), rp.getDone(), Integer.parseInt(rp.getDoneValue()),
// rp.getDoneDelay(), start, r.getEnd(),
// r.getStepSize(), moveTimeout);
// }
//
// act.setAsynchronous(rp.isAsynchronous());
// Actor a = act;
//
// ComplexActuator ca = new ComplexActuator();
// ca.getActors().add(a);
// ca.getPreActions().addAll(mapActions(r.getPreAction()));
// actuator.getActors().add(ca);
// lastRegion = r;
// } else {
// // Function based region
//
// // Cannot check whether the regions are consecutive as
// // the function
// // used might change the start value to something else
// // [THIS LIMITATION NEEDS TO BE SOMEHOW RESOLVED IN THE
// // NEXT VERSIONS]
// JythonFunction function = mapFunction(r.getFunction());
// ChannelAccessFunctionActuator<?> act;
// if (rp.getType().equals("String")) {
// act = new ChannelAccessFunctionActuator<String>(cservice,
// rp.getName(), rp.getDone(), rp.getDoneValue(), rp.getDoneDelay(),
// function, r.getStart(), r.getEnd(),
// r.getStepSize(), moveTimeout);
// } else if (rp.getType().equals("Double")) {
// act = new ChannelAccessFunctionActuator<Double>(cservice,
// rp.getName(), rp.getDone(), Double.parseDouble(rp.getDoneValue()),
// rp.getDoneDelay(), function, r.getStart(),
// r.getEnd(), r.getStepSize(), moveTimeout);
// } else {
// // Default
// act = new ChannelAccessFunctionActuator<Integer>(cservice,
// rp.getName(), rp.getDone(), Integer.parseInt(rp.getDoneValue()),
// rp.getDoneDelay(), function, r.getStart(),
// r.getEnd(), r.getStepSize(), moveTimeout);
// }
//
// act.setAsynchronous(rp.isAsynchronous());
// Actor a = act;
//
// ComplexActuator ca = new ComplexActuator();
// ca.getActors().add(a);
// ca.getPreActions().addAll(mapActions(r.getPreAction()));
// actuator.getActors().add(ca);
// lastRegion = r;
// }
// }
// aLoop.getActors().add(actuator);
//
// // Add a sensor for the readback
// String name = rp.getReadback();
// if (name == null) {
// name = rp.getName();
// }
// ChannelAccessDoubleSensor sensor = new
// ChannelAccessDoubleSensor(cservice, rp.getId(), name);
// aLoop.getSensors().add(sensor);
// } else if (p instanceof PseudoPositioner) {
// PseudoPositioner pp = (PseudoPositioner) p;
// PseudoActuatorSensor actorSensor = new
// PseudoActuatorSensor(pp.getId(), pp.getCounts());
//
// // Register as actor
// aLoop.getActors().add(actorSensor);
//
// // Register as sensor
// aLoop.getSensors().add(actorSensor);
// } else {
// // Not supported
// logger.warning("Mapping for " + p.getClass().getName() +
// " not available");
// }
// }
}
/**
* Get unique variable names that do not collide with others. (at least have
* an extreme unlikeness to do so)
*
* @return
*/
private String getUniqueVariableName() {
return "v" + UUID.randomUUID().toString().replaceAll("-", "");
}
/**
* Get unique variable names that do not collide with others. (at least have an extreme unlikeness to do so)
* Get the string representation for a variable in python
* i.e. surrounds String with '', ensures that double has a . in the value, ...
* @param value
* @param type
* @return
*/
private String getUniqueVariableName(){
return "v"+UUID.randomUUID().toString().replaceAll("-", "");
private String getPythonValue(String value, Class<?> type){
if(type.equals(String.class)){
return "'"+value+"'";
}
else if(type.equals(Double.class)){
return String.format("%f", new Double(value));
}
else if(type.equals(Integer.class)){
return String.format("%d", new Integer(value));
}
return value.toString();
}
/**
* Request resource
*
* @param resourceId
* @return variable name for resource
*
* TODO Eventually we need to add type of resource here to be able
* to generate the resource before the script is executed.
*/
private String getChannelResourceVariable(String channelName, Class<?> type, boolean monitor) {
// Right now each a new channel object will be created for each requirested channel resource (even it is the same channel)
// TODO Optimize the resource consumption by checking whether the resource already exists and return only one reference.
String varname = getUniqueVariableName();
resourceDescriptors.put(varname, new ChannelDescriptor<>(type, channelName, monitor));
return varname;
}
//
// String operation = ca.getOperation(); // Default = put
// String type=ca.getType(); // Default = String
//
// if(operation.equals("put")){
// Long timeout = null;
// if(ca.getTimeout()!=null){
// timeout = Math.round(ca.getTimeout()*1000);
// }
// if(type.equals("String")){
// alist.add(new ChannelAccessPut<String>(cservice, ca.getChannel(), ca.getValue(), false, timeout));
// }
// else if(type.equals("Integer")){
// alist.add(new ChannelAccessPut<Integer>(cservice, ca.getChannel(), new Integer(ca.getValue()), false, timeout));
// }
// else if(type.equals("Double")){
// alist.add(new ChannelAccessPut<Double>(cservice, ca.getChannel(), new Double(ca.getValue()), false, timeout));
// }
// }
// else if(operation.equals("putq")){
// if(type.equals("String")){
// alist.add(new ChannelAccessPut<String>(cservice, ca.getChannel(), ca.getValue(), true, null));
// }
// else if(type.equals("Integer")){
// alist.add(new ChannelAccessPut<Integer>(cservice, ca.getChannel(), new Integer(ca.getValue()), true, null));
// }
// else if(type.equals("Double")){
// alist.add(new ChannelAccessPut<Double>(cservice, ca.getChannel(), new Double(ca.getValue()), true, null));
// }
// }
// else if(operation.equals("wait")){
// Long timeout = null ; // Default timeout = wait forever
// if(ca.getTimeout()!=null){
// timeout = Math.round(ca.getTimeout()*1000);
// }
// if(type.equals("String")){
// alist.add(new ChannelAccessCondition<String>(cservice, ca.getChannel(), ca.getValue(), timeout));
// }
// else if(type.equals("Integer")){
// alist.add(new ChannelAccessCondition<Integer>(cservice, ca.getChannel(), new Integer(ca.getValue()), timeout));
// }
// else if(type.equals("Double")){
// alist.add(new ChannelAccessCondition<Double>(cservice, ca.getChannel(), new Double(ca.getValue()), timeout));
// }
// }
// else if(operation.equals("waitREGEX")){
// Long timeout = null ; // Default timeout = wait forever
// if(ca.getTimeout()!=null){
// timeout = Math.round(ca.getTimeout()*1000);
// }
// if(type.equals("String")){
// alist.add(new ChannelAccessConditionRegex<String>(cservice, ca.getChannel(), ca.getValue(), timeout));
// }
// else{
// logger.warning("Operation "+operation+" wity type "+type+" for action is not supported");
// }
// }
// else if(operation.equals("waitOR")){
// Long timeout = null ; // Default timeout = wait forever
// if(ca.getTimeout()!=null){
// timeout = Math.round(ca.getTimeout()*1000);
// }
//
// if(type.equals("Integer")){
// alist.add(new ChannelAccessConditionOr<Integer>(cservice, ca.getChannel(), new Integer(ca.getValue()), timeout));
// }
// else{
// logger.warning("Operation "+operation+" wity type "+type+" for action is not supported");
// }
// }
// else if(operation.equals("waitAND")){
// Long timeout = null ; // Default timeout = wait forever
// if(ca.getTimeout()!=null){
// timeout = Math.round(ca.getTimeout()*1000);
// }
// if(type.equals("Integer")){
// alist.add(new ChannelAccessConditionAnd<Integer>(cservice, ca.getChannel(), new Integer(ca.getValue()), timeout));
// }
// else {
// logger.warning("Operation "+operation+" wity type "+type+" for action is not supported");
// }
// }
// else{
// // Operation not supported
// logger.warning("Operation "+operation+" for action is not supported");
// }
//
// // Translate delay attribute to delay action
// if(ca.getDelay()!=null){
// Double x = ca.getDelay()*1000;
// alist.add(new Delay(x.longValue()));
// }
//
//}
}

View File

@@ -0,0 +1,28 @@
/**
*
* Copyright 2013 Paul Scherrer Institute. All rights reserved.
*
* This code is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This code 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <http://www.gnu.org/licenses/>.
*
*/
package ch.psi.fda.aq;
/**
* Resource descriptor of an operating system shell.
* @author ebner
*
*/
public class ShellDescriptor {
}

View File

@@ -0,0 +1,59 @@
/**
*
* Copyright 2013 Paul Scherrer Institute. All rights reserved.
*
* This code is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This code 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <http://www.gnu.org/licenses/>.
*
*/
package ch.psi.fda.aq;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Logger;
/**
* @author ebner
*
*/
public class ShellResource {
private static final Logger logger = Logger.getLogger(ShellResource.class.getName());
public void execute(String script, int returnValue, boolean checkReturnValue){
ProcessBuilder pb = new ProcessBuilder(new String[]{"/bin/bash","-c",script});
pb.redirectErrorStream(true);
try {
Process p = pb.start();
int rvalue = p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while((line=reader.readLine()) != null){
logger.info(line);
}
// Check return value if need to be checked
if(checkReturnValue){
if(rvalue != returnValue){
throw new RuntimeException("Executing script "+script+" failed");
}
}
} catch (IOException | InterruptedException e) {
throw new RuntimeException("Unable to execute script", e);
}
}
}

View File

@@ -18,17 +18,27 @@
*/
package ch.psi.fda.aq;
import static org.junit.Assert.*;
import java.util.logging.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import ch.psi.fda.TestChannels;
import ch.psi.fda.model.v1.ChannelAction;
import ch.psi.fda.model.v1.Configuration;
import ch.psi.fda.model.v1.Scan;
import ch.psi.fda.model.v1.ScriptAction;
import ch.psi.fda.model.v1.ShellAction;
import ch.psi.jcae.impl.DefaultChannelService;
/**
* @author ebner
*
*/
public class AcquisitionEngineNGTest {
private static final Logger logger = Logger.getLogger(AcquisitionEngineNGTest.class.getName());
private AcquisitionEngineNG engine;
@@ -37,7 +47,7 @@ public class AcquisitionEngineNGTest {
*/
@Before
public void setUp() throws Exception {
engine = new AcquisitionEngineNG();
engine = new AcquisitionEngineNG(new DefaultChannelService());
}
/**
@@ -51,10 +61,50 @@ public class AcquisitionEngineNGTest {
* Test method for {@link ch.psi.fda.aq.AcquisitionEngineNG#execute(java.lang.String)}.
*/
@Test
public void testExecute() {
// engine.execute("import os");
engine.execute("print 'hello'");
// engine.execute("os.system('echo hello world this is a test')");
public void testExecuteChannelAction() {
Configuration config = new Configuration();
config.setScan(new Scan());
// Set value
ChannelAction ca = new ChannelAction();
ca.setChannel(TestChannels.ANALOG_OUT);
ca.setValue("12");
ca.setType("Double");
ca.setDelay(1.2);
config.getScan().getPreAction().add(ca);
// Wait for value
ca = new ChannelAction();
ca.setChannel(TestChannels.ANALOG_OUT);
ca.setValue("13");
ca.setOperation("wait");
ca.setTimeout(10.0);
ca.setType("Double");
config.getScan().getPreAction().add(ca);
ScriptAction sa = new ScriptAction();
sa.setScript("for i in range(0, 3):\n logger.info('hello %d' %i)\n");
ShellAction a = new ShellAction();
a.setCommand("echo hello world this is a test");
// a.setExitValue(1);
config.getScan().getPostAction().add(sa);
config.getScan().getPostAction().add(a);
ScanMapperNG mapper = new ScanMapperNG();
mapper.map(config);
logger.info("Resources to create: "+mapper.getResourceDescriptors());
logger.info("Script to execute: "+mapper.getScript());
engine.execute(mapper.getResourceDescriptors(), mapper.getScript());
}
}

View File

@@ -27,6 +27,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import ch.psi.fda.model.v1.ChannelAction;
import ch.psi.fda.model.v1.Configuration;
import ch.psi.fda.model.v1.DiscreteStepDimension;
import ch.psi.fda.model.v1.Scan;
@@ -62,17 +63,19 @@ public class ScanMapperNGTest {
*/
@Test
public void testMap() {
System.out.println("juhu"+("This is a Java string".hashCode()));
Configuration config = new Configuration();
config.setScan(new Scan());
ShellAction a = new ShellAction();
a.setCommand("echo hello world this is a test");
ChannelAction ca = new ChannelAction();
ca.setValue("hossa");
ca.setDelay(1.2);
config.getScan().getPreAction().add(a);
config.getScan().getPreAction().add(ca);
ScriptAction sa = new ScriptAction();
sa.setScript("print 'hello'");
@@ -80,6 +83,7 @@ public class ScanMapperNGTest {
config.getScan().getPostAction().add(sa);
config.getScan().getPostAction().add(a);
DiscreteStepDimension d = new DiscreteStepDimension();
d.getPreAction().add(a);
d.getAction().add(sa);