This commit is contained in:
2018-11-23 08:42:01 +01:00
parent c6cd6123b0
commit bf5d1b8d7c
32 changed files with 1961 additions and 20 deletions

View File

@@ -1,5 +1,6 @@
#Thu Aug 02 10:45:31 CEST 2018
#Tue Nov 06 14:31:07 CET 2018
autoSaveScanData=true
commandExecutionEvents=false
createSessionFiles=true
dataLayout=default
dataPath={data}/{year}_{month}/{date}/{date}_{time}_{name}
@@ -9,6 +10,7 @@ dataScanPreserveTypes=false
dataScanReleaseRecords=false
dataServerPort=5573
depthDimension=0
generateCommandExecutionEvents=true
hostName=
instanceName=Dev
logDaysToLive=50
@@ -17,7 +19,7 @@ logLevelConsole=Off
logPath={logs}/{date}_{time}
notificationLevel=Off
scanStreamerPort=5563
serverEnabled=true
serverEnabled=false
serverPort=8080
simulation=false
terminalEnabled=false

View File

@@ -1,7 +1,9 @@
dispatcher=ch.psi.pshell.bs.Provider|tcp://localhost:9999|||
cam_server_local=ch.psi.pshell.bs.PipelineServer|localhost:8889|||true
cam_server=ch.psi.pshell.bs.PipelineServer|sf-daqsync-01:8889|||true
#ts1=ch.psi.pshell.epics.GenericArray|TESTIOC:TESTWF2:MyWF|||
#monit_cam=ch.psi.pshell.imaging.MjpegSource|http://axis-accc8e9cc87b.psi.ch/axis-cgi/mjpg/video.cgi?camera=2 reopen||-200|false
#tststr=ch.psi.pshell.epics.ChannelString|TESTIOC:TESTSINUS:SinCalc|||
#stream=ch.psi.pshell.bs.Stream|<dispatcher> #false:boolean|||
#scalar=ch.psi.pshell.bs.Scalar|stream Int8Scalar|||
#cam=ch.psi.pshell.bs.StreamCamera|"tcp://gfa-lc6-64:10100" 1|||true
@@ -9,7 +11,8 @@ cam_server=ch.psi.pshell.bs.PipelineServer|sf-daqsync-01:8889|||true
#rr=RotationReadback|TESTIOC:TESTCALCOUT:Output|||true
#rp=ch.psi.pshell.epics.Positioner|TESTIOC:TESTCALCOUT:Input null rr|||
#webcam=ch.psi.pshell.webcam.Webcam|:2|||true
#det=ch.psi.pshell.epics.AreaDetector|13SIM1|||false
$det=ch.psi.pshell.epics.AreaDetector|13SIM1|||true
deting=ch.psi.pshell.imaging.CameraSource|det||-500|
#PiezoRoll1=ch.psi.pshell.epics.ControlledVariable|"TESTIOC:TESTCALCOUT:Input" TESTIOC:TESTCALCOUT:Output false|||true
#$ser=ch.psi.pshell.serial.TcpDevice||||
#$beam_ok=ch.psi.pshell.epics.ChannelString|CHANNEL|||
@@ -57,6 +60,11 @@ sin=ch.psi.pshell.epics.ChannelDouble|TESTIOC:TESTSINUS:SinCalc 3 true|||true
#average=ch.psi.pshell.device.Averager|sin||2000|
#isin=ch.psi.pshell.epics.ChannelInteger|TESTIOC:TESTSINUS:SinCalc|||true
arr=ch.psi.pshell.epics.ChannelDoubleArray|TESTIOC:TESTWF2:MyWF 6 -1 false|||true
arr1=ch.psi.pshell.epics.ChannelIntegerArray|TESTIOC:TESTWF2:MyWF -1 false|||
mt=ch.psi.pshell.epics.GenericMatrix|TESTIOC:TESTWF2:MyWF 2 3 false|||
mt1=ch.psi.pshell.epics.GenericMatrix|TESTIOC:TESTWF2:MyWF 3 2 False None [i|||
as1=ch.psi.pshell.imaging.RegisterArraySource|arr1|||
cm1=ch.psi.pshell.epics.ChannelIntegerMatrix|TESTIOC:TESTWF2:MyWF 3 3 false|||
pv=ch.psi.pshell.epics.ProcessVariable|TESTIOC:TESTCALCOUT:Input|||true
shutter=ch.psi.pshell.epics.BinaryPositioner|TESTIOC:TESTBO:MyBO TESTIOC:TESTBO:MyBO|||true
$motor=ch.psi.pshell.epics.Motor|MTEST-GOBBO:MOT1|||true

View File

@@ -1,7 +1,7 @@
#Fri Aug 24 11:15:23 CEST 2018
#Fri Nov 16 23:08:57 CET 2018
ch.psi.jcae.ContextFactory.addressList=127.0.0.1\:54321
ch.psi.jcae.ContextFactory.maxArrayBytes=10000000
ch.psi.jcae.ChannelFactory.timeout=100
ch.psi.jcae.ChannelFactory.timeout=200
ch.psi.jcae.ChannelFactory.retries=1
ch.psi.jcae.ContextFactory.serverPort=
ch.psi.jcae.impl.DefaultChannelService.retries=1

View File

@@ -1,3 +1,5 @@
PID.java=enabled
SpinnerLayoutTest.java=disabled
MXSC-1.10.0.jar=disabled
ScreenPanel3.java=disabled
Tomaz.java=disabled

27
devices/as.properties Normal file
View File

@@ -0,0 +1,27 @@
#Tue Oct 30 09:21:40 CET 2018
colormap=Grayscale
colormapAutomatic=false
colormapLogarithmic=false
colormapMax=NaN
colormapMin=NaN
flipHorizontally=false
flipVertically=false
grayscale=false
imageHeight=3
imageWidth=3
invert=false
rescaleFactor=1.0
rescaleOffset=0.0
roiHeight=-1
roiWidth=-1
roiX=0
roiY=0
rotation=0.0
rotationCrop=false
scale=1.0
spatialCalOffsetX=NaN
spatialCalOffsetY=NaN
spatialCalScaleX=NaN
spatialCalScaleY=NaN
spatialCalUnits=mm
transpose=false

27
devices/as1.properties Normal file
View File

@@ -0,0 +1,27 @@
#Tue Oct 30 09:23:19 CET 2018
colormap=Grayscale
colormapAutomatic=false
colormapLogarithmic=false
colormapMax=NaN
colormapMin=NaN
flipHorizontally=false
flipVertically=false
grayscale=false
imageHeight=3
imageWidth=3
invert=false
rescaleFactor=1.0
rescaleOffset=0.0
roiHeight=-1
roiWidth=-1
roiX=0
roiY=0
rotation=0.0
rotationCrop=false
scale=1.0
spatialCalOffsetX=NaN
spatialCalOffsetY=NaN
spatialCalScaleX=NaN
spatialCalScaleY=NaN
spatialCalUnits=mm
transpose=false

9
devices/cm1.properties Normal file
View File

@@ -0,0 +1,9 @@
#Tue Oct 30 09:41:22 CET 2018
mirror_x=false
mirror_y=false
precision=-1
roi_height=-1
roi_width=-1
roi_x=0
roi_y=0
transpose=false

View File

@@ -0,0 +1,25 @@
#Fri Aug 31 16:53:08 CEST 2018
colormap=Temperature
colormapAutomatic=true
colormapLogarithmic=false
colormapMax=1.0
colormapMin=0.0
flipHorizontally=false
flipVertically=false
grayscale=false
invert=false
rescaleFactor=1.0
rescaleOffset=0.0
roiHeight=-1
roiWidth=-1
roiX=0
roiY=0
rotation=0.0
rotationCrop=false
scale=1.0
spatialCalOffsetX=NaN
spatialCalOffsetY=NaN
spatialCalScaleX=NaN
spatialCalScaleY=NaN
spatialCalUnits=mm
transpose=false

25
devices/deting.properties Normal file
View File

@@ -0,0 +1,25 @@
#Thu Sep 13 17:21:24 CEST 2018
colormap=Grayscale
colormapAutomatic=false
colormapLogarithmic=false
colormapMax=NaN
colormapMin=NaN
flipHorizontally=false
flipVertically=false
grayscale=false
invert=false
rescaleFactor=1.0
rescaleOffset=0.0
roiHeight=-1
roiWidth=-1
roiX=0
roiY=0
rotation=0.0
rotationCrop=false
scale=1.0
spatialCalOffsetX=NaN
spatialCalOffsetY=NaN
spatialCalScaleX=NaN
spatialCalScaleY=NaN
spatialCalUnits=mm
transpose=false

View File

@@ -1,4 +1,4 @@
#Tue Jun 19 17:19:36 CEST 2018
#Tue Oct 16 15:21:38 CEST 2018
accessType=ReadWrite
channel=MTEST-GOBBO\:MOT2
defaultSpeed=0.2
@@ -7,9 +7,9 @@ hasEnable=true
homingDirection=Backward
homingType=Backward
maxSpeed=100.0
maxValue=2.0
maxValue=100.0
minSpeed=0.001
minValue=-2.0
minValue=-100.0
offset=10.0
precision=3
resolution=NaN

9
devices/mt.properties Normal file
View File

@@ -0,0 +1,9 @@
#Tue Oct 30 08:49:48 CET 2018
mirror_x=false
mirror_y=false
precision=-1
roi_height=-1
roi_width=-1
roi_x=0
roi_y=0
transpose=false

9
devices/mt1.properties Normal file
View File

@@ -0,0 +1,9 @@
#Tue Oct 30 08:49:48 CET 2018
mirror_x=false
mirror_y=false
precision=-1
roi_height=-1
roi_width=-1
roi_x=0
roi_y=0
transpose=false

468
plugins/PID.java Normal file
View File

@@ -0,0 +1,468 @@
/**
* Small, easy to use PID implementation with advanced controller capability.<br>
* Minimal usage:<br>
* MiniPID pid = new MiniPID(p,i,d); <br>
* ...looping code...{ <br>
* output= pid.getOutput(sensorvalue,target); <br>
* }
*
* @see http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-direction/improving-the-beginners-pid-introduction
*/
public class PID{
//**********************************
// Class private variables
//**********************************
private double P=0;
private double I=0;
private double D=0;
private double F=0;
private double maxIOutput=0;
private double maxError=0;
private double errorSum=0;
private double maxOutput=0;
private double minOutput=0;
private double setpoint=0;
private double lastActual=0;
private boolean firstRun=true;
private boolean reversed=false;
private double outputRampRate=0;
private double lastOutput=0;
private double outputFilter=0;
private double setpointRange=0;
//**********************************
// Constructor functions
//**********************************
/**
* Create a MiniPID class object.
* See setP, setI, setD methods for more detailed parameters.
* @param p Proportional gain. Large if large difference between setpoint and target.
* @param i Integral gain. Becomes large if setpoint cannot reach target quickly.
* @param d Derivative gain. Responds quickly to large changes in error. Small values prevents P and I terms from causing overshoot.
*/
public PID(double p, double i, double d){
P=p; I=i; D=d;
checkSigns();
}
/**
* Create a MiniPID class object.
* See setP, setI, setD, setF methods for more detailed parameters.
* @param p Proportional gain. Large if large difference between setpoint and target.
* @param i Integral gain. Becomes large if setpoint cannot reach target quickly.
* @param d Derivative gain. Responds quickly to large changes in error. Small values prevents P and I terms from causing overshoot.
* @param f Feed-forward gain. Open loop "best guess" for the output should be. Only useful if setpoint represents a rate.
*/
public PID(double p, double i, double d, double f){
P=p; I=i; D=d; F=f;
checkSigns();
}
//**********************************
// Configuration functions
//**********************************
/**
* Configure the Proportional gain parameter. <br>
* This responds quickly to changes in setpoint, and provides most of the initial driving force
* to make corrections. <br>
* Some systems can be used with only a P gain, and many can be operated with only PI.<br>
* For position based controllers, this is the first parameter to tune, with I second. <br>
* For rate controlled systems, this is often the second after F.
*
* @param p Proportional gain. Affects output according to <b>output+=P*(setpoint-current_value)</b>
*/
public void setP(double p){
P=p;
checkSigns();
}
/**
* Changes the I parameter <br>
* This is used for overcoming disturbances, and ensuring that the controller always gets to the control mode.
* Typically tuned second for "Position" based modes, and third for "Rate" or continuous based modes. <br>
* Affects output through <b>output+=previous_errors*Igain ;previous_errors+=current_error</b>
*
* @see {@link #setMaxIOutput(double) setMaxIOutput} for how to restrict
*
* @param i New gain value for the Integral term
*/
public void setI(double i){
if(I!=0){
errorSum=errorSum*I/i;
}
if(maxIOutput!=0){
maxError=maxIOutput/i;
}
I=i;
checkSigns();
// Implementation note:
// This Scales the accumulated error to avoid output errors.
// As an example doubling the I term cuts the accumulated error in half, which results in the
// output change due to the I term constant during the transition.
}
/**
* Changes the D parameter <br>
* This has two primary effects:
* <list>
* <li> Adds a "startup kick" and speeds up system response during setpoint changes
* <li> Adds "drag" and slows the system when moving toward the target
* </list>
* A small D value can be useful for both improving response times, and preventing overshoot.
* However, in many systems a large D value will cause significant instability, particularly
* for large setpoint changes.
* <br>
* Affects output through <b>output += -D*(current_input_value - last_input_value)</b>
*
* @param d New gain value for the Derivative term
*/
public void setD(double d){
D=d;
checkSigns();
}
/**
* Configure the FeedForward parameter. <br>
* This is excellent for velocity, rate, and other continuous control modes where you can
* expect a rough output value based solely on the setpoint.<br>
* Should not be used in "position" based control modes.<br>
* Affects output according to <b>output+=F*Setpoint</b>. Note, that a F-only system is actually open loop.
*
* @param f Feed forward gain.
*/
public void setF(double f){
F=f;
checkSigns();
}
/**
* Configure the PID object.
* See setP, setI, setD methods for more detailed parameters.
* @param p Proportional gain. Large if large difference between setpoint and target.
* @param i Integral gain. Becomes large if setpoint cannot reach target quickly.
* @param d Derivative gain. Responds quickly to large changes in error. Small values prevents P and I terms from causing overshoot.
*/
public void setPID(double p, double i, double d){
P=p;D=d;
//Note: the I term has additional calculations, so we need to use it's
//specific method for setting it.
setI(i);
checkSigns();
}
/**
* Configure the PID object.
* See setP, setI, setD, setF methods for more detailed parameters.
* @param p Proportional gain. Large if large difference between setpoint and target.
* @param i Integral gain. Becomes large if setpoint cannot reach target quickly.
* @param d Derivative gain. Responds quickly to large changes in error. Small values prevents P and I terms from causing overshoot.
* @param f Feed-forward gain. Open loop "best guess" for the output should be. Only useful if setpoint represents a rate.
*/
public void setPID(double p, double i, double d,double f){
P=p;D=d;F=f;
//Note: the I term has additional calculations, so we need to use it's
//specific method for setting it.
setI(i);
checkSigns();
}
/**
* Set the maximum output value contributed by the I component of the system
* This can be used to prevent large windup issues and make tuning simpler
* @param maximum. Units are the same as the expected output value
*/
public void setMaxIOutput(double maximum){
// Internally maxError and Izone are similar, but scaled for different purposes.
// The maxError is generated for simplifying math, since calculations against
// the max error are far more common than changing the I term or Izone.
maxIOutput=maximum;
if(I!=0){
maxError=maxIOutput/I;
}
}
/**
* Specify a maximum output range. <br>
* When one input is specified, output range is configured to
* <b>[-output, output]</b>
* @param output
*/
public void setOutputLimits(double output){
setOutputLimits(-output,output);
}
/**
* Specify a maximum output.
* When two inputs specified, output range is configured to
* <b>[minimum, maximum]</b>
* @param minimum possible output value
* @param maximum possible output value
*/
public void setOutputLimits(double minimum,double maximum){
if(maximum<minimum)return;
maxOutput=maximum;
minOutput=minimum;
// Ensure the bounds of the I term are within the bounds of the allowable output swing
if(maxIOutput==0 || maxIOutput>(maximum-minimum) ){
setMaxIOutput(maximum-minimum);
}
}
/**
* Set the operating direction of the PID controller
* @param reversed Set true to reverse PID output
*/
public void setDirection(boolean reversed){
this.reversed=reversed;
}
//**********************************
// Primary operating functions
//**********************************
/**
* Configure setpoint for the PID calculations<br>
* This represents the target for the PID system's, such as a
* position, velocity, or angle. <br>
* @see PID#getOutput(actual) <br>
* @param setpoint
*/
public void setSetpoint(double setpoint){
this.setpoint=setpoint;
}
/**
* Calculate the output value for the current PID cycle.<br>
* @param actual The monitored value, typically as a sensor input.
* @param setpoint The target value for the system
* @return calculated output value for driving the system
*/
public double getOutput(double actual, double setpoint){
double output;
double Poutput;
double Ioutput;
double Doutput;
double Foutput;
this.setpoint=setpoint;
// Ramp the setpoint used for calculations if user has opted to do so
if(setpointRange!=0){
setpoint=constrain(setpoint,actual-setpointRange,actual+setpointRange);
}
// Do the simple parts of the calculations
double error=setpoint-actual;
// Calculate F output. Notice, this depends only on the setpoint, and not the error.
Foutput=F*setpoint;
// Calculate P term
Poutput=P*error;
// If this is our first time running this, we don't actually _have_ a previous input or output.
// For sensor, sanely assume it was exactly where it is now.
// For last output, we can assume it's the current time-independent outputs.
if(firstRun){
lastActual=actual;
lastOutput=Poutput+Foutput;
firstRun=false;
}
// Calculate D Term
// Note, this is negative. This actually "slows" the system if it's doing
// the correct thing, and small values helps prevent output spikes and overshoot
Doutput= -D*(actual-lastActual);
lastActual=actual;
// The Iterm is more complex. There's several things to factor in to make it easier to deal with.
// 1. maxIoutput restricts the amount of output contributed by the Iterm.
// 2. prevent windup by not increasing errorSum if we're already running against our max Ioutput
// 3. prevent windup by not increasing errorSum if output is output=maxOutput
Ioutput=I*errorSum;
if(maxIOutput!=0){
Ioutput=constrain(Ioutput,-maxIOutput,maxIOutput);
}
// And, finally, we can just add the terms up
output=Foutput + Poutput + Ioutput + Doutput;
// Figure out what we're doing with the error.
if(minOutput!=maxOutput && !bounded(output, minOutput,maxOutput) ){
errorSum=error;
// reset the error sum to a sane level
// Setting to current error ensures a smooth transition when the P term
// decreases enough for the I term to start acting upon the controller
// From that point the I term will build up as would be expected
}
else if(outputRampRate!=0 && !bounded(output, lastOutput-outputRampRate,lastOutput+outputRampRate) ){
errorSum=error;
}
else if(maxIOutput!=0){
errorSum=constrain(errorSum+error,-maxError,maxError);
// In addition to output limiting directly, we also want to prevent I term
// buildup, so restrict the error directly
}
else{
errorSum+=error;
}
// Restrict output to our specified output and ramp limits
if(outputRampRate!=0){
output=constrain(output, lastOutput-outputRampRate,lastOutput+outputRampRate);
}
if(minOutput!=maxOutput){
output=constrain(output, minOutput,maxOutput);
}
if(outputFilter!=0){
output=lastOutput*outputFilter+output*(1-outputFilter);
}
// Get a test printline with lots of details about the internal
// calculations. This can be useful for debugging.
// System.out.printf("Final output %5.2f [ %5.2f, %5.2f , %5.2f ], eSum %.2f\n",output,Poutput, Ioutput, Doutput,errorSum );
// System.out.printf("%5.2f\t%5.2f\t%5.2f\t%5.2f\n",output,Poutput, Ioutput, Doutput );
lastOutput=output;
return output;
}
/**
* Calculate the output value for the current PID cycle.<br>
* In no-parameter mode, this uses the last sensor value,
* and last setpoint value. <br>
* Not typically useful, and use of parameter modes is suggested. <br>
* @return calculated output value for driving the system
*/
public double getOutput(){
return getOutput(lastActual,setpoint);
}
/**
* Calculate the output value for the current PID cycle.<br>
* In one parameter mode, the last configured setpoint will be used.<br>
* @see PID#setSetpoint()
* @param actual The monitored value, typically as a sensor input.
* @param setpoint The target value for the system
* @return calculated output value for driving the system
*/
public double getOutput(double actual){
return getOutput(actual,setpoint);
}
/**
* Resets the controller. This erases the I term buildup, and removes
* D gain on the next loop.<br>
* This should be used any time the PID is disabled or inactive for extended
* duration, and the controlled portion of the system may have changed due to
* external forces.
*/
public void reset(){
firstRun=true;
errorSum=0;
}
/**
* Set the maximum rate the output can increase per cycle.<br>
* This can prevent sharp jumps in output when changing setpoints or
* enabling a PID system, which might cause stress on physical or electrical
* systems. <br>
* Can be very useful for fast-reacting control loops, such as ones
* with large P or D values and feed-forward systems.
*
* @param rate, with units being the same as the output
*/
public void setOutputRampRate(double rate){
outputRampRate=rate;
}
/**
* Set a limit on how far the setpoint can be from the current position
* <br>Can simplify tuning by helping tuning over a small range applies to a much larger range.
* <br>This limits the reactivity of P term, and restricts impact of large D term
* during large setpoint adjustments. Increases lag and I term if range is too small.
* @param range, with units being the same as the expected sensor range.
*/
public void setSetpointRange(double range){
setpointRange=range;
}
/**
* Set a filter on the output to reduce sharp oscillations. <br>
* 0.1 is likely a sane starting value. Larger values use historical data
* more heavily, with low values weigh newer data. 0 will disable, filtering, and use
* only the most recent value. <br>
* Increasing the filter strength will P and D oscillations, but force larger I
* values and increase I term overshoot.<br>
* Uses an exponential wieghted rolling sum filter, according to a simple <br>
* <pre>output*(1-strength)*sum(0..n){output*strength^n}</pre> algorithm.
* @param output valid between [0..1), meaning [current output only.. historical output only)
*/
public void setOutputFilter(double strength){
if(strength==0 || bounded(strength,0,1)){
outputFilter=strength;
}
}
//**************************************
// Helper functions
//**************************************
/**
* Forces a value into a specific range
* @param value input value
* @param min maximum returned value
* @param max minimum value in range
* @return Value if it's within provided range, min or max otherwise
*/
private double constrain(double value, double min, double max){
if(value > max){ return max;}
if(value < min){ return min;}
return value;
}
/**
* Test if the value is within the min and max, inclusive
* @param value to test
* @param min Minimum value of range
* @param max Maximum value of range
* @return true if value is within range, false otherwise
*/
private boolean bounded(double value, double min, double max){
// Note, this is an inclusive range. This is so tests like
// `bounded(constrain(0,0,1),0,1)` will return false.
// This is more helpful for determining edge-case behaviour
// than <= is.
return (min<value) && (value<max);
}
/**
* To operate correctly, all PID parameters require the same sign
* This should align with the {@literal}reversed value
*/
private void checkSigns(){
if(reversed){ // all values should be below zero
if(P>0) P*=-1;
if(I>0) I*=-1;
if(D>0) D*=-1;
if(F>0) F*=-1;
}
else{ // all values should be above zero
if(P<0) P*=-1;
if(I<0) I*=-1;
if(D<0) D*=-1;
if(F<0) F*=-1;
}
}
}

27
script/AreaDetectorROI.py Normal file
View File

@@ -0,0 +1,27 @@
device = det
det.imageCounter.polling = 500
class AreaDetectorROI(ReadonlyRegisterBase, ReadonlyRegisterMatrix):
def __init__(self, name, detector, x, y, w, h):
ReadonlyRegisterBase.__init__(self, name)
self.detector = detector
self.x, self.y, self.w, self.h = x, y, w, h
def doRead(self):
data = self.detector.dataMatrix.take()
ret = Convert.matrixRoi(data, self.x, self.y, self.w, self.h)
return ret
def getWidth(self):
return self.w
def getHeight(self):
return self.h
add_device(AreaDetectorROI("roi1", device, 10,10,10,5), True)
add_device(AreaDetectorROI("roi2", device,100,30,7,3), True)
#tscan((roi1, roi2), 10, 0.1)
mscan(device.imageCounter, (roi1, roi2), 10, async=False)

0
script/TestPID.py Normal file
View File

View File

@@ -1,18 +1,21 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// Deployment specific global definitions - executed after startup.groovy
///////////////////////////////////////////////////////////////////////////////////////////////////
import ch.psi.pshell.scan.ScanRecord
import ch.psi.pshell.scan.ScanRecord
System.out.println("OK")
before_readout = { double[] pos-> println (pos) }
after_readout = { ScanRecord rec->println (rec) }
after_readout = { ch.psi.pshell.scan.ScanRecord rec->println (rec) }
def onBeforeReadout(double[]pos){
println (pos)
}
def onAfterReadout(ScanRecord rec){
def onAfterReadout(ch.psi.pshell.scan.ScanRecord rec){
println (rec)
}
}
////

View File

@@ -10,4 +10,5 @@ function onAfterReadout(rec){
run("SimulatedDEvices")
run("SimulatedDEvices")

View File

@@ -8,17 +8,21 @@ import ch.psi.pshell.crlogic.CrlogicPositioner as CrlogicPositioner
import ch.psi.pshell.crlogic.CrlogicSensor as CrlogicSensor
def on_command_started(info):
print "Started: " + str(info.script) + str(info.error)
def on_command_finished(info):
print "Finished: " + str(info.script) + str(info.error)
###################################################################################################
# Layout setup
###################################################################################################
import ch.psi.pshell.data.LayoutSF as LayoutSF
LayoutSF.setExperimentArguments([pv, motor, pe, cv, en, sin])
LayoutSF.setExperimentArguments([pv, motor, pe, cv, energy, sin])
#Libraries
#Librariesenergy
#import Jama.Matrix
#sys.path.append('/Users/gobbo_a/dev/pshell/config/home/script/Lib/diffcalc')
@@ -136,14 +140,14 @@ get_context().addListener(clistener)
def trig_scienta():
time.sleep(1.0)
energy = None
en_val = None
class SimulatedEnergy(Writable):
def write(self, value):
self.put(value)
def put(self, value, timeout = None):
global energy
energy = value
global en_val
en_val = value
def close(self):
pass
@@ -155,8 +159,8 @@ class SimulatedEnergy(Writable):
class SimulatedEnergyReadback(Readable):
def read(self):
global energy
return energy;
global en_val
return en_val;
def get(self):
return self.read()

14
script/test/CustomPlot.py Normal file
View File

@@ -0,0 +1,14 @@
p = plot(None, title="Custom Plot")[0]
p.addSeries(LinePlotSeries("My Series"))
proc_data = "/proc/calc"
create_dataset(proc_data , 'd')
def AfterReadout(record, scan):
val = record.values[1] - record.values[0]
p.getSeries(0).appendData(record.positions[0], val)
append_dataset(proc_data , val)
lscan(inp, (out, sin), 0.0, 10.0, 1.0, latency = 0.1, after_read=AfterReadout)

22
script/test/TestChanel.py Normal file
View File

@@ -0,0 +1,22 @@
import ch.psi.pshell.epics.CAS as CAS
import random
class Waveform(ReadonlyRegisterBase, ReadonlyRegisterArray):
def doRead(self):
ret = []
for i in range(self.getSize()):
ret.append(random.random())
ret = to_array(ret, 'd')
return ret
def getSize(self):
return 1000
wf = Waveform("wf")
wf.initialize()
print wf.read()[0]
casN = CAS("TESTCAS:VAL", wf, 'double')
print casN
print caget("TESTCAS:VAL")

78
script/test/TestData.py Normal file
View File

@@ -0,0 +1,78 @@
###################################################################################################
#Data Manipulation: Using the data access API to generate and retrieve data
###################################################################################################
#Creating a 1D dataset from an array
path="group/data1"
data1d = [1.0, 2.0, 3.0, 4.0, 5.0]
save_dataset(path, data1d)
#Reading ii back
read =load_data(path)
print read.tolist()
assert data1d==read.tolist()
plot(read)
#Creating a 2D dataset from an array with some attributes
data2d = [ [1.0, 2.0, 3.0, 4.0, 5.0], [2.0, 3.0, 4.0, 5.0, 6.0, ], [3.0, 4.0, 5.0, 6.0, 7.0]]
path="group/data2"
save_dataset(path, data2d)
set_attribute(path, "AttrString", "Value")
set_attribute(path, "AttrInteger", 1)
set_attribute(path, "AttrDouble", 2.0)
set_attribute(path, "AttrBoolean", True)
#Reading it back
read =load_data(path)
print read.tolist()
plot(read)
#Creating a 3D dataset from an array
data3d = [ [ [1,2,3,4,5], [2,3,4,5,6], [3,4,5,6,7]], [ [3,2,3,4,5], [4,3,4,5,6], [5,4,5,6,7]]]
path="group/data3"
save_dataset(path, data3d)
#Reading it back
read =load_data(path,0)
print read.tolist()
read =load_data(path,1)
print read.tolist()
#Creating a INT dataset adding elements one by one
path = "group/data4"
create_dataset(path, 'i')
for i in range(10):
append_dataset(path,i)
#Creating a 2D data FLOAT dataset adding lines one by one
path = "group/data5"
create_dataset(path, 'd', False, (0,0))
for row in data2d:
append_dataset(path, row)
#Creating a Table (compund type)
path = "group/data6"
names = ["a", "b", "c", "d"]
types = ["d", "d", "d", "[d"]
lenghts = [0,0,0,5]
table = [ [1,2,3,[0,1,2,3,4]],
[2,3,4,[3,4,5,6,7]],
[3,4,5,[6,7,8,9,4]] ]
create_table(path, names, types, lenghts)
for row in table:
append_table(path, row)
flush_data()
#Read it back
read =load_data(path)
print read
#Writing scalars (datasets with rank 0)
save_dataset("group/val1", 1)
save_dataset("group/val2", 3.14)
save_dataset("group/val3", "test")
print load_data("group/val1")
print load_data("group/val2")
print load_data("group/val3")

View File

@@ -0,0 +1,22 @@
class DetectorRoi(ReadonlyRegisterBase, ReadonlyRegisterMatrix):
def doRead(self):
#data = caget(“PINK:GEYES:image2:ArrayData")
data = caget("TESTCAS:VAL", '[d', self.getHeight() * self.getWidth())
return Convert.reshape(data,self.getHeight(), self.getWidth()) #
def getWidth(self):
return 50
def getHeight(self):
return 20
add_device (DetectorRoi("detector_roi"), True)
add_device(RegisterMatrixSource("detector_roi_img", detector_roi), True)
detector_roi_img.polling = -500

557
script/test/TestDiff.py Normal file
View File

@@ -0,0 +1,557 @@
###################################################################################################\
# Diffcalc utilities
###################################################################################################
###################################################################################################\
# Installaling
###################################################################################################
#1- Download from: https://github.com/DiamondLightSource/diffcalc/archive/master.zip
#2- Extract the contents to {script}/Lib/diffcalc
#3- Download http://central.maven.org/maven2/gov/nist/math/jama/1.0.3/jama-1.0.3.jar
# to the extensions folder.
###################################################################################################\
# Library loading and Hardware setup
###################################################################################################
#1- Create a MotorGroup with the diffractometer motors
# e.g. 'sixc', containing mu, delta, gam, eta, chi, phi motors (gam = nu)
# or 'fivec', containing delta, gam, eta, chi, phi motors
# or 'fourc', containing delta, eta, chi, phi motors
#2- Create positioner to read/set the energy in kEv, e.g. named 'en'
#3- Execute: run("diffutils")
#4- Execute: setup_diff(sixc, en)
from __future__ import absolute_import
import traceback
import Jama.Matrix
diffcalc_path = os.path.abspath(get_context().setup.expandPath("{script}/Lib/diffcalc"))
if not diffcalc_path in sys.path:
sys.path.append(diffcalc_path)
import diffcalc
from diffcalc import settings
from diffcalc.hkl.you.geometry import YouGeometry,SixCircle, FiveCircle, FourCircle, YouPosition
from diffcalc.hardware import HardwareAdapter
from diffcalc.ub.persistence import UbCalculationNonPersister
from diffcalc.gdasupport.minigda.scannable import ScannableBase, ScannableGroup
#from diffcalc.gdasupport.minigda import command
from diffcalc.hardware import HardwareAdapter
import ch.psi.pshell.device.PositionerConfig as PositionerConfig
import ch.psi.pshell.device.RegisterConfig as RegisterConfig
import ch.psi.pshell.device.Register as Register
_difcalc_names = {}
#
# Disable error handling designed for interactive use
#diffcalc.util.DEBUG = True
###################################################################################################
# Device mapping to difcalc
###################################################################################################
class PositionerScannable(ScannableBase):
def __init__(self, positioner, name = None):
self.positioner = positioner
self.name = positioner.name if name is None else name
self.inputNames = [self.name]
self.outputFormat = ['% 6.4f']
self.level = 3
def isBusy(self):
return self.positioner.state == State.Busy
def waitWhileBusy(self):
self.positioner.waitReady(-1)
def asynchronousMoveTo(self, new_position):
#print "Moving " , self.name, " to: ", new_position
self.positioner.moveAsync(float(new_position), -1)
def getPosition(self):
return self.positioner.getPosition()
def _get_diffcalc_axis_names():
nu_name=diffcalc.hkl.you.constraints.NUNAME
return ("mu", "delta", nu_name, "eta", "chi", "phi")
class PositionerScannableGroup(ScannableGroup):
def __init__(self, name, motors, diffcalc_axis_names=None):
self.name = name
global _difcalc_names
_difcalc_names = {}
positioners = []
if diffcalc_axis_names is None:
if len(motors) == 6: diffcalc_axis_names = _get_diffcalc_axis_names()
elif len(motors) == 5: diffcalc_axis_names = ("delta", "gam", "eta", "chi", " phi")
elif len(motors) == 4: diffcalc_axis_names = ("delta", "eta", "chi", " phi")
for i in range(len(motors)):
_difcalc_names[motors[i]] = diffcalc_axis_names[i]
exec('self.' + diffcalc_axis_names[i] + ' = PositionerScannable(' + motors[i].name + ', "' +diffcalc_axis_names[i] + '")')
exec('positioners.append(self.' + diffcalc_axis_names[i] + ')' )
#for m in motors:
# exec('self.' + m.name + ' = PositionerScannable(' + m.name + ', "' + m.name + '")')
# exec('positioners.append(self.' + m.name + ')' )
ScannableGroup.__init__(self, self.name, positioners)
class MotorGroupScannable(PositionerScannableGroup):
def __init__(self, motor_group, diffcalc_axis_names=None):
self.motor_group = motor_group
PositionerScannableGroup.__init__(self, motor_group.name, motor_group.motors, diffcalc_axis_names)
class ScannableAdapter(HardwareAdapter):
def __init__(self, diffractometer, energy, energy_multiplier_to_kev=1):
self.diffractometer = diffractometer
self.energy = energy
self.energy_multiplier_to_kev = energy_multiplier_to_kev
input_names = diffractometer.getInputNames()
HardwareAdapter.__init__(self, input_names)
#Returns the current physical POSITIONS
def get_position(self):
"""
pos = getDiffractometerPosition() -- returns the current physical
diffractometer position as a list in degrees
"""
return self.diffractometer.getPosition()
#returns energy in kEv
def get_energy(self):
"""energy = get_energy() -- returns energy in kEv (NOT eV!) """
multiplier = self.energy_multiplier_to_kev
energy = self.energy.getPosition() * multiplier
if energy is None:
raise DiffcalcException("Energy has not been set")
return energy
@property
def name(self):
return self.diffractometer.getName()
class MotorGroupAdapter(ScannableAdapter):
def __init__(self, diffractometer, energy, energy_multiplier_to_kev=1, diffcalc_axis_names=None):
self.diffractometer = MotorGroupScannable(diffractometer, diffcalc_axis_names)
self.energy = PositionerScannable(energy)
self.energy.level = 3
ScannableAdapter.__init__(self, self.diffractometer, self.energy, energy_multiplier_to_kev)
class Wavelength(RegisterBase):
def doRead(self):
try:
return get_wavelength().getPosition()
except:
return None
def doWrite(self, val):
get_wavelength().asynchronousMoveTo(val)
###################################################################################################
# HKL Pseudo-devices
###################################################################################################
class HklPositoner (PositionerBase):
def __init__(self, name, index, hkl_group):
PositionerBase.__init__(self, name, PositionerConfig())
self.setParent(hkl_group)
self.index = index
def isReady(self):
return PositionerBase.isReady(self) and self.getParent().isReady()
def doRead(self):
return self.getParent()._setpoint[self.index]
def doWrite(self, value):
#print "Setting " , self.getName(), "to: ", value
pos = [None, None, None]
pos[self.index] = value
self.getParent().write(pos)
def doReadReadback(self):
if java.lang.Thread.currentThread() != self.getParent()._updating_thread:
self.getParent().update()
return self.getParent()._readback[self.index]
class HklGroup(RegisterBase, Register.RegisterArray):
def __init__(self, name):
RegisterBase.__init__(self, name, RegisterConfig())
self.hkl=get_hkl()
self.h, self.k, self.l = HklPositoner("h", 0, self), HklPositoner("k", 1, self), HklPositoner("l", 2, self)
add_device(self.h, True)
add_device(self.k, True)
add_device(self.l, True)
self._setpoint = self.doRead()
self._updating = False
def getSize(self):
return 3
def doRead(self):
try:
self._readback = self.hkl.getPosition()
self._updating_thread = java.lang.Thread.currentThread()
self.h.update()
self.k.update()
self.l.update()
except:
#traceback.print_exc()
self._readback = (None, None, None)
finally:
self._updating_thread = None
return self._readback
def doWrite(self, pos):
self._setpoint = pos
#print "Moving to: " + str(pos)
self.hkl.asynchronousMoveTo(pos)
def sim(self, pos):
return self.hkl.simulateMoveTo(pos)
###################################################################################################
# System setup
###################################################################################################
you = None
dc, ub, hardware, hkl = None, None, None, None
_motor_group = None
def setup_diff(diffractometer, energy, diffcalc_axis_names = None, geometry=None):
"""
diffractometer: Diffraction motor group
energy: Positioner having energy in kev
geometry: YouGeometry extension. If none, uses default
diffcalc_axis_names: if None use defaults:
- mu, delta, gam, eta, chi, phi (six circle)
- delta, gam, eta, chi, phi (ficve circle)
- delta, eta, chi, phi (four circle)
"""
global you, dc, ub, hardware, hkl, _motor_group
_motor_group = diffractometer
you = None
if geometry is not None:
settings.geometry = geometry
elif diffcalc_axis_names is not None:
class CustomGeometry(YouGeometry):
def __init__(self):
self.all_axis_names = _get_diffcalc_axis_names()
self.my_axis_names = diffcalc_axis_names
fixed_constraints = {}
for axis in self.all_axis_names:
if not axis in self.my_axis_names:
fixed_constraints[axis] = 0
YouGeometry.__init__(self, diffractometer.name, fixed_constraints)
def physical_angles_to_internal_position(self, physical_angle_tuple):
pos=[]
index = 0
for axis in self.all_axis_names:
pos.append(physical_angle_tuple[index] if (axis in self.my_axis_names) else 0)
index = index+1
return YouPosition(*pos)
def internal_position_to_physical_angles(self, internal_position):
pos = internal_position.totuple()
ret = []
for i in range (len(self.all_axis_names)):
if self.all_axis_names[i] in self.my_axis_names:
ret.append(pos[i])
return tuple(ret)
settings.geometry = CustomGeometry()
elif len(diffractometer.motors) == 6:
settings.geometry = SixCircle()
elif len(diffractometer.motors) == 5:
settings.geometry = FiveCircle()
elif len(diffractometer.motors) == 4:
settings.geometry = FourCircle()
else:
raise Exception("Invalid motor group")
settings.hardware = MotorGroupAdapter(diffractometer, energy, diffcalc_axis_names = diffcalc_axis_names)
settings.ubcalc_persister = UbCalculationNonPersister()
settings.axes_scannable_group = settings.hardware.diffractometer
settings.energy_scannable = settings.hardware.energy
settings.ubcalc_strategy = diffcalc.hkl.you.calc.YouUbCalcStrategy()
settings.angles_to_hkl_function = diffcalc.hkl.you.calc.youAnglesToHkl
from diffcalc.gdasupport import you
reload(you)
# These must be imported AFTER the settings have been configured
from diffcalc.dc import dcyou as dc
from diffcalc.ub import ub
from diffcalc import hardware
from diffcalc.hkl.you import hkl
add_device(HklGroup("hkl_group"), True)
add_device(Wavelength("wavelength", 6), True)
hkl_group.polling = 250
wavelength.polling = 250
def setup_axis(motor, min=None, max=None, cut=None):
name = _difcalc_names[motor]
if min is not None: hardware.setmin(name, min)
if max is not None: hardware.setmax(name, max)
if cut is not None: hardware.setcut(name, cut)
def print_axis_setup():
print "Diffcalc names:"
for m in _difcalc_names.keys():
print " \t" + m.name + " = " + _difcalc_names[m]
print "------------------------------------------------------"
hardware.hardware()
###################################################################################################
# Acceess functions
###################################################################################################
def get_diff():
return settings.hardware.diffractometer
def get_en():
return settings.hardware.energy
def get_motor_group():
return _motor_group
def get_wavelength():
return you.wl
def get_hkl():
return you.hkl
def hkl_to_angles(h, k, l, energy=None):
return dc.hkl_to_angles(h, k, l, energy)
def angles_to_hkl(positions, energy=None):
return dc.angles_to_hkl(positions, energy)
def hkl_read():
return hkl_group.read()
def hkl_write(h, k, l):
hkl_group.write([h,k,l])
def hkl_simulate(h, k, l):
return hkl_group.sim([h,k,l])
def con(*args):
hkl.con(*args)
def uncon(name):
hkl.uncon(name)
def print_con():
hkl.con()
###################################################################################################
# HKL Combined Scan
###################################################################################################
def hklscan(vector, readables,latency = 0.0, passes = 1, **pars):
"""
HKL Scan:
Args:
vector(list of lists): HKL values to be scanned
readables(list of Readable): Sensors to be sampled on each step.
latency(float, optional): settling time for each step before readout, defaults to 0.0.
passes(int, optional): number of passes
pars(keyworded variable length arguments, optional): scan optional named arguments:
- title(str, optional): plotting window name.
- hidden(bool, optional): if true generates no effects on user interface.
- before_read (function, optional): callback on each step, before sampling. Arguments: positions, scan
- after_read (function, optional): callback on each step, after sampling. Arguments: record, scan.
- before_pass (function, optional): callback before each scan pass execution. Arguments: pass_num, scan.
- after_pass (function, optional): callback after each scan pass execution. Arguments: pass_num, scan.
- Aditional arguments defined by set_exec_pars.
Returns:
ScanResult object.
"""
readables=to_list(string_to_obj(readables))
pars["initial_move"] = False
scan = ManualScan([h,k,l], readables ,vector[0], vector[-1], [len(vector)-1] * 3, dimensions = 1)
if not "domain_axis" in pars.keys():
pars["domain_axis"] = "Index"
processScanPars(scan, pars)
scan.start()
try:
for pos in vector:
#print "Writing ", pos
hkl_group.write(pos)
time.sleep(0.1) #Make sure is busy
get_motor_group().update()
get_motor_group().waitReady(-1)
time.sleep(latency)
hkl_group.update()
scan.append ([h.take(), k.take(), l.take()], [h.getPosition(), k.getPosition(), l.getPosition()], [readable.read() for readable in readables ])
finally:
scan.end()
return scan.result
def test_diffcalc():
print "Start test"
en.move(20.0)
delta.config.maxSpeed = 50.0
delta.speed = 50.0
delta.move(1.0)
#Setup
setup_diff(sixc, en)
setup_axis('gam', 0, 179)
setup_axis('delta', 0, 179)
setup_axis('delta', min=0)
setup_axis('phi', cut=-180.0)
print_axis_setup()
#Orientation
help(ub.ub)
ub.listub()
# Create a new ub calculation and set lattice parameters
ub.newub('test')
ub.setlat('cubic', 1, 1, 1, 90, 90, 90)
# Add 1st reflection (demonstrating the hardware adapter)
settings.hardware.wavelength = 1
ub.c2th([1, 0, 0]) # energy from hardware
settings.hardware.position = 0, 60, 0, 30, 0, 0
ub.addref([1, 0, 0])# energy and position from hardware
# Add 2nd reflection (this time without the harware adapter)
ub.c2th([0, 1, 0], 12.39842)
ub.addref([0, 1, 0], [0, 60, 0, 30, 0, 90], 12.39842)
# check the state
ub.ub()
ub.checkub()
#Constraints
help(hkl.con)
hkl.con('qaz', 90)
hkl.con('a_eq_b')
hkl.con('mu', 0)
hkl.con()
#Motion
print angles_to_hkl((0., 60., 0., 30., 0., 0.))
print hkl_to_angles(1, 0, 0)
sixc.write([0, 60, 0, 30, 90, 0])
print "sixc=" , sixc.position
wavelength.write(1.0)
print "wavelength = ", wavelength.read()
ub.lastub()
ub.setu ([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
ub.showref()
ub.swapref(1,2)
#print you.hkl
#pos(get_hkl())
hkl_group.read()
#you.hkl.simulateMoveTo([0,1,1])
#sim(get_hkl(), [0,1,1])
hkl_group.sim([0.0,1.0,1.0])
#pos(get_hkl(), [0,1,1])
hkl_group.write([0.0,1.0,1.0])
#Scans
lscan(l, [sin], 1.0, 1.5, 0.1)
ascan([k,l], [sin], [1.0, 1.0], [1.2, 1.3], [0.1, 0.1], zigzag=True, parallel_positioning = False)
vector = [[1.0,1.0,1.0], [1.0,1.0,1.1], [1.0,1.0,1.2], [1.0,1.0,1.4]]
hklscan(vector, [sin, arr], 0.9)
#
#run("diffutils")
###################################################################################################\
#Setup
###################################################################################################
#alpha, delta, gamma, omegaV
setup_diff(fourcv, energy, ("mu", "delta", "gam", "eta"))
print_axis_setup()
setup_axis(mu, mu.getMinValue(), mu.getMaxValue())
setup_axis(delta, delta.getMinValue(), 90) #delta.getMaxValue())
setup_axis(gamma, 0, gamma.getMaxValue())
setup_axis(eta, eta.getMinValue(), eta.getMaxValue())
wavelength.write(1.0)
###################################################################################################\
#Orientation
###################################################################################################
help(ub.ub)
ub.listub()
#alpha delta gamma omegaV
# Create a new ub calculation and set lattice parameters
ub.newub('test')
"""
ub.setlat('cubic', 5.114, 5.8361, 11.058, 90, 90, 90)
en = 8
#ub.c2th([0, 0, 4], en)
#ub.addref([0, 0, 4]) #From current position and ekergy
ub.addref([0, 0, 4], [16.2785, 0.0, 32.5568, 0.0], en)
#ub.c2th([2, 0, 12], en)
ub.addref([2, 0, 12], [71.8285, 37.3082, 138.7440, 0.0], en)
#ub.c2th([1, -4, 10], en)
ub.addref([1, -4, 10], [27.7185, 17.6409 , 128.4220, 0.0], en)
"""
ub.setlat('cubic', 1.0, 1.0, 1.0, 90, 90, 90)
en = 12.4
#ub.c2th([0, 0, 4], en)
#ub.addref([0, 0, 4]) #From current position and ekergy
ub.addref([0, 0, 1], [30.0, 0.0, 60.0, 0.0], en)
#ub.c2th([2, 0, 12], en)
ub.addref([1, 0, 1], [20.0, 45.5564,90.000, 44.4437], en)
#ub.c2th([1, -4, 10], en)
ub.addref([0, 1, 1], [20.0, 45.5564,90.000, 134.4437], en)
ub.ub()
#ub.setub([[1.22862,0.00000,0.00000], [-0.00000,1.07663,0.00000], [-0.00000,-0.00000,0.56820]])
# check the state
ub.checkub()
###################################################################################################\
#Constraints
###################################################################################################
help(hkl.con)
hkl.con('a_eq_b')
#hkl.con('eta:0')
#hkl.con( 'eta', 0) #OmegaV constant
#hkl.con( 'mu', 20) #Alpha constant
###################################################################################################\
#Motion
###################################################################################################
#print angles_to_hkl((16.278, 0.0000, 32.5568, 0.0))
#print angles_to_hkl((44.3400, 0.0000, 123.7322 , 0.0))
#print hkl_to_angles(2, -2, 10)

154
script/test/TestNilson.py Normal file
View File

@@ -0,0 +1,154 @@
# Greateyes scan
#******** SCAN Settings ********
Note="DESY - "
Exp_Time= 1
X0=4200
Xstep=450
XNum_points=3
Y0=5960
Ystep=-40
YNum_points=10
GE_ROI_Line = 3
GE_AreaDet = det
GE_ROI_Image= det.getDataMatrix()
GE_Raw_Image= det.getDataMatrix()
GE_BG_Image = det.getDataMatrix()
GE_Spectrum_Conv = det.getDataArray()
GE_Spectrum = det.getDataArray()
GE_BG_Line = det.getArraySize2()
GE_BG_SizeX = det.getArraySize0()
GE_BG_SizeY = det.getArraySize1()
GE_ROI_Line = det.getArraySize2()
GE_ROI_SizeX = det.getArraySize0()
GE_ROI_SizeY = det.getArraySize1()
IZero_Profile = det.getDataArray()
TFY_Profile = det.getDataArray()
IZero=sin
TFY = sin
GE_Sensor_Temp = sin
GE_FrameID = sin
Press_Diag_PV= sin
Press_Spec_PV= sin
Press_Spec_HV =sin
Press_Sample_Ch=sin
Press_Diag_HV = sin
GE_Spectrum_Sum = det.getDataArray()
#******** Functions Definitions ********
def Save_Pre_Scan_Data():
save_dataset("RAW/GE_BG_Image", GE_BG_Image.read())
save_dataset("Processed/GE_Spectrum_Convertion", GE_Spectrum_Conv.read())
save_dataset("Detector/GE_ROI_Line", GE_ROI_Line.read())
save_dataset("Detector/GE_ROI_SizeX", GE_ROI_SizeX.read())
save_dataset("Detector/GE_ROI_SizeY", GE_ROI_SizeY.read())
save_dataset("Detector/Exposure_Time", GE_AreaDet.getExposure())
save_dataset("Detector/GE_Open_Delay", 1)
save_dataset("Detector/GE_Close_Delay", 1)
save_dataset("Detector/GE_Num_Images", GE_AreaDet.getNumImages())
save_dataset("Detector/Gain_Type", 1)
save_dataset("Scan/Scan_Start_Time", time.ctime())
save_dataset("Scan/Note", Note)
#save_dataset("Scan/Note", Note)
def Create_Scan_Dataset():
create_dataset("RAW/GE_Raw_Image", 'd', False, (Num_Images, int(GE_BG_SizeY.take()), int(GE_BG_SizeX.take())))
create_dataset("RAW/IZero_Profile", 'd', False, (Num_Images, 100))
create_dataset("RAW/TFY_Profile", 'd', False, (Num_Images, 100))
create_dataset("Processed/GE_ROI_Image", 'd', False, (Num_Images, int(GE_ROI_SizeY.take()), int(GE_ROI_SizeX.take())))
create_dataset("Processed/GE_Spectrum", 'd', False, (Num_Images, int(GE_BG_SizeX.take())))
create_dataset("Processed/Izero", 'd', False)
create_dataset("Processed/TFY", 'd', False)
create_dataset("Detector/GE_Sensor_Temp", 'd', False)
create_dataset("Scan/GE_FrameID", 'i', False)
create_dataset("Scan/Timestamps", 'l', False)
create_dataset("Pressure/Diagnostic_PV", 'd', False)
create_dataset("Pressure/Diagnostic_HV", 'd', False)
create_dataset("Pressure/Spectrometer_PV", 'd', False)
create_dataset("Pressure/Spectrometer_HV", 'd', False)
create_dataset("Pressure/Sample_Chamber", 'd', False)
create_dataset("RAW/Xposition", 'd', False)
create_dataset("RAW/Yposition", 'd', False)
def Save_Scan_Data():
#sleep(0.2)
append_dataset("RAW/GE_Raw_Image", GE_Raw_Image.read())
append_dataset("RAW/IZero_Profile", IZero_Profile.take())
append_dataset("RAW/TFY_Profile", TFY_Profile.take())
append_dataset("Processed/GE_ROI_Image", GE_ROI_Image.read())
append_dataset("Processed/GE_Spectrum", GE_Spectrum.take())
append_dataset("Processed/Izero", IZero.take())
append_dataset("Processed/TFY", TFY.take())
append_dataset("Detector/GE_Sensor_Temp", GE_Sensor_Temp.take())
append_dataset("Scan/GE_FrameID", GE_FrameID.take())
append_dataset("Scan/Timestamps", GE_FrameID.getTimestampNanos())
append_dataset("Pressure/Diagnostic_PV", Press_Diag_PV.take())
append_dataset("Pressure/Diagnostic_HV", Press_Diag_HV.take())
append_dataset("Pressure/Spectrometer_PV", Press_Spec_PV.take())
append_dataset("Pressure/Spectrometer_HV", Press_Spec_HV.take())
append_dataset("Pressure/Sample_Chamber", Press_Sample_Ch.take())
#Scan_Progress = (100*calcprog(GE_FrameID.take(),GE_start_frame,Num_Images))
def Save_Pos_Scan_Data():
sleep(1)
save_dataset("Processed/GE_Spectrum_Sum", GE_Spectrum_Sum.read())
save_dataset("Scan/Scan_Finish_Time", time.ctime())
#******** Test limits on sample vertical and horizontal motor ********
X0=float(X0)
Xstep=float(Xstep)
Y0=float(Y0)
Ystep=float(Ystep)
X1=X0+(XNum_points*Xstep)
Y1=Y0+(YNum_points*Ystep)
Num_Images= XNum_points*YNum_points
#******** Setting up Caenels ********
values_p_reading=1000*Exp_Time
Scan_Progress = 1
############### Scan ###############
#******** Scan Script Begins here ********
# Set Nr of images to NofImages
#******** Saving Pre Scan data ********
Save_Pre_Scan_Data()
#******** Pre Scan Setup ********
print("Scan starting: " + time.ctime())
GE_start_frame =1
Create_Scan_Dataset()
#Sample_Horiz.move(X0)
#******** Main Scan Function ********
for j in range(XNum_points):
#Sample_Horiz.move(X0+(j*Xstep))
for i in range(YNum_points):
#Sample_Vert.move(Y0+(i*Ystep))
print GE_start_frame , " / ", (XNum_points*YNum_points)
time.sleep(0.001)
Save_Scan_Data()
GE_start_frame = GE_start_frame+1
#Save_Scan_Data()
#Save_Scan_Data()
#******** Saving Pos Scan data ********
Save_Pos_Scan_Data()
#******** Post Scan ********
print("Scan Finished: " + time.ctime())

172
script/test/TestNilson2.py Normal file
View File

@@ -0,0 +1,172 @@
#features = {"compression" : "true", "shuffle": "false", "chunk":[1, 100, 200]}
features = {"compression" : True, "shuffle": False}
#features =None
FIXED = False
# Greateyes scan
#******** SCAN Settings ********
Note="DESY - "
Exp_Time= 1
X0=4200
Xstep=450
XNum_points=10
Y0=5960
Ystep=-40
YNum_points=10
GE_ROI_Line = 3
GE_AreaDet = det
GE_ROI_Image= det.getDataMatrix()
GE_Raw_Image= det.getDataMatrix()
GE_BG_Image = det.getDataMatrix()
GE_Spectrum_Conv = arr #det.getDataArray()
GE_Spectrum = arr #det.getDataArray()
GE_BG_Line = det.getArraySize2()
GE_BG_SizeX = det.getArraySize0()
GE_BG_SizeY = det.getArraySize1()
GE_ROI_Line = det.getArraySize2()
GE_ROI_SizeX = det.getArraySize0()
GE_ROI_SizeY = det.getArraySize1()
IZero_Profile = arr #det.getDataArray()
TFY_Profile = arr #det.getDataArray()
IZero=sin
TFY = sin
GE_Sensor_Temp = sin
GE_FrameID = sin
Press_Diag_PV= sin
Press_Spec_PV= sin
Press_Spec_HV =sin
Press_Sample_Ch=sin
Press_Diag_HV = sin
GE_Spectrum_Sum = det.getDataArray()
Sample_Horiz=motor
Sample_Vert=motor2
#******** Functions Definitions ********
def Save_Pre_Scan_Data():
save_dataset("RAW/GE_BG_Image", GE_BG_Image.read())
save_dataset("Processed/GE_Spectrum_Convertion", GE_Spectrum_Conv.read())
save_dataset("Detector/GE_ROI_Line", GE_ROI_Line.read())
save_dataset("Detector/GE_ROI_SizeX", GE_ROI_SizeX.read())
save_dataset("Detector/GE_ROI_SizeY", GE_ROI_SizeY.read())
save_dataset("Detector/Exposure_Time", GE_AreaDet.getExposure())
save_dataset("Detector/GE_Open_Delay", 1)
save_dataset("Detector/GE_Close_Delay", 1)
save_dataset("Detector/GE_Num_Images", GE_AreaDet.getNumImages())
save_dataset("Detector/Gain_Type", 1)
save_dataset("Scan/Scan_Start_Time", time.ctime())
save_dataset("Scan/Note", Note)
#save_dataset("Scan/Note", Note)
def Create_Scan_Dataset():
create_dataset("RAW/GE_Raw_Image", 'd', False, (Num_Images if FIXED else 0, int(GE_BG_SizeY.take()), int(GE_BG_SizeX.take())), features)
create_dataset("RAW/IZero_Profile", 'd', False, (Num_Images if FIXED else 0, 100))
create_dataset("RAW/TFY_Profile", 'd', False, (Num_Images if FIXED else 0, 100))
#create_dataset("Processed/GE_ROI_Image", 'd', False, (Num_Images if FIXED else 0Images, int(GE_ROI_SizeY.take()), int(GE_ROI_SizeX.take())))
create_dataset("Processed/GE_Spectrum", 'd', False, (Num_Images if FIXED else 0, int(GE_BG_SizeX.take())))
create_dataset("Processed/Izero", 'd', False)
create_dataset("Processed/TFY", 'd', False)
create_dataset("Detector/GE_Sensor_Temp", 'd', False)
create_dataset("Scan/GE_FrameID", 'i', False)
create_dataset("Scan/Timestamps", 'l', False)
create_dataset("Pressure/Diagnostic_PV", 'd', False)
create_dataset("Pressure/Diagnostic_HV", 'd', False)
create_dataset("Pressure/Spectrometer_PV", 'd', False)
create_dataset("Pressure/Spectrometer_HV", 'd', False)
create_dataset("Pressure/Sample_Chamber", 'd', False)
create_dataset("RAW/Xposition", 'd', False)
create_dataset("RAW/Yposition", 'd', False)
def Save_Scan_Data():
#sleep(0.2)
append_dataset("RAW/GE_Raw_Image", GE_Raw_Image.read())
append_dataset("RAW/IZero_Profile", IZero_Profile.take())
append_dataset("RAW/TFY_Profile", TFY_Profile.take())
#append_dataset("Processed/GE_ROI_Image", GE_ROI_Image.read())
append_dataset("Processed/GE_Spectrum", GE_Spectrum.take())
append_dataset("Processed/Izero", IZero.take())
append_dataset("Processed/TFY", TFY.take())
append_dataset("Detector/GE_Sensor_Temp", GE_Sensor_Temp.take())
append_dataset("Scan/GE_FrameID", GE_FrameID.take())
append_dataset("Scan/Timestamps", GE_FrameID.getTimestampNanos())
append_dataset("Pressure/Diagnostic_PV", Press_Diag_PV.take())
append_dataset("Pressure/Diagnostic_HV", Press_Diag_HV.take())
append_dataset("Pressure/Spectrometer_PV", Press_Spec_PV.take())
append_dataset("Pressure/Spectrometer_HV", Press_Spec_HV.take())
append_dataset("Pressure/Sample_Chamber", Press_Sample_Ch.take())
#Scan_Progress = (100*calcprog(GE_FrameID.take(),GE_start_frame,Num_Images))
def Save_Pos_Scan_Data():
sleep(1)
save_dataset("Processed/GE_Spectrum_Sum", GE_Spectrum_Sum.read())
save_dataset("Scan/Scan_Finish_Time", time.ctime())
#******** Test limits on sample vertical and horizontal motor ********
X0=float(X0)
Xstep=float(Xstep)
Y0=float(Y0)
Ystep=float(Ystep)
X1=X0+(XNum_points*Xstep)
Y1=Y0+(YNum_points*Ystep)
Num_Images= XNum_points*YNum_points
#******** Setting up Caenels ********
values_p_reading=1000*Exp_Time
Scan_Progress = 1
############### Scan ###############
create_dataset("RAW/GE_Raw_Image2", 'd', False, (Num_Images if FIXED else 0, int(GE_BG_SizeY.take()), int(GE_BG_SizeX.take())), features)
Save_Pre_Scan_Data()
#******** Pre Scan Setup ********
print("Scan starting: " + time.ctime())
GE_start_frame =1
Create_Scan_Dataset()
#Sample_Horiz.move(X0)
#******** Main Scan Function ********
#XNum_points, YNum_points 3, 4
X0, Y0, Xstep, Ystep = 0, 0, 0.1, 0.1
for j in range(XNum_points):
#Sample_Horiz.move(X0+(j*Xstep))
for i in range(YNum_points):
#Sample_Vert.move(Y0+(i*Ystep))
print GE_start_frame , " / ", (XNum_points*YNum_points)
time.sleep(0.001)
Save_Scan_Data()
GE_start_frame = GE_start_frame+1
"""
def after(record, scan):
Save_Scan_Data()
ascan((Sample_Horiz, Sample_Vert), (GE_Raw_Image), (X0, Y0), (X1, Y1), (Xstep, Ystep), after_read = after)
"""
#Save_Scan_Data()
#Save_Scan_Data()
#******** Saving Pos Scan data ********
Save_Pos_Scan_Data()
#******** Post Scan ********
print("Scan Finished: " + time.ctime())

View File

@@ -0,0 +1,23 @@
features = None
size = 5
typ = 'd'
features = {"compression" : True, "shuffle": True}
#features = {"layout" : "chunked", "chunk_size":[1, 500, 1000]}
create_dataset("group/contiguous", typ, False, (size, 1000, 1000), features)
create_dataset("group/chunked", typ, False, (0, 1000, 1000), features)
for i in range(size):
data = [ [int(i)] * 1000, ] * 1000
#data = Convert.flatten(to_array(data, typ))
append_dataset("group/chunked", data )
append_dataset("group/contiguous", data)

17
script/test/TestPID.py Normal file
View File

@@ -0,0 +1,17 @@
PID = get_context().getClassByName("PID")
pid=PID(1,1,1);
while True:
sensor = sin.read()
target = 30.0
#set some sort of target value
output=pid.getOutput(sensor,target);
print output
#do something with the output
inp.write(output)
time.sleep(1.0)

View File

@@ -0,0 +1,5 @@
tscan([out, inp, sin, arr], 10, 0.1)
set_exec_pars(plot_layout = "Grid")
tscan([out, inp, sin, arr], 10, 0.1, plot_layout = "Grid")
set_exec_pars(defaults=True)
tscan([out, inp, sin, arr], 10, 0.1)

2
script/test/TestThen.py Normal file
View File

@@ -0,0 +1,2 @@
lscan(inp, sin, 0, 10, 0.1)
set_exec_pars(then="lscan(inp, sin, 0, 10, 0.2)")

143
script/test/TestTiff.py Normal file
View File

@@ -0,0 +1,143 @@
from ijutils import *
#Image Loading
ip = load_image("/Users/gobbo_a/dev/pshell/config/home/images/img.tiff", title="Image")
#Basic image manipulation: creation, copying, padding, saving
resized = resize(ip, 300,300)
save_image(resized, get_context().setup.expandPath("{images}/resized.tiff") ,"tiff")
crop=sub_image(ip,10,20,50,30)
bin_im = binning(ip,2)
new_im = new_image(256, 256, "color")
copy_image_to(bin_im, new_im, 20, 20)
pad_im = pad_image(ip, 1, 2, 3, 4, Color.RED)
stack=create_stack([ip,resized,crop, bin_im, new_im, pad_im], title = "Basic Functions")
save_image(stack, get_context().setup.expandPath("{images}/stack.tiff") ,"tiff")
stack.show()
#Decomposing color channels
create_stack([ get_channel(ip, "red"),
get_channel(ip, "green"),
get_channel(ip, "blue"),
get_channel(ip, "alpha"),
grayscale(get_channel(ip, "brightness"), False)], title = "Color Decomposition").show()
#Basic functions (in_place)
aux = ip.duplicate()
aux.show()
grayscale(aux)
gaussian_blur(aux); aux.repaintWindow()
invert(aux); aux.repaintWindow()
smooth(aux); aux.repaintWindow()
sharpen(aux); aux.repaintWindow()
noise(aux, 100); aux.repaintWindow()
#Changing LUT
aux = ip.duplicate()
aux = grayscale(aux, in_place=False)
r,g,b = [],[],[]
for i in range(256):
r.append(0)
g.append(0)
b.append(i)
set_lut(aux, r, g, b)
aux.show()
#Histogram
plot(get_histogram(ip))
aux = grayscale(ip, in_place = False)
bin = ip.duplicate()
ip_bin = auto_threshold(aux, in_place=False)
create_stack([ ip_bin,
binary_fill_holes(ip_bin, in_place=False),
binary_outline(ip_bin, in_place=False),
binary_outline(binary_fill_holes(ip_bin, in_place=False)),
binary_dilate(ip_bin, in_place=False),
binary_erode(ip_bin, in_place=False),
binary_open(ip_bin, in_place=False),
binary_close(ip_bin, in_place=False),
binary_skeletonize(ip_bin, in_place=False)], title = "Binarization").show()
#EDM, const & image operations
aux = grayscale(ip, in_place = False)
ip_bin = auto_threshold(aux, in_place=False)
binary_fill_holes(ip_bin)
edm = edm(ip_bin, in_place=False)
ws = watershed(ip_bin, in_place=False)
up = ultimate_points(ip_bin, in_place=False)
vr = veronoi(ip_bin, in_place=False)
edm_disp = remap(edm, in_place=False)
ws_disp = grayscale(ws, False)
up_disp = enhance_contrast(up, in_place=False)
vr_disp = enhance_contrast(vr, in_place=False)
create_stack([edm_disp, aux, ip_bin, ws_disp, up_disp, vr_disp], title = "EDM Operations").show()
final = grayscale(ip_bin, in_place = False)
op_const(final,"add", -200)
op_image(final, vr_disp, 'or')
op_image(final, up_disp, 'or')
final.show()
aux = grayscale(ip, in_place = False)
create_stack([ aux,
subtract_background(aux, in_place=False),
smooth(aux, False),
sharpen(aux, False),
edges(aux, False),
bandpass_filter(aux,0, 5, in_place=False),
bandpass_filter(aux,5, 100, in_place=False),
op_const(aux,"and", 127, False),
convolve(aux, KERNEL_BLUR, False),
convolve(aux, KERNEL_SHARPEN, False),
convolve(aux, KERNEL_SHARPEN_2, False),
convolve(aux, KERNEL_LIGHT, False),
convolve(aux, KERNEL_DARK, False),
convolve(aux, KERNEL_EDGE_DETECT, False),
convolve(aux, KERNEL_EDGE_DETECT_2, False),
convolve(aux, KERNEL_DIFFERENTIAL_EDGE_DETECT, False),
convolve(aux, KERNEL_PREWITT, False),
convolve(aux, KERNEL_SOBEL, False)
], title = "General Operations").show()
#Rank operators
rank_opers = []
for op in "mean", "min", "max", "variance", "median", "close_maxima", "open_maxima", "remove_outliers", "remove_nan", "despeckle":
rank_opers.append(op_rank(aux,op, in_place=False, kernel_radius=1))
create_stack(rank_opers, title = "Rank Operations").show()
#Reslicing
#orig = load_image("{data}/img/img2.png")
orig = resize(ip, 300,200)
grayscale(orig)
images=[]
for i in range (20):
images.append(orig.duplicate())
op_const(orig, "multiply", 0.9)
stack=create_stack(images, title = "Original Stack")
#stack.show()
r1 = reslice(stack, start_at="Left", title="Reslice Horizontally")
r2 = reslice(stack, start_at="Top", title="Reslice Vertically")
r1.show()
r2.show()
#Particle Analysis
aux = grayscale(ip, in_place = False)
auto_threshold(aux)
#binary_fill_holes(aux)
#aux.show()
(results,output_img)=analyse_particles(aux, 100,1000, print_table=True)
output_img.show()

31
script/test/TestTypes.py Normal file
View File

@@ -0,0 +1,31 @@
class StringDev(ReadonlyRegisterBase, Readable.StringType):
def doRead(self):
time.sleep(0.001)
return str(time.time())
class BoolDevS(ReadonlyRegisterBase):
def doRead(self):
return (int(time.time()) %2) == 0
class BoolDev(ReadonlyRegisterBase, Readable.BooleanType):
def doRead(self):
return (int(time.time()) %2) == 0
class ImageDev(ReadonlyRegisterBase, ReadonlyRegisterMatrix, Readable.IntegerType):
def doRead(self):
return mt1.read()
def getWidth(self):
return mt1.width
def getHeight(self):
return mt1.height
add_device(StringDev(), True)
add_device(BoolDev(), True)
add_device(BoolDevS(), True)
add_device(ImageDev(), True)
tscan((StringDev, BoolDev, BoolDevS, sin, arr, arr1, mt, mt1, cm1, ImageDev), 10, 0.1, compression =ImageDev)

View File

@@ -0,0 +1,55 @@
def set_energy(v):
motor.move(v)
energy_setpoint = motor
energy = motor.getReadback()
set_device_alias(energy, "energy")
START, STOP, STEP = 0, 40, 2
ENERGIES = [0.0, 0.5, 0.25]
sensors = (sin,out, energy)
#def before_pass(pass_num):
# set_energy(ENERGIES[pass_num-1])
#ret= lscan(inp, sensors, START, STOP, STEP, 0.2, passes = len(ENERGIES), before_pass = before_pass, latency = 0.5)
#positions = frange(START, STOP, STEP , True)
#vector = [[pos, en] for en in ENERGIES for pos in positions]
#ret = vscan((inp,energy_setpoint), sensors, vector, line = True, latency = 0.5)
"""
plots = plot([None]*len(sensors), name = [d.name for d in sensors])
for p in plots: p.clear()
def AfterReadout(record, scan):
if record.setpoints[1] == scan.getStart()[1]:
for p in plots: p.addSeries(LinePlotSeries(str(record.positions[0])))
for i in range(len(plots)):
plots[i].getSeries(plots[i].numberOfSeries-1).appendData(record.positions[1], record.values[i])
class EnergyIndex("Writable):
def write(self, value):
if not hasattr(self, 'setpoint') or self.setpoint != value:
self.setpoint = value
set_energy(ENERGIES[int(value)])
positions = frange(START, STOP, STEP , True)
ret = ascan([EnergyIndex(), inp], sensors, (0,START), (len(ENERGIES)-1,STOP), (1.0,STEP), latency = 0.1, after_read=AfterReadout, plot_disabled=True)
"""
plots = plot([None]*len(sensors), name = [d.name for d in sensors])
for p in plots:
p.clear()
p.legendVisible = True
def after_readout(record, scan):
for i in range(len(plots)):
plots[i].getSeries(plots[i].numberOfSeries-1).appendData(record.positions[0], record.values[i])
def before_pass(pass_num):
en = ENERGIES[pass_num-1]
set_energy(en)
for p in plots: p.addSeries(LinePlotSeries(str(en)))
ret= lscan(inp, sensors, START, STOP, STEP, latency = 0.2, passes = len(ENERGIES), before_pass = before_pass, after_read=after_readout, plot_disabled=True)