This commit is contained in:
14
script/tutorial/10_LineScan.js
Executable file
14
script/tutorial/10_LineScan.js
Executable file
@@ -0,0 +1,14 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Demonstrate the use of Line Scan: one or multiple positioners move together linearly.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//Execute the scan: 100 steps, a1 from 0 to 40
|
||||
r1 = lscan(ao1, [ai1,ai2,wf1], 0, 40, 100, 0.01)
|
||||
|
||||
//Steps of size 1.0, a1 from 0 to 40
|
||||
r2 = lscan(ao1, [ai1,ai2,wf1], 0, 40, 1.0, 0.01)
|
||||
|
||||
//2 positioners moving together in 10 steps. Also sampling an image:
|
||||
r3 = lscan([ao1,ao2], [ai1,ai2,wf1,im1], [0, 0], [40, 100], 4, 0.01)
|
||||
|
||||
8
script/tutorial/11_TimeScan.js
Executable file
8
script/tutorial/11_TimeScan.js
Executable file
@@ -0,0 +1,8 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Demonstrate the use of Time Scan: time-based sensor sampling
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//Execute the scan: 100 samples, 10ms sampling interval
|
||||
r1 = tscan((ai1,ai2,wf1), 100, 0.01)
|
||||
|
||||
10
script/tutorial/12_AreaScan.js
Executable file
10
script/tutorial/12_AreaScan.js
Executable file
@@ -0,0 +1,10 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Area Scan: Multiple positioners, each one is one dimension.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//The second sensor is an array. In the plot window it is overwritten in every same x position.
|
||||
//The data window never displays 3d data, but the 3d data can be accesses during the scan in the Data tab.
|
||||
r1 = ascan([m1,m2], [ai1,wf1], [0.0,0.0], [2.0,1.0], [10,10])
|
||||
|
||||
|
||||
20
script/tutorial/13_VectorScan.js
Executable file
20
script/tutorial/13_VectorScan.js
Executable file
@@ -0,0 +1,20 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Demonstrate use of Vector Scan: one or multiple positioners set according to a position vector.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//1D vector scan, plot to 1D Vector tab
|
||||
vector = [ 1, 3, 5, 10, 25, 40, 45, 47, 49]
|
||||
r1 = vscan(ao1, [ai1,ai2], vector, false, 0.5, false, undefined, undefined, undefined, undefined, title = "1D Vector")
|
||||
|
||||
|
||||
|
||||
|
||||
//2D vector scan, plot to 2D Vector tab
|
||||
vector = [ [1,1] , [1,2] , [1,3] , [1,4] ,
|
||||
[1.5,2.5] ,
|
||||
[2,1] , [2,2] , [2,3] , [2,4] ,
|
||||
[2.5,2.5] ,
|
||||
[3,1] , [3,2] , [3,3] , [3,4] ]
|
||||
|
||||
r2 = vscan([m1,m2], [ai1,ai2], vector, false, 0.1, false, undefined, undefined, undefined, undefined, title = "2D Vector")
|
||||
11
script/tutorial/14_RegionScan.js
Executable file
11
script/tutorial/14_RegionScan.js
Executable file
@@ -0,0 +1,11 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Demonstrate the use of Region Scan: one positioner move linearly in multiple regions.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
//Execute the scan: 3 regions with different number of steps
|
||||
r1 = rscan(ao1, [ai1,ai2], [[0,5,5], [10,15,20], [20,25,5]] , 0.01)
|
||||
|
||||
//Execute the scan: 3 regions with different step size
|
||||
r2 = rscan(ao1, [ai1,ai2], [[0,5,1.0], [10,15,0.2], [20,25,1.0]] , 0.01)
|
||||
17
script/tutorial/15_ContinuousScan.js
Executable file
17
script/tutorial/15_ContinuousScan.js
Executable file
@@ -0,0 +1,17 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Demonstrate the use of Continuous Scan Scan: a Linear Scan with continuous motor move and
|
||||
// sampling on the fly.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
m1.move(0.0)
|
||||
|
||||
//A single motor at current speed
|
||||
r1 = cscan(m1, (ai1,ai2), -2, 3 , steps=10, undefined, undefined ,true)
|
||||
|
||||
//A single motor in a given time
|
||||
r2 = cscan(m1, (ai1,ai2), -2.0, 3.0, 100 , undefined , 4.0, true)
|
||||
|
||||
//Multiple motors in a given time
|
||||
r3 = cscan((m1, m2), (ai1,ai2), (-2.0, -3), (3.0, 5.0), steps=100, undefined, time = 4.0, relative=true)
|
||||
|
||||
46
script/tutorial/16_HardwareScan.js
Executable file
46
script/tutorial/16_HardwareScan.js
Executable file
@@ -0,0 +1,46 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Use of HardwareScan
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
CrlogicPositioner = Java.type('ch.psi.pshell.crlogic.CrlogicPositioner')
|
||||
CrlogicSensor = Java.type('ch.psi.pshell.crlogic.CrlogicSensor')
|
||||
|
||||
//sc1.stop()
|
||||
//sc1.setOneShot()
|
||||
//sc1.channels[0].setPreset(false)
|
||||
//sc1.channels[0].setPresetValue(0)
|
||||
//sc1.start()
|
||||
|
||||
config = {}
|
||||
config["class"] = "ch.psi.pshell.crlogic.CrlogicScan"
|
||||
config["prefix"] = "MTEST-HW3-CRL"
|
||||
config["ioc"] = "MTEST-VME-HW3.psi.ch"
|
||||
config["integrationTime"] = 0.01
|
||||
config["additionalBacklash"] = 0.0
|
||||
|
||||
pos = new CrlogicPositioner("CrlogicPositioner", "MTEST-HW3:MOT1", null)
|
||||
|
||||
sensors = [
|
||||
new CrlogicSensor("Trigger0", "TRIGGER0"),
|
||||
new CrlogicSensor("Trigger1", "TRIGGER1"),
|
||||
new CrlogicSensor("Scaler0", "SCALER0", true),
|
||||
new CrlogicSensor("Scaler1", "SCALER1", true),
|
||||
new CrlogicSensor("Timestamp", "TIMESTAMP"),
|
||||
]
|
||||
|
||||
|
||||
|
||||
//pos.initialize()
|
||||
//pos.move(0.0)
|
||||
|
||||
try {
|
||||
r1 = hscan(config, pos, sensors,0.0, 10.0, 0.1,1, false)
|
||||
}
|
||||
catch(err) {
|
||||
|
||||
}
|
||||
finally {
|
||||
pos.close()
|
||||
}
|
||||
|
||||
13
script/tutorial/20_Relative.js
Executable file
13
script/tutorial/20_Relative.js
Executable file
@@ -0,0 +1,13 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Demonstrate use of Relative Line Scan.
|
||||
// The arguments start and end are relative to the current position.
|
||||
// After the scan the positioner(s) move back to the initial position.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
print ("Initial position = " + m1.position)
|
||||
|
||||
r1 = lscan(m1, [ai1,ai2,wf1], start = -2, end =2, steps = 20, latency = undefined, relative = true)
|
||||
|
||||
|
||||
print ("Final position = " + m1.position)
|
||||
13
script/tutorial/21_MultipassAndZigzag.js
Executable file
13
script/tutorial/21_MultipassAndZigzag.js
Executable file
@@ -0,0 +1,13 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Multi-pass and zigzag scans
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//Linear with 2 passes
|
||||
a= lscan(m1, [ai1,wf1], -0.2, 0.2, 20, latency = 0.0, relative = true, passes = 4)
|
||||
|
||||
//Linear with 4 passes and zigzag
|
||||
a= lscan(m1, [ai1,wf1], -0.2, 0.2, 20, latency = 0.0, relative = true, passes = 4, zigzag = true)
|
||||
|
||||
//Multi-dimentional zigzag
|
||||
x = ascan ([m1,m2], ai1, [0,0], [1, 1], [0.25,0.25], latency=0.01, relative = undefined, passes = undefined, zigzag=true)
|
||||
23
script/tutorial/22_ScanCallbacks.js
Executable file
23
script/tutorial/22_ScanCallbacks.js
Executable file
@@ -0,0 +1,23 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Demonstrate use of scan callbacks to trigger a detector at falling edge.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
function BeforeReadout(position){
|
||||
ao1.write(1)
|
||||
ao1.write(0)
|
||||
//Example with an epics direct channel access
|
||||
//caput("CHANNEL_NAME", 1)
|
||||
//caput("CHANNEL_NAME", 0)
|
||||
print ("In position: " + position[0] + ", " + position[1])
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function AfterReadout(record, scan){
|
||||
print ("Aquired frame: " + record.index)
|
||||
}
|
||||
|
||||
a= lscan([m1,m2], [ai1, ai2], [0,0], [4,8], steps=20, latency = 0.01, relative = undefined,
|
||||
passes = undefined, zigzag = undefined,before_read=BeforeReadout, after_read=AfterReadout)
|
||||
21
script/tutorial/23_Metadata.js
Executable file
21
script/tutorial/23_Metadata.js
Executable file
@@ -0,0 +1,21 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Demonstrate adding attributs to scan groups and datasets.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//Execute the scan: 200 steps, a1 from 0 to 40
|
||||
a= lscan(ao1, [ai1,ai2], 0, 40, 10, 0.01)
|
||||
|
||||
|
||||
//Setting attributes to the scan group
|
||||
path = get_exec_pars().group
|
||||
set_attribute(path, "AttrString", "Value")
|
||||
set_attribute(path, "AttrInteger", 1)
|
||||
set_attribute(path, "AttrDouble", 2.0)
|
||||
set_attribute(path, "AttrBoolean", true)
|
||||
|
||||
//Setting attributes to the scan datasets
|
||||
set_attribute(path + ao1.name, "AttrInteger", 2)
|
||||
set_attribute(path + ai1.name, "AttrInteger", 3)
|
||||
set_attribute(path + ai2.name, "AttrInteger", 4)
|
||||
|
||||
19
script/tutorial/24_ScanDataManipulation.js
Executable file
19
script/tutorial/24_ScanDataManipulation.js
Executable file
@@ -0,0 +1,19 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Processing and plotting scan data.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ao1.write(0.0)
|
||||
scan1= lscan(ao1, [ai1,ai2,wf1], 0, 40, 40, 0.01, false)
|
||||
scan2= lscan(ao1, [ai1,ai2,wf1], 0, 40, 40, 0.01, false)
|
||||
|
||||
|
||||
result=[]
|
||||
for (var i=0; i<scan1.records.length; i++){
|
||||
result.push(scan1.records[i].values[0]+scan2.records[i].values[0])
|
||||
}
|
||||
|
||||
|
||||
plot(result)
|
||||
print (result
|
||||
)
|
||||
36
script/tutorial/25_PseudoDevices.js
Executable file
36
script/tutorial/25_PseudoDevices.js
Executable file
@@ -0,0 +1,36 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Using pseudo-device to :
|
||||
// - Add calculations to scan data.
|
||||
// - Execute logic during scan
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var Clock = Java.extend(Readable)
|
||||
var clock = new Clock() {
|
||||
read: function (value) {
|
||||
return Date.now()
|
||||
},
|
||||
}
|
||||
set_device_alias(clock, "Clock")
|
||||
|
||||
var PseudoSensor = Java.extend(Readable)
|
||||
var averager = new PseudoSensor() {
|
||||
read: function (value) {
|
||||
arr = wf1.take() //Gets the CACHED waveform
|
||||
arr = to_array(arr) //Converts to a javascript array
|
||||
return arr.reduce(function(a, b) { return a + b; }) / arr.length
|
||||
},
|
||||
}
|
||||
set_device_alias(averager, "Averager")
|
||||
|
||||
var PseudoPositioner = Java.extend(Writable)
|
||||
var positioner = new PseudoPositioner() {
|
||||
write: function (value) {
|
||||
print ("Step = " + value)
|
||||
},
|
||||
}
|
||||
set_device_alias(positioner, "Positioner")
|
||||
|
||||
|
||||
a= lscan([ao1,positioner],[ai2,wf1,averager,clock],[0,0],[40,20],20,0.1)
|
||||
|
||||
|
||||
50
script/tutorial/26_DeviceListener.js
Executable file
50
script/tutorial/26_DeviceListener.js
Executable file
@@ -0,0 +1,50 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Create a device listener to interrupt the scan
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
InterruptedException = Java.type('java.lang.InterruptedException')
|
||||
|
||||
//Create a listener to the sensor, verifying the readback values.
|
||||
|
||||
var ListenerAI = Java.extend(DeviceListener)
|
||||
var listenerAI = new ListenerAI() {
|
||||
onValueChanged: function (device, value, former) {
|
||||
if (value > 1.02) {
|
||||
print ("Value over limit-> aborting")
|
||||
abort()
|
||||
}
|
||||
},
|
||||
}
|
||||
ai1.addListener(listenerAI)
|
||||
|
||||
|
||||
var ListenerAO = Java.extend(DeviceListener)
|
||||
var listenerAO = new ListenerAO() {
|
||||
onStateChanged: function (device, state, former) {
|
||||
|
||||
},
|
||||
onValueChanged: function (device, value, former) {
|
||||
print ("Moved to: " + value)
|
||||
},
|
||||
onValueChanginf: function (device, value, former) {
|
||||
if (value > 20) {
|
||||
throw "Forbidden move to " + value
|
||||
}
|
||||
print( "Moving to: " + value + " ... ")
|
||||
},
|
||||
}
|
||||
|
||||
ao1.addListener(listenerAO)
|
||||
|
||||
|
||||
|
||||
|
||||
try{
|
||||
lscan(ao1, (ai1), 0, 40, 200, 0.01)
|
||||
} catch (ex){
|
||||
print ("Aborted"
|
||||
)
|
||||
}
|
||||
finally{
|
||||
ai1.removeListener(listenerAI)
|
||||
ao1.removeListener(listenerAO)
|
||||
19
script/tutorial/27_ResamplingRecord.js
Executable file
19
script/tutorial/27_ResamplingRecord.js
Executable file
@@ -0,0 +1,19 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Resampling a scan record if a fail condition is met.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
index=0
|
||||
|
||||
function AfterReadout(rec){
|
||||
print (rec.getIndex() + " - " + to_array(rec.values))
|
||||
//Only accept records if ai2 is positive
|
||||
if (ai2.take() < 0){
|
||||
sleep(1.0)
|
||||
print("Invalidating")
|
||||
rec.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
a= lscan(m1, [ai1,ai2], [0,], [0.4,], 20, 0.1, relative = undefined, passes = undefined, zigzag = undefined, before_read = undefined, after_read=AfterReadout)
|
||||
9
script/tutorial/28_Averaging.js
Executable file
9
script/tutorial/28_Averaging.js
Executable file
@@ -0,0 +1,9 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Scan averaging
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
av = create_averager(ai2, 50, 0.05)
|
||||
//set_preference(Preference.PLOT_TYPES, {av.name:'minmax'}) //This is to display min/max instead of sigma.
|
||||
res= lscan(ao1, [av, av.samples], 0, 40, 20, 0.1)
|
||||
|
||||
55
script/tutorial/29_ArrayCalibration.js
Executable file
55
script/tutorial/29_ArrayCalibration.js
Executable file
@@ -0,0 +1,55 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Calibrating array and matrix pseudo-devices
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
var ArrayCalibrated = Java.extend(ReadableArray, ReadableCalibratedArray)
|
||||
var ac1 = new ArrayCalibrated() {
|
||||
read: function () {
|
||||
return wf1.read()
|
||||
},
|
||||
getSize: function (value) {
|
||||
return wf1.size
|
||||
},
|
||||
getCalibration: function (value) {
|
||||
return new ArrayCalibration(5,1000)
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var ac2 = new ArrayCalibrated() {
|
||||
read: function () {
|
||||
return wf1.read()
|
||||
},
|
||||
getSize: function (value) {
|
||||
return wf1.size
|
||||
},
|
||||
getCalibration: function (value) {
|
||||
return new ArrayCalibration(5,1000)
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
var MatrixCalibrated = Java.extend(ReadableMatrix, ReadableCalibratedMatrix)
|
||||
var mc1 = new MatrixCalibrated() {
|
||||
read: function () {
|
||||
return im1.read()
|
||||
},
|
||||
getWidth: function (value) {
|
||||
return im1.width
|
||||
},
|
||||
getHeight: function (value) {
|
||||
return im1.height
|
||||
},
|
||||
getCalibration: function (value) {
|
||||
return new MatrixCalibration(2,4,100,200)
|
||||
},
|
||||
}
|
||||
|
||||
set_device_alias(ac1, "wf1_calib")
|
||||
set_device_alias(ac2, "wf1_calib_1d")
|
||||
set_device_alias(mc1, "im1_calib")
|
||||
|
||||
set_preference(Preference.PLOT_TYPES, {"wf1_calib_1d":1})
|
||||
|
||||
30
script/tutorial/30_ScanPlotSetup.js
Executable file
30
script/tutorial/30_ScanPlotSetup.js
Executable file
@@ -0,0 +1,30 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Demonstrate configuring scan plot options
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//This optional preference limits the displayed plots
|
||||
set_preference(Preference.ENABLED_PLOTS, [ai1, wf1])
|
||||
|
||||
//This optional preference displays wf1 as a 1d plot at each scan point, instead of a matrix plot
|
||||
set_preference(Preference.PLOT_TYPES, {wf1:1})
|
||||
|
||||
|
||||
//This optional preference disables printing the scan table
|
||||
//set_preference(Preference.PLOT_DISABLED, true)
|
||||
|
||||
//This optional preference disable all scan plotting
|
||||
//set_preference( Preference.TABLE_DISABLED, true)
|
||||
|
||||
//Execute the scan: 200 steps, a1 from 0 to 40
|
||||
a= lscan(ao1, [ai1,ai2,wf1], 0, 40, 100, 0.01)
|
||||
|
||||
|
||||
|
||||
|
||||
//This optional preference displays wf1 as a 1d plot at each scan point, instead of a matrix plot
|
||||
set_preference(Preference.PLOT_TYPES, {wf1:1})
|
||||
|
||||
ascan([m1,m2], [ai1,wf1], [0.0,0.0], [2.0,1.0], [4,4])
|
||||
|
||||
|
||||
24
script/tutorial/31_UsersPlots.js
Executable file
24
script/tutorial/31_UsersPlots.js
Executable file
@@ -0,0 +1,24 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Direct creation of plots
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
data_1d = [10.0, 20.0, 30.0, 40.0, 50.0]
|
||||
data_2d = [ data_1d, data_1d, data_1d, data_1d, data_1d]
|
||||
data_3d = [ data_2d, data_2d , data_2d, data_2d, data_2d]
|
||||
data_x = [1.0, 2.0, 3.0, 4.0, 5.0]
|
||||
data_y = [2.0, 4.0, 6.0, 8.0, 10.0]
|
||||
|
||||
//1d-plot with optional xdata
|
||||
plot(data_1d, name = undefined, xdata = data_x, ydata = undefined, title = "1d")
|
||||
|
||||
//2d-plot with optional xdata and ydata
|
||||
plot(data_2d, name = undefined, xdata = data_x, ydata = data_y, title = "2d")
|
||||
|
||||
//3d-plot
|
||||
plot(data_3d, name = undefined, xdata = undefined, ydata = undefined, title = "3d")
|
||||
|
||||
//3 plots in the save panel
|
||||
plot([data_1d, data_2d, data_3d], ["1d", "2d", "3d"])
|
||||
|
||||
|
||||
|
||||
29
script/tutorial/32_MultipleSeries.js
Executable file
29
script/tutorial/32_MultipleSeries.js
Executable file
@@ -0,0 +1,29 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Advanced plotting examples
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//2 series in the same plot
|
||||
var xdata = [10,20,30,40,50,60]
|
||||
var p = plot(null, name="Data 1")[0]
|
||||
p.addSeries(new LinePlotSeries("Data2"))
|
||||
p.getSeries(0).setData(xdata, [1,2,3,4,5,6])
|
||||
p.getSeries(1).setData(xdata, [6,5,4,3,2,1])
|
||||
p.addMarker(35.0, null, "This is the answer", Color.BLACK)
|
||||
|
||||
|
||||
//2 series in the same plot, setting range & appending point by point
|
||||
var p = plot(null,name="Data 1", title = "Plot 2")[0]
|
||||
p.getAxis(AxisId.X).setRange(0.0,80.0)
|
||||
p.getAxis(AxisId.Y).setRange(0.0,7.0)
|
||||
p.addSeries(new LinePlotSeries("Data2"))
|
||||
for (var i = 0; i< xdata.length; i++){
|
||||
p.getSeries(0).appendData(xdata[i], i)
|
||||
p.getSeries(1).appendData(xdata[i], 1.0/(i+1))
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
18
script/tutorial/33_CustomScanPlot.js
Executable file
18
script/tutorial/33_CustomScanPlot.js
Executable file
@@ -0,0 +1,18 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Custom plot: Example of creating a 1D plot for a 2D scan where each scanned row is a series
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//Setting the 1d preference would create in the place of the matrix plot, a 1d plot where
|
||||
//each scanned column is a series
|
||||
//setup_plotting(line_plots = (ai1,))
|
||||
|
||||
p = plot(null, name=undefined, xdata=undefined, ydata=undefined, title="1D Plot")[0]
|
||||
function AfterReadout(record, scan){
|
||||
if (record.setpoints[1] == scan.getStart()[1]){
|
||||
p.addSeries(new LinePlotSeries(record.positions[0].toString()))
|
||||
}
|
||||
p.getSeries(p.numberOfSeries-1).appendData(record.positions[1], record.values[0])
|
||||
}
|
||||
|
||||
ascan([ao1,ao2], [ai1], [0,10], [20,30], [20,20], 0.1, relative = undefined, passes = undefined, zigzag = undefined, before_read = undefined, after_read=AfterReadout)
|
||||
57
script/tutorial/34_ErrorPlot.js
Executable file
57
script/tutorial/34_ErrorPlot.js
Executable file
@@ -0,0 +1,57 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Example creating error plots
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
plots=plot([null,null,null],["y","x", "xy"])
|
||||
py = plots[0]
|
||||
px = plots[1]
|
||||
pxy = plots[2]
|
||||
|
||||
//Y error plot
|
||||
py.setStyle(LinePlotStyle.ErrorY)
|
||||
py.setLegendVisible(true)
|
||||
|
||||
sy1 = new LinePlotErrorSeries("F1")
|
||||
py.addSeries(sy1)
|
||||
sy1.appendData(1.0, 10.0, 9.0, 11.0)
|
||||
sy1.appendData(10.0, 6.1, 4.34, 7.54)
|
||||
sy1.appendData(17.8, 4.5, 3.1, 5.8)
|
||||
//One can define error instead of min/max (appendData(x, y, error))
|
||||
sy2 = new LinePlotErrorSeries("F2")
|
||||
py.addSeries(sy2)
|
||||
sy2.setLinesVisible(false)
|
||||
sy2.appendData(3.0, 7.0, 2.0);
|
||||
sy2.appendData(13.0, 13.0, 2.0);
|
||||
sy2.appendData(24.0, 16.1, 1.0);
|
||||
|
||||
//X error plot
|
||||
px.setStyle(LinePlotStyle.ErrorX)
|
||||
px.setLegendVisible(true)
|
||||
sx = new LinePlotErrorSeries("F3")
|
||||
px.addSeries(sx)
|
||||
sx.appendData(1.0, 10.0, 0.5, 1.5)
|
||||
sx.appendData(10.0, 6.1, 9.0, 10.3)
|
||||
sx.appendData(17.8, 4.5, 17.0, 18.0)
|
||||
//One can define error instead of min/max (appendData(x, y, error))
|
||||
sx2 = new LinePlotErrorSeries("F4")
|
||||
px.addSeries(sx2)
|
||||
sx2.setLinesVisible(false)
|
||||
sx2.appendData(1.0, 3.0, 1.0)
|
||||
sx2.appendData(10.0, 5.1, 1.0)
|
||||
sx2.appendData(17.8, 7.5, 0.5)
|
||||
|
||||
//XY error plot
|
||||
pxy.setStyle(LinePlotStyle.ErrorXY)
|
||||
pxy.setLegendVisible(true)
|
||||
sxy = new LinePlotErrorSeries("F5")
|
||||
pxy.addSeries(sxy)
|
||||
sxy.appendData(1.0,0.5,1.5, 10.0, 9.0, 11.0)
|
||||
sxy.appendData(10.0,9.0, 11.0, 6.1, 4.34, 7.54)
|
||||
sxy.appendData(17.8, 17.0, 18.0, 4.5, 3.1, 5.8)
|
||||
//One can define error instead of min/max (appendData(x, y, errorX, errorY))
|
||||
sxy2 = new LinePlotErrorSeries("F6")
|
||||
pxy.addSeries(sxy2)
|
||||
sxy2.appendData(3.0, 7.0, 0.5, 4.0);
|
||||
sxy2.appendData(13.0, 13.0, 0.5, 3.0);
|
||||
sxy2.appendData(24.0, 16.1, 0.2, 2.0);
|
||||
12
script/tutorial/35_LinePlotStyles.js
Executable file
12
script/tutorial/35_LinePlotStyles.js
Executable file
@@ -0,0 +1,12 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Example changing plot styles
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
data = [0,3,5,1,3,5,3,4,3,2,1,0]
|
||||
plots = plot([data, data, data], ["normal", "step", "spline"])
|
||||
p1 = plots[0]
|
||||
p2 = plots[1]
|
||||
p3 = plots[2]
|
||||
p2.setStyle(LinePlotStyle.Step)
|
||||
p3.setStyle(LinePlotStyle.Spline)
|
||||
12
script/tutorial/36_LogarithmicScales.js
Executable file
12
script/tutorial/36_LogarithmicScales.js
Executable file
@@ -0,0 +1,12 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Displaying logarithmic scales
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
p = plot([10,500,1000,5000,1000], name = undefined, xdata = [0.1,1,10,100,1000, 10000])[0]
|
||||
p.getAxis(AxisId.X).logarithmic = true
|
||||
p.getAxis(AxisId.Y).setRange(1, 100000)
|
||||
p.getAxis(AxisId.Y).logarithmic = true
|
||||
|
||||
|
||||
|
||||
|
||||
27
script/tutorial/37_SecondaryDomainAxis.js
Executable file
27
script/tutorial/37_SecondaryDomainAxis.js
Executable file
@@ -0,0 +1,27 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Creating a secondary X axis, using the underlying JFreeChart libraey API
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
importClass(org.jfree.chart.axis.NumberAxis)
|
||||
importClass(org.jfree.chart.axis.LogarithmicAxis)
|
||||
|
||||
p = plot([1,2,3,4,5])[0]
|
||||
|
||||
x2 = new NumberAxis("Secondary X Axis") //Linear scale
|
||||
//x2 = new LogarithmicAxis("Secondary X Axis") //Logarithmic scale
|
||||
x2.setRange(0.1, 100)
|
||||
p.getAxis(AxisId.X).setRange(-2, 5) // So the relation between X1 and X2 is enforced
|
||||
|
||||
|
||||
jf = p.chart.plot
|
||||
jf.setDomainAxis(1, x2 )
|
||||
|
||||
//This is just for formatting te new axis fonts and colors, equals to the first axis
|
||||
jf.getDomainAxis(1).labelPaint = jf.getDomainAxis(0).labelPaint
|
||||
jf.getDomainAxis(1).labelFont = jf.getDomainAxis(0).labelFont
|
||||
jf.getDomainAxis(1).tickLabelPaint = jf.getDomainAxis(0).tickLabelPaint
|
||||
jf.getDomainAxis(1).tickLabelFont = jf.getDomainAxis(0).tickLabelFont
|
||||
|
||||
|
||||
|
||||
|
||||
16
script/tutorial/40_SimultaneousScans.js
Executable file
16
script/tutorial/40_SimultaneousScans.js
Executable file
@@ -0,0 +1,16 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Example on running simultaneous scans. They should not manipulate same writables
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
function scan1(){
|
||||
print ("scan1")
|
||||
return lscan(ao1, ai1, 0, 40, 20, 0.1)
|
||||
}
|
||||
|
||||
function scan2(){
|
||||
print ("scan2")
|
||||
return lscan(ao2, wf1, 0, 40, 20, 0.1, undefined, undefined, undefined, undefined, undefined, title = "scan2")
|
||||
}
|
||||
|
||||
parallelize(scan1, scan2)
|
||||
41
script/tutorial/41_ManualScan.js
Executable file
41
script/tutorial/41_ManualScan.js
Executable file
@@ -0,0 +1,41 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Manual scan: Manually setting positioners and reading back sensors, but still using
|
||||
// the standard data handling and plotting of built-in scans.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
var MOTOR_RANGE = [0.0, 8.0]
|
||||
var OUTPUT_SETPOINTS = [1.0, 2.0, 3.0]
|
||||
var FIXED_X = true
|
||||
|
||||
|
||||
writables_names = to_array([m1.getName(), ao1.getName()], 's')
|
||||
readable_names = to_array([ai1.getName(), ai2.getName()], 's')
|
||||
start = to_array( [ FIXED_X ? MOTOR_RANGE[0] : -1, OUTPUT_SETPOINTS[0]] , 'd')
|
||||
stop =to_array([ FIXED_X ? MOTOR_RANGE[1] : -1, OUTPUT_SETPOINTS[OUTPUT_SETPOINTS.length-1]] , 'd')
|
||||
steps = to_array([Math.round(MOTOR_RANGE[1]-MOTOR_RANGE[0]), OUTPUT_SETPOINTS.length-1] , 'i')
|
||||
|
||||
print (to_array(writables_names))
|
||||
print (to_array(readable_names))
|
||||
print (to_array(start))
|
||||
print (to_array(stop))
|
||||
print (to_array(steps))
|
||||
|
||||
scan = new ManualScan(writables_names, readable_names, start, stop, steps, false)
|
||||
|
||||
|
||||
//This option is to plot the foe each output value one 1D series, instead of all in a matrix plot
|
||||
set_preference(Preference.PLOT_TYPES, {"ai1":1, "ai2":1})
|
||||
|
||||
|
||||
scan.start()
|
||||
m1.setSpeed(10.0)
|
||||
for (var setpoint1 = MOTOR_RANGE[0]; setpoint1 <=MOTOR_RANGE[1]; setpoint1+=1.0){
|
||||
m1.move(setpoint1)
|
||||
for (var setpoint2 in OUTPUT_SETPOINTS){
|
||||
ao1.write(setpoint2)
|
||||
scan.append (to_array([setpoint1, setpoint2], 'd'), to_array([m1.read(), ao1.read()], 'd'), to_array([ai1.read(), ai2.read()], 'd'))
|
||||
}
|
||||
}
|
||||
|
||||
scan.end()
|
||||
38
script/tutorial/42_MaximumSearch.js
Executable file
38
script/tutorial/42_MaximumSearch.js
Executable file
@@ -0,0 +1,38 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Using bsearch(Binary Search) and hsearch(Hill Climbing Search) to find optimum
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
var FitnessFunction = Java.extend(ReadonlyRegisterBase)
|
||||
add_device(new FitnessFunction("fitness") {
|
||||
doRead: function () {
|
||||
return 1000.0 - (Math.pow(ao1.take()-18, 2) + Math.pow(ao2.take()-6, 2))
|
||||
},
|
||||
}, true)
|
||||
|
||||
|
||||
|
||||
//Plot Fitness Function
|
||||
r = ascan([ao1, ao2], fitness, [0.0,0.0], [21.0,26.0], [1.0, 1.0], title = "Fitness")
|
||||
|
||||
//Binary Search
|
||||
strategy = "Normal" // or "Boundary" or "FullNeighborhood"
|
||||
r = bsearch([ao1, ao2], fitness, [0.0,0.0], [21.0,26.0], [0.1, 0.1], maximum=true, strategy = strategy, latency = 0.01, relative=false, before_read=undefined, after_read=undefined, title = "Binary Search")
|
||||
//Relative search:
|
||||
//ao1.write(10.5); ao2.write(13.0)
|
||||
//r = bsearch([ao1, ao2], fitness, [-10.5,-13.0], [10.5,13.0], [0.1, 0.1],maximum=true, strategy = strategy, latency = 0.01, relative = true, before_read=undefined, after_read=undefined, title = "Binary Search")
|
||||
|
||||
print ("--------------- Binary Search -----------------")
|
||||
print (r)
|
||||
print (r.print())
|
||||
print (r.getRecords().length)
|
||||
|
||||
|
||||
//Hill Climbing Search
|
||||
ao1.write(10.5)
|
||||
ao2.write(13.0)
|
||||
r = hsearch([ao1, ao2], fitness,[0.0,0.0], [21.0,26.0], [1.0, 1.0], [0.1, 0.1], 1, maximum=true, latency = 0.01, relative=false, before_read=undefined, after_read=undefined, title = "Hill Climbing")
|
||||
print ("--------------- Hill Climbing Search -----------------")
|
||||
print (r)
|
||||
print (r.print())
|
||||
print (r.getRecords().length)
|
||||
37
script/tutorial/43_BeamSynchronousScan.js
Executable file
37
script/tutorial/43_BeamSynchronousScan.js
Executable file
@@ -0,0 +1,37 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Scans with beam synchronous streams
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//Creating a stream, assuming a provided named "dispatcher".
|
||||
st1 = new Stream("st1", dispatcher)
|
||||
|
||||
//Adding channels to that stream
|
||||
s1=st1.addScalar("Int8Scalar", "Int8Scalar", 10, 0)
|
||||
s2=st1.addScalar("Float64Scalar", "Float64Scalar", 10, 0)
|
||||
w1=st1.addWaveform("Int32Waveform", "Int32Waveform", 10, 0)
|
||||
mt1=st1.addMatrix("Int16Waveform", "Int16Waveform", 10, 0, 64, 32)
|
||||
st1.initialize()
|
||||
|
||||
try{
|
||||
//The stream can be used on any conventional scan. The next stream value is sampled.
|
||||
//Readable values belong to same pulse id.
|
||||
tscan (st1.getReadables(), 10 , 0.2)
|
||||
|
||||
//The bscan command performs samples every stream element
|
||||
//Readable values belong to same pulse id.
|
||||
bscan (st1, 10) //Sampling 10 elements
|
||||
|
||||
//An individual stream channel can be used in a conventional scan, but in this case the stream
|
||||
//must be explicitly started, and there is no guarantee the values belong to the same PulseID
|
||||
//(likely they are since as only cached values are taken).
|
||||
st1.start(true)
|
||||
tscan ([s1,s2], 10 , 0.2)
|
||||
|
||||
//If waveform individual stream channel is used, and no size is provided in constructor/config,
|
||||
//then it must be read previously to the scan to update the size value.
|
||||
st1.start(true)
|
||||
w1.update()
|
||||
tscan ([s1,w1,mt1], 10 , 0.2)
|
||||
} finally{
|
||||
st1.close()
|
||||
}
|
||||
86
script/tutorial/50_DataManipulation.js
Executable file
86
script/tutorial/50_DataManipulation.js
Executable file
@@ -0,0 +1,86 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//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(to_array(read)
|
||||
)
|
||||
assert (data1d.toString() == to_array(read).toString() )
|
||||
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(to_array(read)
|
||||
)
|
||||
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(to_array(read))
|
||||
read =load_data(path,1)
|
||||
print(to_array(read))
|
||||
|
||||
//Creating a INT dataset adding elements one by one
|
||||
path = "group/data4"
|
||||
create_dataset(path, 'i')
|
||||
for (var i=0; i<10; i++){
|
||||
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 (var row in data2d){
|
||||
append_dataset(path, data2d[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 (var row in table){
|
||||
append_table(path, table[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")
|
||||
)
|
||||
|
||||
|
||||
54
script/tutorial/51_Parallelization.js
Executable file
54
script/tutorial/51_Parallelization.js
Executable file
@@ -0,0 +1,54 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//// Using Parallelization API to execute tasks concurrently
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//Simple parallization
|
||||
function task1(){
|
||||
m1.moveRel(1.0)
|
||||
return m1.getPosition()
|
||||
}
|
||||
|
||||
function task2(){
|
||||
m2.moveRel(1.0)
|
||||
return m1.getPosition()
|
||||
}
|
||||
|
||||
function task3(){
|
||||
return ai1.read()
|
||||
}
|
||||
|
||||
ret = parallelize(task1, task2, task3)
|
||||
print (ret
|
||||
)
|
||||
|
||||
|
||||
//Fork amd join
|
||||
ret = fork(task1, task2, task3)
|
||||
print (ai1.read()
|
||||
)
|
||||
ret = join(ret)
|
||||
print (ret
|
||||
)
|
||||
|
||||
|
||||
|
||||
//Functions with parameters
|
||||
function moveRelative(motor, step){
|
||||
motor.moveRel(step)
|
||||
return motor.getPosition()
|
||||
}
|
||||
|
||||
ret = parallelize([moveRelative,[m1,-2]], [moveRelative,[m2,-2]])
|
||||
print (ret
|
||||
)
|
||||
|
||||
|
||||
//Exception in parallel task is thrown back to script
|
||||
try{
|
||||
parallelize([moveRelative,[ai1,1]], [moveRelative,[ai2,1]])
|
||||
}catch (ex){
|
||||
print ("Ok, caught exception:"
|
||||
)
|
||||
print(ex)
|
||||
}
|
||||
21
script/tutorial/52_ParametersAndReturn.js
Executable file
21
script/tutorial/52_ParametersAndReturn.js
Executable file
@@ -0,0 +1,21 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Setting script parameters and return value
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//Providing a map of global variables
|
||||
//run ("52_ParametersAndReturn", {"start":10.0, "end":50.0, "step":40})
|
||||
|
||||
|
||||
//Setting sys.argv:
|
||||
//run ("52_ParametersAndReturn", [10.0, 50.0, 2.0])
|
||||
|
||||
//In this case the parameters would be parsed as:
|
||||
//start = argv[0]
|
||||
//end = argv[1]
|
||||
//step = argv[2]
|
||||
|
||||
|
||||
a= lscan(ao1, ai1, start, end, step, 0.1)
|
||||
a.getReadable(0)
|
||||
set_return(a.getReadable(0))
|
||||
68
script/tutorial/53_DirectEpicsAccess.js
Executable file
68
script/tutorial/53_DirectEpicsAccess.js
Executable file
@@ -0,0 +1,68 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// EPICS direct channel access.
|
||||
// EPICS devices implemented are included in PShell, package ch.psi.pshell.epics.
|
||||
// However direct channel access builtin functions are available.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
channel_name = "TESTIOC:TESTCALCOUT:Output"
|
||||
|
||||
//reading/writing to a channel
|
||||
print (caget(channel_name))
|
||||
caput(channel_name, 0.0)
|
||||
//Put with no wait
|
||||
caput(channel_name, 0.0)
|
||||
print (caget(channel_name))
|
||||
|
||||
//waiting for a channel value
|
||||
cawait(channel_name, 0.0, timeout = 10.0)
|
||||
|
||||
//If many IO it is better to keep the same CA connection
|
||||
channel = create_channel(channel_name, 'd')
|
||||
for (var i=0; i<10; i++){
|
||||
print (channel.get()
|
||||
)
|
||||
}
|
||||
channel.close()
|
||||
|
||||
|
||||
//The create_channel_device method return a device implements Readable and Writable and therefore can be used in scans
|
||||
channel = create_channel_device(channel_name, 'd', null, "My Channel")
|
||||
lscan(channel, ai2, 0, 10, 0.1)
|
||||
channel.close()
|
||||
|
||||
|
||||
//Or else we can use a Device
|
||||
ChannelDouble= Java.type('ch.psi.pshell.epics.ChannelDouble')
|
||||
channel = new ChannelDouble("My Channel", channel_name)
|
||||
channel.initialize()
|
||||
lscan(channel, ai2, 0, 10, 0.1)
|
||||
channel.close()
|
||||
|
||||
|
||||
|
||||
//Creating a table reading set of channels for each scan step.
|
||||
attrs_dataset = null
|
||||
attrs_names = ["TESTIOC:TESTCALCOUT:Input",
|
||||
"TESTIOC:TESTCALCOUT:Output",
|
||||
"TESTIOC:TESTSINUS:SinCalc",
|
||||
"TESTIOC:TESTWF2:MyWF"]
|
||||
attrs_types = ["d", "d", "d", "[d"]
|
||||
attrs_lenghts = [0,0,0,10]
|
||||
|
||||
|
||||
function AfterReadout(rec){
|
||||
if (attrs_dataset == null){
|
||||
attrs_dataset = get_exec_pars().group + "attributes"
|
||||
create_table(attrs_dataset, attrs_names, attrs_types, attrs_lenghts)
|
||||
}
|
||||
record = []
|
||||
for (var i=0; i<attrs_names.length; i++){
|
||||
val = caget(attrs_names[i], attrs_types[i])
|
||||
record.push(val)
|
||||
}
|
||||
//print record
|
||||
append_table(attrs_dataset, record)
|
||||
}
|
||||
|
||||
a = lscan(m1, [ai1, ai2], 0, 0.1, 20, 0.01, undefined, undefined, undefined, undefined, after_read=AfterReadout)
|
||||
29
script/tutorial/54_ChannelAccessServer.js
Executable file
29
script/tutorial/54_ChannelAccessServer.js
Executable file
@@ -0,0 +1,29 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Creation of EPICS CA servers over register devices
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CAS = Java.type('ch.psi.pshell.epics.CAS')
|
||||
|
||||
cas = []
|
||||
|
||||
//CAS.setServerPort(5062)
|
||||
|
||||
cas1 = new CAS("TESTCAS:c1", ai1, 'double')
|
||||
cas2 = new CAS("TESTCAS:c2", ai1, 'int')
|
||||
cas3 = new CAS("TESTCAS:c3", ai1, 'string')
|
||||
cas4 = new CAS("TESTCAS:c4", ao1, 'double')
|
||||
cas5 = new CAS("TESTCAS:c5", dp1, 'string')
|
||||
cas6 = new CAS("TESTCAS:c6", wf1, 'double')
|
||||
cas7 = new CAS("TESTCAS:c7", wf1, 'int')
|
||||
cas8 = new CAS("TESTCAS:c8", wf1, 'string')
|
||||
|
||||
print (caget("TESTCAS:c1")
|
||||
)
|
||||
print (caget("TESTCAS:c2")
|
||||
)
|
||||
print (caget("TESTCAS:c3")
|
||||
)
|
||||
print (caget("TESTCAS:c4")
|
||||
)
|
||||
print (caget("TESTCAS:c5")
|
||||
)
|
||||
51
script/tutorial/55_Interlocks.js
Executable file
51
script/tutorial/55_Interlocks.js
Executable file
@@ -0,0 +1,51 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Interlocks: example on creating and installing device interlock rules.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//Motor and Positioners
|
||||
var MyInterlock1 = Java.extend(Interlock)
|
||||
var interlock1 = new MyInterlock1( [m1, p1]) {
|
||||
check: function (pos) {
|
||||
m=pos[0]
|
||||
p=pos[1]
|
||||
if ((p<500) && (m<5) && (m>4)){
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
//Motor group
|
||||
var MyInterlock2 = Java.extend(Interlock)
|
||||
var interlock2 = new MyInterlock2( [mg1, p1]) {
|
||||
check: function (pos) {
|
||||
print(pos)
|
||||
mg=pos[0]
|
||||
p=pos[1]
|
||||
print(to_array(mg))
|
||||
if ((p<500) && (mg[0]<5) && (mg[1]>4)){
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
//Discrete Positioner
|
||||
var MyInterlock3 = Java.extend(Interlock)
|
||||
interlock3 = new MyInterlock3( [dp1, p1]) {
|
||||
check: function (pos) {
|
||||
dp=pos[0]
|
||||
p=pos[1]
|
||||
print ("DP " + dp)
|
||||
print ("P " + p)
|
||||
if ((p<500) && (dp=="Out")){
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
}
|
||||
*/
|
||||
9
script/tutorial/56_ExecutingCPython.js
Executable file
9
script/tutorial/56_ExecutingCPython.js
Executable file
@@ -0,0 +1,9 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Executing CPython in external process.
|
||||
// Requires cpython.py to be put in the scripts folder, or else in the python path.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//Executing a module
|
||||
ret = exec_cpython("cpython", [])
|
||||
print (ret
|
||||
98
script/tutorial/57_EmbeddingCPython.js
Executable file
98
script/tutorial/57_EmbeddingCPython.js
Executable file
@@ -0,0 +1,98 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Embedding CPython with JEP: USe of numpy, pandas and matpplotlib in the same process.
|
||||
// Requires cpython.py to be put in the scripts folder, or else in the python path.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//Requirements to the use of JEP:
|
||||
// 1- PYTHONHOME is set to the python interpreter home folder.
|
||||
// 2- jep*.so is in LD_LIBRARY_PATH (e.g. in extensions folder )
|
||||
// 3- jep*.jar is in the CLASS_PATH (e.g. in extensions folder )
|
||||
//JEP works with python 2 and 3.
|
||||
|
||||
run("jeputils")
|
||||
|
||||
//In order to use matplotlib we must set Tk backend before importing plt
|
||||
eval_jep("import matplotlib")
|
||||
eval_jep("matplotlib.use('TkAgg')")
|
||||
|
||||
|
||||
//Evaluating statements
|
||||
eval_jep("import sys")
|
||||
eval_jep("import numpy as np")
|
||||
eval_jep("a = np.array((100, 100), )")
|
||||
eval_jep("print (a)")
|
||||
|
||||
eval_jep("\
|
||||
def stderr(str): \n\
|
||||
if sys.version_info < (3,0) :\n\
|
||||
exec(\"print >> sys.stderr, '\" + str + \"'\") \n\
|
||||
else: \n\
|
||||
exec(\"print ('\" + str + \"', file=sys.stderr)\") \n\
|
||||
")
|
||||
|
||||
eval_jep("stderr('Testing stderr')")
|
||||
|
||||
|
||||
//Accessing a numpy array
|
||||
a=get_jep("a")
|
||||
print (a.getData()
|
||||
)
|
||||
print (a.getDimensions()
|
||||
)
|
||||
|
||||
|
||||
//Setting numpy array with scan data
|
||||
steps = [3,4]
|
||||
dims = [steps[0]+1 , steps[1]+1 ]
|
||||
r = ascan([m1,m2], [ai1], [0.0,0.0], [0.2,0.2], steps)
|
||||
data = r.getReadable(0)
|
||||
a = new_numpy_array(data, dims,'d')
|
||||
print (to_array(a.getDimensions()))
|
||||
print (to_array(a.getData()))
|
||||
plot( Convert.reshape(a.getData(),a.getDimensions()),null, null, null, "Scan Data")
|
||||
|
||||
|
||||
//Calling a module function
|
||||
b = call_jep("numpy", "transpose", [a,])
|
||||
print (to_array(b.getDimensions()))
|
||||
print (to_array(b.getData()))
|
||||
plot( Convert.reshape(b.getData(),b.getDimensions()),null, null, null, title="Transposed")
|
||||
|
||||
|
||||
|
||||
|
||||
//More calculations calling numpy
|
||||
a = call_jep("numpy", "ones", [[400,200],'d'])
|
||||
for (var i=0; i<100; i++){
|
||||
b = call_jep("numpy", "ones", [[400,200],'d'])
|
||||
a = call_jep("numpy", "add", [a,b])
|
||||
s = call_jep("numpy", "sum", [a,])
|
||||
print (a.getData()[0] + " " + s
|
||||
)
|
||||
sleep(0.001)
|
||||
}
|
||||
|
||||
//Calling a local function
|
||||
data = [1,2,3,4,5,6,7,8,9,0]
|
||||
dims = [2,5]
|
||||
array = new_numpy_array(data, dims,'d') //Auxiliary function to create numpy arrays from lists or java arrays.
|
||||
ret = call_jep("cpython", "calc", [array,])
|
||||
print (ret.getDimensions() + " - " + ret.getData()
|
||||
)
|
||||
|
||||
|
||||
//Testing pandas
|
||||
ret = call_jep("cpython", "test_pandas")
|
||||
|
||||
|
||||
//Testing tkinter
|
||||
ret = call_jep("cpython", "test_tkinter")
|
||||
|
||||
|
||||
//Testing matplotlib
|
||||
ret = call_jep("cpython", "test_matplotlib", [0.1, 4, 0.4])
|
||||
|
||||
|
||||
//Running a modole
|
||||
run_jep("cpython")
|
||||
|
||||
68
script/tutorial/60_Fitting.js
Executable file
68
script/tutorial/60_Fitting.js
Executable file
@@ -0,0 +1,68 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Function fitting and peak search with mathutils.py
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
run("mathutils")
|
||||
|
||||
|
||||
start = 0
|
||||
end = 10
|
||||
step_size = 0.1
|
||||
|
||||
result= lscan(ao1,ai1,start,end,[step_size,],0.01)
|
||||
|
||||
readable = result.getReadable(0)
|
||||
positions = result.getPositions(0)
|
||||
|
||||
function get_function_data(func, start, end, resolution){
|
||||
ret = []
|
||||
for (var x=start; x<=end; x+=resolution){
|
||||
fit_polinomial.push(func.value(x))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pars_polynomial = fit_polynomial(readable, positions, 6)
|
||||
//(a0, a1, a2, a3, a4, a5, a6)
|
||||
fitted_polynomial_function = new PolynomialFunction(pars_polynomial)
|
||||
print (pars_polynomial)
|
||||
|
||||
pars_gaussian = fit_gaussian(readable, positions)
|
||||
normalization = pars_gaussian[0]
|
||||
mean_val = pars_gaussian[1]
|
||||
sigma = pars_gaussian [2]
|
||||
fitted_gaussian_function = new Gaussian(normalization, mean_val, sigma)
|
||||
print (normalization + " " + mean_val + " " + sigma)
|
||||
|
||||
pars_harmonic= fit_harmonic(readable, positions)
|
||||
amplitude = pars_harmonic[0]
|
||||
angular_frequency = pars_harmonic[1]
|
||||
phase = pars_harmonic[2]
|
||||
fitted_harmonic_function = new HarmonicOscillator(amplitude, angular_frequency, phase)
|
||||
print (amplitude+ " " + angular_frequency+ " " + phase)
|
||||
|
||||
|
||||
resolution = step_size/100
|
||||
fit_polinomial = []
|
||||
fit_gaussian = []
|
||||
fit_harmonic = []
|
||||
for (var x=start; x<=end; x+=resolution){
|
||||
fit_polinomial.push(fitted_polynomial_function.value(x))
|
||||
fit_gaussian.push(fitted_gaussian_function.value(x))
|
||||
fit_harmonic.push(fitted_harmonic_function.value(x))
|
||||
}
|
||||
x = range(start, end+resolution, resolution)
|
||||
|
||||
|
||||
peaks = calculate_peaks(fitted_polynomial_function, start, end)
|
||||
|
||||
plots = plot([readable, fit_polinomial, fit_gaussian, fit_harmonic] ,
|
||||
["data", "polinomial", "gaussian", "harmonic"], xdata = [positions,x,x,x], ydata=undefined, title="Data")
|
||||
|
||||
for (var p in peaks){
|
||||
print ("Max: " + p)
|
||||
plots[0].addMarker(p, null, "Max=" + Math.round(p,2), Color.LIGHT_GRAY)
|
||||
}
|
||||
|
||||
plots[0].addMarker(mean_val, null, "Mean=" + Math.round(mean_val,2), Color.LIGHT_GRAY)
|
||||
43
script/tutorial/61_MultipleGaussianFit.js
Executable file
43
script/tutorial/61_MultipleGaussianFit.js
Executable file
@@ -0,0 +1,43 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Multiple Gaussians peak search with mathutils.py
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
run("mathutils")
|
||||
|
||||
start = 0
|
||||
end = 50
|
||||
step_size = 0.2
|
||||
|
||||
result= lscan(ao1,ai1,start,end,[step_size,])
|
||||
|
||||
readable = result.getReadable(0)
|
||||
positions = result.getPositions(0)
|
||||
|
||||
min = Math.min.apply(null, readable)
|
||||
max = Math.max.apply(null, readable)
|
||||
|
||||
threshold = (min + max)/2
|
||||
min_peak_distance = 5.0
|
||||
|
||||
peaks = estimate_peak_indexes(readable, positions, threshold, min_peak_distance)
|
||||
print ("Peak indexes: " + peaks)
|
||||
print ("Peak x: " + peaks.map(function(x) {return positions[x]}))
|
||||
print ("Peak y: " + peaks.map(function(x) {return readable[x]}))
|
||||
|
||||
gaussians = fit_gaussians(readable, positions, peaks)
|
||||
|
||||
plots = plot([readable],["sin"],[positions], undefined, title="Data" )
|
||||
for (var i=0; i< peaks.length; i++){
|
||||
peak = peaks[i]
|
||||
pars_gaussian = gaussians[i]
|
||||
normalization = pars_gaussian[0]
|
||||
mean_val = pars_gaussian[1]
|
||||
sigma = pars_gaussian [2]
|
||||
if (Math.abs(mean_val - positions[peak]) < min_peak_distance){
|
||||
print ("Peak -> " + mean_val)
|
||||
plots[0].addMarker(mean_val, null, "N="+ Math.round(normalization,2), new Color(210,0,0))
|
||||
}else {
|
||||
print ("Invalid gaussian fit: " + mean_val)
|
||||
}
|
||||
}
|
||||
30
script/tutorial/62_FFT.js
Executable file
30
script/tutorial/62_FFT.js
Executable file
@@ -0,0 +1,30 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Demonstrate the use of fft function in mathutils.py
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
run("mathutils")
|
||||
|
||||
|
||||
|
||||
//The signal is composed by 3 sinusoids (100Hz, 200Hz, 400Hz) and a background noise (a sin waveform is A.sin(2.pi.f.t))
|
||||
function signal_generator(t){
|
||||
return Math.sin(100*2*Math.PI*t) + 0.5 * Math.sin(200*2*Math.PI*t) + 0.25 * Math.sin(400*2*Math.PI*t) + 0.5* Math.random()
|
||||
}
|
||||
|
||||
sampling_frequency = 1024.0
|
||||
number_of_samples = 1024
|
||||
|
||||
|
||||
time_vector = range(0, number_of_samples, 1).map(function(x) {return x / sampling_frequency})
|
||||
signal = time_vector.map(function(x) {return signal_generator(x)})
|
||||
tranform = fft(signal)
|
||||
|
||||
two_side_spectrum = get_modulus(tranform).map(function(x) {return x / number_of_samples})
|
||||
spectrum = two_side_spectrum.slice(1,two_side_spectrum.length/2 + 1).map(function(x) {return (x * x)})
|
||||
spectrum.splice(0,0,two_side_spectrum[0])
|
||||
|
||||
number_of_samples = tranform.length // Signal may have been padded to next power of two
|
||||
freq_vector = range(0, spectrum.length , 1).map(function(x) {return x * sampling_frequency / parseFloat(number_of_samples)})
|
||||
|
||||
plot([signal,spectrum], ["signal", "spectrum"],[time_vector, freq_vector])
|
||||
|
||||
50
script/tutorial/63_OnlineSpectrumAnalyser.js
Executable file
50
script/tutorial/63_OnlineSpectrumAnalyser.js
Executable file
@@ -0,0 +1,50 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Create an online spectrum analyser uysing mathutils.py
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
run("mathutils")
|
||||
|
||||
function plot_spectrum(signal, sampling_freq){
|
||||
if (!is_defined(plots)) plots = null
|
||||
signal = to_array(signal)
|
||||
number_of_samples = signal.length
|
||||
time_vector = range(0, number_of_samples, 1).map(function(x) {return x / sampling_freq})
|
||||
tranform = fft(signal)
|
||||
two_side_spectrum = get_modulus(tranform).map(function(x) {return x / number_of_samples})
|
||||
spectrum = two_side_spectrum.slice(1,two_side_spectrum.length/2 + 1).map(function(x) {return x * x})
|
||||
spectrum.splice(0,0,two_side_spectrum[0])
|
||||
number_of_samples = tranform.length // Signal may have been padded to next power of two
|
||||
freq_vector = range(0, spectrum.length , 1).map(function(x) {return x * sampling_freq / parseFloat(number_of_samples)})
|
||||
if (plots == null){
|
||||
plots = plot([signal,spectrum], ["signal", "spectrum"],[time_vector, freq_vector], undefined, title = "Spectrum")
|
||||
plots[0].getAxis(AxisId.Y).setRange(-1.5,2.5)
|
||||
plots[1].getAxis(AxisId.Y).setRange(0.0,1.1)
|
||||
} else {
|
||||
plots[0].getSeries(0).setData(time_vector,signal)
|
||||
plots[1].getSeries(0).setData(freq_vector,spectrum)
|
||||
}
|
||||
return plots
|
||||
}
|
||||
|
||||
function get_sample(samples, sampling_freq){
|
||||
return range(0,samples,1).map(function(t) {return Math.sin(200*2*Math.PI*t/sampling_freq) + Math.random()})
|
||||
//Simple example sampling a device:
|
||||
//set_exec_pars(undefined, undefined, undefined, undefined, persist=false)
|
||||
//set_preference(Preference.PLOT_DISABLED, true)
|
||||
//set_preference(Preference.TABLE_DISABLED, true)
|
||||
//return tscan(ai1, samples, 1/sampling_freq).getReadable(0)
|
||||
}
|
||||
|
||||
plots = null
|
||||
samples = 1024
|
||||
sampling_freq = 1024.0
|
||||
|
||||
while(true){
|
||||
signal = get_sample(samples, sampling_freq)
|
||||
plots = plot_spectrum(signal, sampling_freq, plots)
|
||||
sleep(0.1)
|
||||
if (plots[0].displayable == false){
|
||||
break
|
||||
}
|
||||
}
|
||||
39
script/tutorial/64_NumericalAnalysis.js
Executable file
39
script/tutorial/64_NumericalAnalysis.js
Executable file
@@ -0,0 +1,39 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Use of numerical analysis functions in mathutils
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
run("mathutils")
|
||||
|
||||
//interpolation
|
||||
var fy = [0, 1, 4,10,50,25,12, 5, 3, 0]
|
||||
var fx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
types = ["linear", "cubic", "akima", "loess", "neville", "newton"]
|
||||
functions = types.map(function(t) {return interpolate(fy,fx,t)})
|
||||
|
||||
plot_x = range (0,9,0.01)
|
||||
values = functions.map(function(f) {return get_values(f,plot_x)})
|
||||
plots=plot(values,types,plot_x)
|
||||
|
||||
//derivative
|
||||
for (var i=0; i<types.length; i++){
|
||||
try{
|
||||
d = deriv(functions[i])
|
||||
plots[i].addSeries(new LinePlotSeries("derivative"))
|
||||
plots[i].getSeries(1).setData(plot_x, get_values(d,plot_x))
|
||||
} catch(ex){
|
||||
//not differentiable
|
||||
}
|
||||
}
|
||||
|
||||
//integration
|
||||
for (var i=0; i<types.length; i++){
|
||||
s = integrate(functions[i],fx)
|
||||
plots[i].addMarker(fx[fx.length-1]+0.1, null, "Integral=" + Math.round(s,4), plots[i].background).setLabelPaint(Color.BLACK)
|
||||
}
|
||||
|
||||
//Direct calculation on arrays:
|
||||
print ("Deriv (linear interpolation): ", deriv(fy,fx))
|
||||
print ("Deriv (cubic interpolation): ", deriv(fy, fx, "cubic"))
|
||||
print ("Integral (linear interpolation): ", integrate(fy, null, fx, "cubic"))
|
||||
print ("Integral (cubic interpolation): ", integrate(fy, null, fx, "cubic"))
|
||||
print ("Integral (linear interpolation in range [1,5]): ", integrate(fy, [1,5], fx))
|
||||
70
script/tutorial/65_ConvexHull.js
Executable file
70
script/tutorial/65_ConvexHull.js
Executable file
@@ -0,0 +1,70 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Example of convex hull plot
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
function add_convex_hull_plot(title, x,y, name, clear){
|
||||
if (!is_defined(name)) name = null
|
||||
if (!is_defined(clear)) clear = false
|
||||
plots = get_plots(title = title)
|
||||
p = null
|
||||
if (plots.length==0){
|
||||
p = plot(null,name=name, undefined, undefined, title = title)[0]
|
||||
p.getAxis(AxisId.X).setRange(-50,150)
|
||||
p.getAxis(AxisId.Y).setRange(-50,150)
|
||||
p.setLegendVisible(true)
|
||||
} else {
|
||||
p = plots[0]
|
||||
if (clear){
|
||||
p.clear()
|
||||
}
|
||||
p.addSeries(new LinePlotSeries(name))
|
||||
}
|
||||
s = p.getSeries(name)
|
||||
s.setLinesVisible(false)
|
||||
s.setPointSize(3)
|
||||
s.setData(x, y)
|
||||
|
||||
//In the first time the plot shows, it takes some time for the color to be assigned
|
||||
while (s.color == null){
|
||||
sleep(0.001)
|
||||
}
|
||||
|
||||
hull = new LinePlotSeries(name + " Hull", s.color)
|
||||
|
||||
//Bounding box
|
||||
//x1 = Math.min.apply(null, x)
|
||||
//x2 = Math.max.apply(null, x)
|
||||
//y1 = Math.min.apply(null, y)
|
||||
//y2 = Math.max.apply(null, y)
|
||||
//(hx,hy) = ([x1,x2, x2, x1, x1], [y1, y1, y2, y2, y1])
|
||||
|
||||
//Convex Hull
|
||||
ret = convex_hull(point_list=undefined, x=x, y=y)
|
||||
hx=ret[0]
|
||||
hy=ret[1]
|
||||
hx.push(hx[0])
|
||||
hy.push(hy[0])
|
||||
|
||||
p.addSeries(hull)
|
||||
hull.setLineWidth(2)
|
||||
hull.setData(hx,hy)
|
||||
hull.setColor(s.color)
|
||||
}
|
||||
|
||||
title = "Convex Hull"
|
||||
if (get_plots(title).length>0){
|
||||
get_plots(title)[0].clear()
|
||||
}
|
||||
|
||||
for (var step=1; step<=5; step++){
|
||||
x=[]
|
||||
y=[]
|
||||
for (var i=0; i<=50 ; i++){
|
||||
x.push(Math.random() * 100 / step)
|
||||
y.push(Math.random() * 100/ step)
|
||||
}
|
||||
add_convex_hull_plot (title, x,y,"Scan " + step)
|
||||
}
|
||||
|
||||
41
script/tutorial/66_WeightedPolynomialFit.js
Executable file
41
script/tutorial/66_WeightedPolynomialFit.js
Executable file
@@ -0,0 +1,41 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Example if fitting with weights
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
run("mathutils")
|
||||
run("plotutils")
|
||||
|
||||
|
||||
fx = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
|
||||
fy = [36.0, 66.0, 121.0, 183.0, 263.0, 365.0, 473.0, 603.0, 753.0, 917.0]
|
||||
num_samples = fx.length
|
||||
|
||||
p=plot(fy, "Observed Data", xdata=fx)[0]
|
||||
p.setLegendVisible(true)
|
||||
|
||||
pars_polynomial= fit_polynomial(fy, fx, 1, null)
|
||||
func = new PolynomialFunction(pars_polynomial)
|
||||
plot_function(p, func, "1st order", fx)
|
||||
|
||||
var w = []; size=num_samples; while(size--) w.push(1.0);
|
||||
w[5]=20.0
|
||||
pars_polynomial= fit_polynomial(fy, fx, 1, null, w)
|
||||
func = new PolynomialFunction(pars_polynomial)
|
||||
plot_function(p, func, "1st order Weighted: " + w , fx)
|
||||
|
||||
pars_polynomial= fit_polynomial(fy, fx, 2, null, w)
|
||||
func = new PolynomialFunction(pars_polynomial)
|
||||
plot_function(p, func, "2nd order" + w , fx)
|
||||
for (var xp in fx){
|
||||
print (fx[xp] + " " + poly(fx[xp], pars_polynomial))
|
||||
}
|
||||
|
||||
print ("")
|
||||
w = [ 10.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 10.0]
|
||||
pars_polynomial= fit_polynomial(fy, fx, 2, null, w)
|
||||
func = new PolynomialFunction(pars_polynomial)
|
||||
plot_function(p, func, "2n order Weighted: " + w , fx)
|
||||
for (var xp in fx){
|
||||
print (fx[xp] + " " + poly(fx[xp], pars_polynomial))
|
||||
}
|
||||
122
script/tutorial/67_LeastSquares.js
Executable file
122
script/tutorial/67_LeastSquares.js
Executable file
@@ -0,0 +1,122 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Example of least squares optimization
|
||||
// http://commons.apache.org/proper/commons-math/userguide/leastsquares.html
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
run("mathutils")
|
||||
run("plotutils")
|
||||
|
||||
|
||||
plots = plot([null, null], [null, null])
|
||||
p1=plots[0]
|
||||
p2=plots[1]
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Fitting the quadratic function f(x) = a x2 + b x + c
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
var fx = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
|
||||
var fy = [36.0, 66.0, 121.0, 183.0, 263.0, 365.0, 473.0, 603.0, 753.0, 917.0]
|
||||
num_samples = fx.length
|
||||
weigths = []; size=num_samples; while(size--) weigths.push(1.0)
|
||||
|
||||
p1.getSeries(0).setData(fx, fy)
|
||||
p1.getSeries(0)
|
||||
|
||||
|
||||
var Model = Java.extend(MultivariateJacobianFunction)
|
||||
var model = new Model() {
|
||||
value: function (variables) {
|
||||
value = new ArrayRealVector(num_samples)
|
||||
jacobian = new Array2DRowRealMatrix(num_samples, 3)
|
||||
for (var i=0; i< num_samples; i++){
|
||||
a=variables.getEntry(0)
|
||||
b=variables.getEntry(1)
|
||||
c=variables.getEntry(2)
|
||||
model = a*fx[i]*fx[i] + b*fx[i] + c
|
||||
value.setEntry(i, model)
|
||||
jacobian.setEntry(i, 0, fx[i]*fx[i]) // derivative with respect to p0 = a
|
||||
jacobian.setEntry(i, 1, fx[i]) // derivative with respect to p1 = b
|
||||
jacobian.setEntry(i, 2, 1.0) // derivative with respect to p2 = c
|
||||
}
|
||||
return new Pair(value, jacobian)
|
||||
},
|
||||
}
|
||||
|
||||
initial = [1.0, 1.0, 1.0] //parameters = a, b, c
|
||||
target = fy.slice(0) //the target is to have all points at the positios
|
||||
|
||||
ret = optimize_least_squares(model, target, initial, weigths)
|
||||
|
||||
parameters = ret[0]
|
||||
residuals = ret[1]
|
||||
rms = ret[2]
|
||||
evals = ret[3]
|
||||
iters = ret[4]
|
||||
|
||||
a = parameters[0]
|
||||
b = parameters[1]
|
||||
c = parameters[2]
|
||||
|
||||
print ("A: " + a + " B: "+ b, " C: "+ c
|
||||
)
|
||||
print ("RMS: " + rms+ " evals: " + evals+ " iters: " + iters
|
||||
)
|
||||
for (var i=0; i<num_samples; i++){
|
||||
print (fx[i] + " " + fy[i] + " " + poly(fx[i] + " " + [c,b,a])
|
||||
)
|
||||
}
|
||||
|
||||
plot_function(p1, new PolynomialFunction([c,b,a]), "Fit", fx)
|
||||
print ("----------------------------------------------------------------------------\n"
|
||||
)
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Fitting center of circle of known radius to observed points
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
radius = 70.0
|
||||
fx = [30.0, 50.0, 110.0, 35.0, 45.0]
|
||||
fy = [68.0, -6.0, -20.0, 15.0, 97.0]
|
||||
num_samples = fx.length
|
||||
weigths = [0.1, 0.1, 1.0, 0.1, 1.0]
|
||||
|
||||
p2.getSeries(0).setData(fx, fy)
|
||||
p2.getSeries(0).setLinesVisible(false)
|
||||
p2.getSeries(0).setPointSize(4)
|
||||
|
||||
// the model function components are the distances to current estimated center,
|
||||
// they should be as close as possible to the specified radius
|
||||
var Model = Java.extend(MultivariateJacobianFunction)
|
||||
var model = new Model() {
|
||||
value: function (variables) {
|
||||
cx=variables.getEntry(0)
|
||||
cy=variables.getEntry(1)
|
||||
value = new ArrayRealVector(num_samples)
|
||||
jacobian = new Array2DRowRealMatrix(num_samples, 2)
|
||||
for (var i=0; i< num_samples; i++){
|
||||
var mod = hypot(cx-fx[i], cy-fy[i])
|
||||
value.setEntry(i, mod)
|
||||
jacobian.setEntry(i, 0, (cx - fx[i]) / mod) // derivative with respect to p0 = x center
|
||||
jacobian.setEntry(i, 1, (cy - fy[i]) / mod) // derivative with respect to p1 = y center
|
||||
}
|
||||
return new Pair(value, jacobian)
|
||||
},
|
||||
}
|
||||
|
||||
initial = [mean(fx), mean(fy)] //parameters = cx, cy
|
||||
target = []; size=num_samples; while(size--) target.push(radius); //the target is to have all points at the specified radius from the center
|
||||
|
||||
ret = optimize_least_squares(model, target, initial, weigths)
|
||||
parameters = ret[0]
|
||||
residuals = ret[1]
|
||||
rms = ret[2]
|
||||
evals = ret[3]
|
||||
iters = ret[4]
|
||||
cx = parameters[0]
|
||||
cy = parameters[1]
|
||||
|
||||
print ("CX: " + cx + " CY: "+ cy)
|
||||
print ("RMS: " + rms+ " evals: " + evals, " iters: " + iters)
|
||||
plot_point(p2, cx, cy, size = 5, color = null, name = "Fit Center")
|
||||
plot_circle(p2, cx, cy, radius, width = 1, color = null, name = "Fit")
|
||||
95
script/tutorial/70_FiltersAndOverlays.js
Executable file
95
script/tutorial/70_FiltersAndOverlays.js
Executable file
@@ -0,0 +1,95 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Demonstrate creation of an image filters and new source based on filter.
|
||||
// Also demonstrate creation of image histogram and use of overlays.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
importClass(java.awt.Point)
|
||||
importClass(java.awt.Dimension)
|
||||
importClass(java.awt.Font)
|
||||
|
||||
Filter = Java.type('ch.psi.pshell.imaging.Filter')
|
||||
|
||||
Pen = Java.type('ch.psi.pshell.imaging.Pen')
|
||||
Line = Java.type('ch.psi.pshell.imaging.Overlays.Line')
|
||||
Rect = Java.type('ch.psi.pshell.imaging.Overlays.Rect')
|
||||
Crosshairs = Java.type('ch.psi.pshell.imaging.Overlays.Crosshairs')
|
||||
Text = Java.type('ch.psi.pshell.imaging.Overlays.Text')
|
||||
Utils = Java.type('ch.psi.pshell.imaging.Utils')
|
||||
|
||||
|
||||
var MyFilter = Java.extend(Filter)
|
||||
var filter = new MyFilter() {
|
||||
process: function (image, data) {
|
||||
image = Utils.grayscale(image)
|
||||
image = Utils.blur(image)
|
||||
image = Utils.sobel(image)
|
||||
return image
|
||||
},
|
||||
}
|
||||
|
||||
//Setting the filter to a source
|
||||
src2.setFilter(filter)
|
||||
|
||||
//Creating a new source with the filter
|
||||
src1.setFilter(null)
|
||||
|
||||
|
||||
add_device(new MyFilter("f1") {
|
||||
process: function (image, data) {
|
||||
image = Utils.grayscale(image)
|
||||
image = Utils.blur(image)
|
||||
image = Utils.sobel(image)
|
||||
return image
|
||||
},
|
||||
}, true)
|
||||
//f1.passive = true
|
||||
src1.addListener(f1)
|
||||
|
||||
|
||||
//Open renderers
|
||||
renderer_filter = show_panel(f1)
|
||||
renderer = show_panel(src1)
|
||||
|
||||
|
||||
//Overlays
|
||||
plots = null
|
||||
size = renderer.getImageSize()
|
||||
ov_text = new Text(new Pen(Color.GREEN.darker()), "Ploting Histogram", new Font("Verdana", Font.PLAIN, 12), new Point(20,20))
|
||||
ov_line = new Line(new Pen(Color.DARK_GRAY), new Point(0,size.height/2), new Point( size.width ,size.height/2))
|
||||
ov_rect = new Rect(new Pen(Color.DARK_GRAY), new Point(size.width/2 -15,size.height/2+10), new Dimension(30,30))
|
||||
ov_cross = new Crosshairs(new Pen(Color.DARK_GRAY), new Point(size.width/2 ,size.height/3), new Dimension(15,15))
|
||||
ov_rect.setSolid(true)
|
||||
ov_rect.setMovable(true)
|
||||
|
||||
//Histogram
|
||||
try{
|
||||
renderer.addOverlays([ov_text,ov_line, ov_rect, ov_cross])
|
||||
|
||||
while(true){
|
||||
|
||||
h = histogram(im1.read(), undefined, undefined, bin=0.1)
|
||||
hd=h[0]; xd = h[1]
|
||||
|
||||
image = Utils.grayscale(src1.getOutput())
|
||||
data = Convert.toUnsigned(image.getData().getDataBuffer().getData())
|
||||
h = histogram(data, range_min=0, range_max=255)
|
||||
hi=h[0]; xi = h[1]
|
||||
|
||||
if (plots == null){
|
||||
plots = plot([hd,hi], ["Data", "Image"],[xd, xi], title = "Histo")
|
||||
} else{
|
||||
plots[0].getSeries(0).setData(xd,hd)
|
||||
plots[1].getSeries(0).setData(xi,hi)
|
||||
}
|
||||
if (plots[0].displayable == false){
|
||||
break
|
||||
}
|
||||
|
||||
ov_cross.update(new Point((ov_cross.position.x+1) % size.width ,(ov_cross.position.y+1) % size.height))
|
||||
|
||||
sleep(0.1)
|
||||
}
|
||||
} finally {
|
||||
renderer.removeOverlays([ov_text,ov_line, ov_rect, ov_cross])
|
||||
}
|
||||
154
script/tutorial/71_ImageJ.js
Executable file
154
script/tutorial/71_ImageJ.js
Executable file
@@ -0,0 +1,154 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Example of using ImageJ functionalities through ijutils.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
run("ijutils")
|
||||
|
||||
//Image Loading
|
||||
ip = load_image("images/img.png", 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], undefined, 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)], undefined, 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 (var i=0; i<256; i++){
|
||||
r.push(0)
|
||||
g.push(0)
|
||||
b.push(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, undefined, undefined, in_place=false)
|
||||
create_stack([ ip_bin,
|
||||
binary_fill_holes(ip_bin, dark_background = false, in_place=false),
|
||||
binary_outline(ip_bin, dark_background = false, in_place=false),
|
||||
binary_outline(binary_fill_holes(ip_bin, dark_background = false, in_place=false), dark_background = false),
|
||||
binary_dilate(ip_bin, undefined, undefined, undefined, in_place=false),
|
||||
binary_erode(ip_bin, undefined, undefined, undefined, in_place=false),
|
||||
binary_open(ip_bin, undefined, undefined, undefined, in_place=false),
|
||||
binary_close(ip_bin, undefined, undefined, undefined, in_place=false),
|
||||
binary_skeletonize(ip_bin, in_place=false)], undefined, title = "Binarization").show()
|
||||
|
||||
|
||||
//EDM, const & image operations
|
||||
aux = grayscale(ip, in_place = false)
|
||||
ip_bin = auto_threshold(aux, undefined, undefined, in_place=false)
|
||||
binary_fill_holes(ip_bin)
|
||||
|
||||
edm = edm(ip_bin, dark_background=false, in_place=false)
|
||||
ws = watershed(ip_bin, dark_background=false, in_place=false)
|
||||
up = ultimate_points(ip_bin, dark_background=false, in_place=false)
|
||||
vr = veronoi(ip_bin, dark_background=false, in_place=false)
|
||||
edm_disp = remap(edm, min=null, max=null, in_place=false)
|
||||
ws_disp = grayscale(ws, in_place=false)
|
||||
up_disp = enhance_contrast(up, undefined, undefined, undefined, undefined, in_place=false)
|
||||
vr_disp = enhance_contrast(vr, undefined, undefined, undefined, undefined, in_place=false)
|
||||
create_stack([edm_disp, aux, ip_bin, ws_disp, up_disp, vr_disp], undefined, title = "EDM Operations").show()
|
||||
final_img = grayscale(ip_bin, in_place = false)
|
||||
op_const(final_img,"add", -200)
|
||||
op_image(final_img, vr_disp, 'or')
|
||||
op_image(final_img, up_disp, 'or')
|
||||
final_img.show()
|
||||
|
||||
aux = grayscale(ip, in_place = false)
|
||||
|
||||
create_stack([ aux,
|
||||
subtract_background(aux, undefined, undefined, undefined, undefined, undefined, undefined, undefined, in_place=false),
|
||||
smooth(aux, false),
|
||||
sharpen(aux, false),
|
||||
edges(aux, false),
|
||||
bandpass_filter(aux,0, 5, undefined, undefined, undefined, undefined, undefined, in_place=false),
|
||||
bandpass_filter(aux,5, 100, undefined, undefined, undefined, undefined, undefined, 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)
|
||||
], undefined, title = "General Operations").show()
|
||||
|
||||
|
||||
//Rank operators
|
||||
rank_opers = []
|
||||
oplist = ["mean", "min", "max", "variance", "median", "close_maxima", "open_maxima", "remove_outliers", "remove_nan", "despeckle"]
|
||||
for (var op in oplist){
|
||||
rank_opers.push(op_rank(aux,oplist[op],kernel_radius=1, undefined, undefined, in_place=false))
|
||||
}
|
||||
create_stack(rank_opers, undefined, title = "Rank Operations").show()
|
||||
|
||||
|
||||
//Reslicing
|
||||
//orig = load_image("{data}/img/img2.png")
|
||||
orig = resize(ip, 300,200)
|
||||
grayscale(orig)
|
||||
images=[]
|
||||
for (var i=0; i<20; i++){
|
||||
images.push(orig.duplicate())
|
||||
op_const(orig, "multiply", 0.9)
|
||||
}
|
||||
stack=create_stack(images, undefined, title = "Original Stack")
|
||||
//stack.show()
|
||||
r1 = reslice(stack, start_at="Left", undefined, undefined, undefined, undefined, title="Reslice Horizontally")
|
||||
r2 = reslice(stack, start_at="Top", undefined, undefined, undefined, undefined, title="Reslice Vertically")
|
||||
r1.show()
|
||||
r2.show()
|
||||
|
||||
|
||||
//Particle Analysis
|
||||
aux = grayscale(ip, in_place = false)
|
||||
auto_threshold(aux)
|
||||
//binary_fill_holes(aux)
|
||||
//aux.show()
|
||||
var ret=analyse_particles(aux, 100,1000, true, true, 0, print_table=true)
|
||||
var results=ret[0]
|
||||
var output_img=ret[1]
|
||||
output_img.show()
|
||||
|
||||
Reference in New Issue
Block a user