diff --git a/ch.psi.fda/pom.xml b/ch.psi.fda/pom.xml
index e6acca9..24d7835 100644
--- a/ch.psi.fda/pom.xml
+++ b/ch.psi.fda/pom.xml
@@ -9,7 +9,7 @@
ch.psi
jcae
- 2.1.9
+ 2.1.10
diff --git a/ch.psi.fda/src/main/java/ch/psi/fda/aq/AcquisitionEngineNG.java b/ch.psi.fda/src/main/java/ch/psi/fda/aq/AcquisitionEngineNG.java
index 682a67a..07abcf4 100644
--- a/ch.psi.fda/src/main/java/ch/psi/fda/aq/AcquisitionEngineNG.java
+++ b/ch.psi.fda/src/main/java/ch/psi/fda/aq/AcquisitionEngineNG.java
@@ -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 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);
}
diff --git a/ch.psi.fda/src/main/java/ch/psi/fda/aq/ScanMapperNG.java b/ch.psi.fda/src/main/java/ch/psi/fda/aq/ScanMapperNG.java
index eeb63da..d573afc 100644
--- a/ch.psi.fda/src/main/java/ch/psi/fda/aq/ScanMapperNG.java
+++ b/ch.psi.fda/src/main/java/ch/psi/fda/aq/ScanMapperNG.java
@@ -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 imports = new HashSet<>();
- private String indentation="";
-
-
-
- public void map(Configuration configuration){
-
+ private Map 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 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 getResourceDescriptors(){
+ return resourceDescriptors;
+ }
+
private void mapDimensions(List 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) actions){
- for(Action action: actions){
- if(action instanceof ChannelAction){
+
+ private void mapActions(List 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 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(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(cservice, lp.getName(), lp.getDone(), Double.parseDouble(lp.getDoneValue()), lp.getDoneDelay(), lp.getStart(), lp.getEnd(),
-// lp.getStepSize(), moveTimeout);
-// } else {
-// // Default
-// a = new ChannelAccessLinearActuator(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(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(cservice, lp.getName(), lp.getDone(), Double.parseDouble(lp.getDoneValue()), lp.getDoneDelay(), function, lp.getStart(), lp.getEnd(),
-// lp.getStepSize(), moveTimeout);
-// } else {
-// // Default
-// a = new ChannelAccessFunctionActuator(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(cservice, p.getName(), p.getDone(), p.getDoneValue(), p.getDoneDelay(), table, moveTimeout);
-// } else if (p.getType().equals("Double")) {
-// a = new ChannelAccessTableActuator(cservice, p.getName(), p.getDone(), Double.parseDouble(p.getDoneValue()), p.getDoneDelay(), table, moveTimeout);
-// } else {
-// // Default
-// a = new ChannelAccessTableActuator(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(cservice, rp.getName(), rp.getDone(), rp.getDoneValue(), rp.getDoneDelay(), start, r.getEnd(), r.getStepSize(), moveTimeout);
-// } else if (rp.getType().equals("Double")) {
-// act = new ChannelAccessLinearActuator(cservice, rp.getName(), rp.getDone(), Double.parseDouble(rp.getDoneValue()), rp.getDoneDelay(), start, r.getEnd(),
-// r.getStepSize(), moveTimeout);
-// } else {
-// // Default
-// act = new ChannelAccessLinearActuator(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(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(cservice, rp.getName(), rp.getDone(), Double.parseDouble(rp.getDoneValue()), rp.getDoneDelay(), function, r.getStart(),
-// r.getEnd(), r.getStepSize(), moveTimeout);
-// } else {
-// // Default
-// act = new ChannelAccessFunctionActuator(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(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(cservice, lp.getName(),
+ // lp.getDone(), Double.parseDouble(lp.getDoneValue()),
+ // lp.getDoneDelay(), lp.getStart(), lp.getEnd(),
+ // lp.getStepSize(), moveTimeout);
+ // } else {
+ // // Default
+ // a = new ChannelAccessLinearActuator(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(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(cservice, lp.getName(),
+ // lp.getDone(), Double.parseDouble(lp.getDoneValue()),
+ // lp.getDoneDelay(), function, lp.getStart(), lp.getEnd(),
+ // lp.getStepSize(), moveTimeout);
+ // } else {
+ // // Default
+ // a = new ChannelAccessFunctionActuator(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(cservice, p.getName(),
+ // p.getDone(), p.getDoneValue(), p.getDoneDelay(), table, moveTimeout);
+ // } else if (p.getType().equals("Double")) {
+ // a = new ChannelAccessTableActuator(cservice, p.getName(),
+ // p.getDone(), Double.parseDouble(p.getDoneValue()), p.getDoneDelay(),
+ // table, moveTimeout);
+ // } else {
+ // // Default
+ // a = new ChannelAccessTableActuator(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(cservice, rp.getName(),
+ // rp.getDone(), rp.getDoneValue(), rp.getDoneDelay(), start,
+ // r.getEnd(), r.getStepSize(), moveTimeout);
+ // } else if (rp.getType().equals("Double")) {
+ // act = new ChannelAccessLinearActuator(cservice, rp.getName(),
+ // rp.getDone(), Double.parseDouble(rp.getDoneValue()),
+ // rp.getDoneDelay(), start, r.getEnd(),
+ // r.getStepSize(), moveTimeout);
+ // } else {
+ // // Default
+ // act = new ChannelAccessLinearActuator(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(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(cservice,
+ // rp.getName(), rp.getDone(), Double.parseDouble(rp.getDoneValue()),
+ // rp.getDoneDelay(), function, r.getStart(),
+ // r.getEnd(), r.getStepSize(), moveTimeout);
+ // } else {
+ // // Default
+ // act = new ChannelAccessFunctionActuator(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(cservice, ca.getChannel(), ca.getValue(), false, timeout));
-// }
-// else if(type.equals("Integer")){
-// alist.add(new ChannelAccessPut(cservice, ca.getChannel(), new Integer(ca.getValue()), false, timeout));
-// }
-// else if(type.equals("Double")){
-// alist.add(new ChannelAccessPut(cservice, ca.getChannel(), new Double(ca.getValue()), false, timeout));
-// }
-// }
-// else if(operation.equals("putq")){
-// if(type.equals("String")){
-// alist.add(new ChannelAccessPut(cservice, ca.getChannel(), ca.getValue(), true, null));
-// }
-// else if(type.equals("Integer")){
-// alist.add(new ChannelAccessPut(cservice, ca.getChannel(), new Integer(ca.getValue()), true, null));
-// }
-// else if(type.equals("Double")){
-// alist.add(new ChannelAccessPut(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(cservice, ca.getChannel(), ca.getValue(), timeout));
-// }
-// else if(type.equals("Integer")){
-// alist.add(new ChannelAccessCondition(cservice, ca.getChannel(), new Integer(ca.getValue()), timeout));
-// }
-// else if(type.equals("Double")){
-// alist.add(new ChannelAccessCondition(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(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(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(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()));
-// }
-//
-//}
-
}
diff --git a/ch.psi.fda/src/main/java/ch/psi/fda/aq/ShellDescriptor.java b/ch.psi.fda/src/main/java/ch/psi/fda/aq/ShellDescriptor.java
new file mode 100644
index 0000000..a1f8e0a
--- /dev/null
+++ b/ch.psi.fda/src/main/java/ch/psi/fda/aq/ShellDescriptor.java
@@ -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 .
+ *
+ */
+package ch.psi.fda.aq;
+
+/**
+ * Resource descriptor of an operating system shell.
+ * @author ebner
+ *
+ */
+public class ShellDescriptor {
+
+}
diff --git a/ch.psi.fda/src/main/java/ch/psi/fda/aq/ShellResource.java b/ch.psi.fda/src/main/java/ch/psi/fda/aq/ShellResource.java
new file mode 100644
index 0000000..14f15ca
--- /dev/null
+++ b/ch.psi.fda/src/main/java/ch/psi/fda/aq/ShellResource.java
@@ -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 .
+ *
+ */
+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);
+ }
+ }
+
+}
diff --git a/ch.psi.fda/src/test/java/ch/psi/fda/aq/AcquisitionEngineNGTest.java b/ch.psi.fda/src/test/java/ch/psi/fda/aq/AcquisitionEngineNGTest.java
index ba5387a..b13aad0 100644
--- a/ch.psi.fda/src/test/java/ch/psi/fda/aq/AcquisitionEngineNGTest.java
+++ b/ch.psi.fda/src/test/java/ch/psi/fda/aq/AcquisitionEngineNGTest.java
@@ -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());
}
}
diff --git a/ch.psi.fda/src/test/java/ch/psi/fda/aq/ScanMapperNGTest.java b/ch.psi.fda/src/test/java/ch/psi/fda/aq/ScanMapperNGTest.java
index 29ed1af..a123b4a 100644
--- a/ch.psi.fda/src/test/java/ch/psi/fda/aq/ScanMapperNGTest.java
+++ b/ch.psi.fda/src/test/java/ch/psi/fda/aq/ScanMapperNGTest.java
@@ -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);