Initial commit
This commit is contained in:
15
bin/psss_panel
Executable file
15
bin/psss_panel
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
/opt/gfa/pshell/pshell \
|
||||
-version=v1_17 \
|
||||
-py3 \
|
||||
-m=/opt/gfa/pshell/apps/psss_panel \
|
||||
-z \
|
||||
-nbcf=true \
|
||||
-laf=dark \
|
||||
-d \
|
||||
-pini=true \
|
||||
-clog=WARNING \
|
||||
-sbar \
|
||||
$@
|
||||
13
bin/psss_panel_editor
Executable file
13
bin/psss_panel_editor
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
/opt/gfa/pshell/pshell \
|
||||
-py3 \
|
||||
-version=v1_17 \
|
||||
-z \
|
||||
-nbcf=true \
|
||||
-laf=dark \
|
||||
-pini=true \
|
||||
-setp=/opt/gfa/pshell/apps/psss_panel/config/setup.properties \
|
||||
-p=PSSS.java \
|
||||
$@
|
||||
16
config/devices.properties
Executable file
16
config/devices.properties
Executable file
@@ -0,0 +1,16 @@
|
||||
psss_fwhm_avg=ch.psi.pshell.epics.ChannelDouble|SARFE10-PSSS059:REL-E-SPREAD|||true
|
||||
dispatcher=ch.psi.pshell.bs.Dispatcher|https://dispatcher-api.psi.ch/sf|||
|
||||
cam_server=ch.psi.pshell.bs.PipelineServer|sf-daqsync-01:8889|||
|
||||
energy_machine=ch.psi.pshell.epics.ChannelDouble|SARFE10-PBPG050:ENERGY|||true
|
||||
psss_energy=ch.psi.pshell.epics.ChannelDouble|SARFE10-PSSS059:ENERGY|||true
|
||||
psss_spectrum_x=ch.psi.pshell.epics.ChannelDoubleArray|SARFE10-PSSS059:SPECTRUM_X -1 -3|||true
|
||||
psss_spectrum_y=ch.psi.pshell.epics.ChannelDoubleArray|SARFE10-PSSS059:SPECTRUM_Y -1 -3|||true
|
||||
psss_center=ch.psi.pshell.epics.ChannelDouble|SARFE10-PSSS059:SPECTRUM_CENTER|||true
|
||||
psss_fwhm=ch.psi.pshell.epics.ChannelDouble|SARFE10-PSSS059:SPECTRUM_FWHM|||true
|
||||
psss_roi_min=ch.psi.pshell.epics.ChannelInteger|SARFE10-PSSS059:SPC_ROI_YMIN|||true
|
||||
psss_roi_max=ch.psi.pshell.epics.ChannelInteger|SARFE10-PSSS059:SPC_ROI_YMAX|||true
|
||||
histo_center=ch.psi.pshell.device.HistogramGenerator|psss_center|||true
|
||||
histo_fwhm=ch.psi.pshell.device.HistogramGenerator|psss_fwhm|||true
|
||||
psss_spectrum_y_average=ch.psi.pshell.device.ArrayAverager|psss_spectrum_y|||true
|
||||
psss_center_average=ch.psi.pshell.device.Averager|psss_center|||true
|
||||
psss_fwhm_average=ch.psi.pshell.device.Averager|psss_fwhm|||true
|
||||
12
config/jcae.properties
Executable file
12
config/jcae.properties
Executable file
@@ -0,0 +1,12 @@
|
||||
#Mon Feb 22 20:35:07 CET 2021
|
||||
ch.psi.jcae.ContextFactory.addressList=
|
||||
ch.psi.jcae.ContextFactory.serverPort=
|
||||
ch.psi.jcae.ContextFactory.maxArrayBytes=50000000
|
||||
ch.psi.jcae.ChannelFactory.retries=1
|
||||
ch.psi.jcae.ChannelFactory.timeout=1250
|
||||
ch.psi.jcae.impl.DefaultChannelService.retries=4
|
||||
ch.psi.jcae.impl.DefaultChannelService.timeout=1000
|
||||
ch.psi.jcae.ContextFactory.autoAddressList=true
|
||||
ch.psi.jcae.ContextFactory.useShellVariables=true
|
||||
ch.psi.jcae.ContextFactory.addLocalBroadcastInterfaces=false
|
||||
ch.psi.jcae.ContextFactory.maxSendArrayBytes=1000000
|
||||
23
config/setup.properties
Normal file
23
config/setup.properties
Normal file
@@ -0,0 +1,23 @@
|
||||
#Tue Jul 06 13:13:12 CEST 2021
|
||||
scriptPath=/opt/gfa/pshell/apps/psss_panel/script
|
||||
sessionsPath={outp}/sessions
|
||||
pluginsPath=/opt/gfa/pshell/apps/psss_panel/plugins
|
||||
configFileDevices=/opt/gfa/pshell/apps/psss_panel/config/devices.properties
|
||||
consoleSessionsPath={sessions}/console
|
||||
libraryPath={script}; {script}/Lib
|
||||
contextPath={outp}/context
|
||||
configFilePlugins={config}/plugins.properties
|
||||
extensionsPath={home}/extensions
|
||||
configPath={home}/config
|
||||
configFileSessions={config}/sessions.properties
|
||||
userSessionsPath={sessions}/user
|
||||
dataPath={outp}/data
|
||||
devicesPath=/opt/gfa/pshell/apps/psss_panel/devices
|
||||
configFileVariables={config}/variables.properties
|
||||
configFileSettings={config}/settings.properties
|
||||
wwwPath={home}/www
|
||||
logPath={outp}/log
|
||||
imagesPath={outp}/images
|
||||
configFile={config}/config.properties
|
||||
scriptType=py
|
||||
configFileTasks={config}/tasks.properties
|
||||
25
devices/cam_server.properties
Executable file
25
devices/cam_server.properties
Executable file
@@ -0,0 +1,25 @@
|
||||
#Mon Jan 17 16:00:40 CET 2022
|
||||
spatialCalOffsetY=-50.02549719530852
|
||||
spatialCalOffsetX=-50.01953888237593
|
||||
colormapLogarithmic=false
|
||||
scale=1.0
|
||||
grayscale=false
|
||||
spatialCalScaleX=-1.0
|
||||
spatialCalScaleY=-1.0
|
||||
colormapMax=255.0
|
||||
rescaleOffset=0.0
|
||||
roiWidth=-1
|
||||
colormap=Temperature
|
||||
invert=false
|
||||
colormapMin=0.0
|
||||
rotationCrop=false
|
||||
rotation=0.0
|
||||
rescaleFactor=1.0
|
||||
spatialCalUnits=mm
|
||||
flipVertically=false
|
||||
roiHeight=-1
|
||||
flipHorizontally=false
|
||||
colormapAutomatic=true
|
||||
roiY=0
|
||||
roiX=0
|
||||
transpose=false
|
||||
13
devices/dispatcher.properties
Executable file
13
devices/dispatcher.properties
Executable file
@@ -0,0 +1,13 @@
|
||||
#Wed Jun 03 18:45:57 CEST 2020
|
||||
sendStrategy=complete_all
|
||||
dropIncomplete=false
|
||||
keepListeningOnStop=false
|
||||
disableCompression=false
|
||||
parallelHandlerProcessing=true
|
||||
sendBuildChannelConfig=at_startup
|
||||
sendAwaitFirstMessage=false
|
||||
socketType=DEFAULT
|
||||
validationInconsistency=keep_as_is
|
||||
byteBufferAllocator=false
|
||||
mappingIncomplete=fill_null
|
||||
sendSyncTimeout=0
|
||||
6
devices/histo_center.properties
Executable file
6
devices/histo_center.properties
Executable file
@@ -0,0 +1,6 @@
|
||||
#Tue Jun 15 11:03:15 CEST 2021
|
||||
bins=1000
|
||||
min=11400.0
|
||||
max=11200.0
|
||||
precision=-1
|
||||
numberOfSamples=10000
|
||||
6
devices/histo_fwhm.properties
Executable file
6
devices/histo_fwhm.properties
Executable file
@@ -0,0 +1,6 @@
|
||||
#Fri Apr 30 07:45:13 CEST 2021
|
||||
bins=1000
|
||||
min=0.0
|
||||
max=40.0
|
||||
precision=-1
|
||||
numberOfSamples=10000
|
||||
4
devices/psss_center_average.properties
Executable file
4
devices/psss_center_average.properties
Executable file
@@ -0,0 +1,4 @@
|
||||
#Mon May 03 09:21:35 CEST 2021
|
||||
measures=10
|
||||
precision=-1
|
||||
interval=-1
|
||||
4
devices/psss_fwhm_average.properties
Executable file
4
devices/psss_fwhm_average.properties
Executable file
@@ -0,0 +1,4 @@
|
||||
#Mon May 03 09:21:52 CEST 2021
|
||||
measures=10
|
||||
precision=-1
|
||||
interval=-1
|
||||
5
devices/psss_spectrum_y_average.properties
Executable file
5
devices/psss_spectrum_y_average.properties
Executable file
@@ -0,0 +1,5 @@
|
||||
#Mon May 03 09:15:04 CEST 2021
|
||||
measures=10
|
||||
precision=-1
|
||||
interval=-1
|
||||
integrate=false
|
||||
73
nb/PSSS/build.xml
Normal file
73
nb/PSSS/build.xml
Normal file
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="PSSS" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project PSSS.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar: JAR building
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="PSSS-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
||||
1766
nb/PSSS/nbproject/build-impl.xml
Normal file
1766
nb/PSSS/nbproject/build-impl.xml
Normal file
File diff suppressed because it is too large
Load Diff
8
nb/PSSS/nbproject/genfiles.properties
Normal file
8
nb/PSSS/nbproject/genfiles.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
build.xml.data.CRC32=cb48e78e
|
||||
build.xml.script.CRC32=f58963e5
|
||||
build.xml.stylesheet.CRC32=f85dc8f2@1.97.0.48
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=cb48e78e
|
||||
nbproject/build-impl.xml.script.CRC32=1f638965
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=d549e5cc@1.97.0.48
|
||||
0
nb/PSSS/nbproject/private/config.properties
Normal file
0
nb/PSSS/nbproject/private/config.properties
Normal file
8
nb/PSSS/nbproject/private/private.properties
Normal file
8
nb/PSSS/nbproject/private/private.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
compile.on.save=true
|
||||
do.depend=false
|
||||
do.jar=true
|
||||
do.jlink=false
|
||||
javac.debug=true
|
||||
javadoc.preview=true
|
||||
jlink.strip=false
|
||||
user.properties.file=/afs/psi.ch/user/g/gobbo_a/.netbeans/12.2/build.properties
|
||||
4
nb/PSSS/nbproject/private/private.xml
Normal file
4
nb/PSSS/nbproject/private/private.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
||||
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
|
||||
</project-private>
|
||||
99
nb/PSSS/nbproject/project.properties
Normal file
99
nb/PSSS/nbproject/project.properties
Normal file
@@ -0,0 +1,99 @@
|
||||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.processors.list=
|
||||
annotation.processing.run.all.processors=true
|
||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||
application.title=PSSS
|
||||
application.vendor=gobbo_a
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.modulepath=\
|
||||
${run.modulepath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
debug.test.modulepath=\
|
||||
${run.test.modulepath}
|
||||
# Files in build.classes.dir which should be excluded from distribution jar
|
||||
dist.archive.excludes=
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=${dist.dir}/PSSS.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
dist.jlink.dir=${dist.dir}/jlink
|
||||
dist.jlink.output=${dist.jlink.dir}/PSSS
|
||||
endorsed.classpath=
|
||||
excludes=
|
||||
file.reference.pshell-latest.jar=../../../../head/pshell-latest.jar
|
||||
file.reference.psss_panel-plugins=../../plugins
|
||||
file.reference.psss_panel-script=../../script
|
||||
includes=**/*.java
|
||||
jar.compress=false
|
||||
javac.classpath=\
|
||||
${file.reference.pshell-latest.jar}
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.external.vm=true
|
||||
javac.modulepath=
|
||||
javac.processormodulepath=
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=11
|
||||
javac.target=11
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
javac.test.modulepath=\
|
||||
${javac.modulepath}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.html5=false
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
# The jlink additional root modules to resolve
|
||||
jlink.additionalmodules=
|
||||
# The jlink additional command line parameters
|
||||
jlink.additionalparam=
|
||||
jlink.launcher=true
|
||||
jlink.launcher.name=PSSS
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
mkdist.disabled=true
|
||||
platform.active=default_platform
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project.
|
||||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||
run.jvmargs=
|
||||
run.modulepath=\
|
||||
${javac.modulepath}
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
run.test.modulepath=\
|
||||
${javac.test.modulepath}
|
||||
source.encoding=UTF-8
|
||||
src.plugins.dir=${file.reference.psss_panel-plugins}
|
||||
src.script.dir=${file.reference.psss_panel-script}
|
||||
14
nb/PSSS/nbproject/project.xml
Normal file
14
nb/PSSS/nbproject/project.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>PSSS</name>
|
||||
<source-roots>
|
||||
<root id="src.plugins.dir" name="Plugins"/>
|
||||
<root id="src.script.dir" name="Scripts"/>
|
||||
</source-roots>
|
||||
<test-roots/>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
BIN
plugins/PSSS$1.class
Normal file
BIN
plugins/PSSS$1.class
Normal file
Binary file not shown.
BIN
plugins/PSSS$2.class
Normal file
BIN
plugins/PSSS$2.class
Normal file
Binary file not shown.
BIN
plugins/PSSS$3.class
Normal file
BIN
plugins/PSSS$3.class
Normal file
Binary file not shown.
BIN
plugins/PSSS$4.class
Normal file
BIN
plugins/PSSS$4.class
Normal file
Binary file not shown.
BIN
plugins/PSSS$5.class
Normal file
BIN
plugins/PSSS$5.class
Normal file
Binary file not shown.
BIN
plugins/PSSS$6.class
Normal file
BIN
plugins/PSSS$6.class
Normal file
Binary file not shown.
BIN
plugins/PSSS$7.class
Normal file
BIN
plugins/PSSS$7.class
Normal file
Binary file not shown.
BIN
plugins/PSSS$8.class
Normal file
BIN
plugins/PSSS$8.class
Normal file
Binary file not shown.
BIN
plugins/PSSS$9.class
Normal file
BIN
plugins/PSSS$9.class
Normal file
Binary file not shown.
BIN
plugins/PSSS.class
Normal file
BIN
plugins/PSSS.class
Normal file
Binary file not shown.
715
plugins/PSSS.form
Executable file
715
plugins/PSSS.form
Executable file
@@ -0,0 +1,715 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Component class="javax.swing.ButtonGroup" name="buttonGroup1">
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="tab" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="tab" alignment="1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JTabbedPane" name="tab">
|
||||
<Events>
|
||||
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="tabStateChanged"/>
|
||||
</Events>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
|
||||
<JTabbedPaneConstraints tabName="Spectrum">
|
||||
<Property name="tabTitle" type="java.lang.String" value="Spectrum"/>
|
||||
</JTabbedPaneConstraints>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spinnerAverage" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="history" alignment="0" pref="453" max="32767" attributes="0"/>
|
||||
<Component id="plot" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="12" pref="12" max="-2" attributes="0"/>
|
||||
<Component id="histogramGeneratorFwhm" min="-2" pref="372" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="histogramGeneratorPanelCenter" alignment="0" min="-2" pref="372" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spinnerAverage" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="histogramGeneratorPanelCenter" alignment="0" pref="194" max="32767" attributes="0"/>
|
||||
<Component id="plot" alignment="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="history" pref="194" max="32767" attributes="0"/>
|
||||
<Component id="histogramGeneratorFwhm" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="ch.psi.pshell.plot.LinePlotJFree" name="plot">
|
||||
<Properties>
|
||||
<Property name="title" type="java.lang.String" value=""/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="ch.psi.pshell.plot.TimePlotJFree" name="history">
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Average:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spinnerAverage">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="1" maximum="100" minimum="1" numberType="java.lang.Integer" stepSize="1" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="spinnerAverageStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="ch.psi.pshell.swing.HistogramGeneratorPanel" name="histogramGeneratorPanelCenter">
|
||||
<Properties>
|
||||
<Property name="deviceName" type="java.lang.String" value="histo_center"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="ch.psi.pshell.swing.HistogramGeneratorPanel" name="histogramGeneratorFwhm">
|
||||
<Properties>
|
||||
<Property name="deviceName" type="java.lang.String" value="histo_fwhm"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel4">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
|
||||
<JTabbedPaneConstraints tabName="Camera">
|
||||
<Property name="tabTitle" type="java.lang.String" value="Camera"/>
|
||||
</JTabbedPaneConstraints>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="843" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Component id="renderer" alignment="0" pref="843" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="432" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Component id="renderer" alignment="0" pref="432" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="ch.psi.pshell.imaging.Renderer" name="renderer">
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel3">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
|
||||
<JTabbedPaneConstraints tabName="Alignment">
|
||||
<Property name="tabTitle" type="java.lang.String" value="Alignment"/>
|
||||
</JTabbedPaneConstraints>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jPanel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
<Component id="plotScan" pref="614" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jPanel2" max="32767" attributes="0"/>
|
||||
<Component id="plotScan" pref="432" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel2">
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="-2" pref="12" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" max="-2" attributes="0">
|
||||
<Component id="jPanel5" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="radioCrystalScan" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="radioCameraScan" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="radioEnergyScan" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btAbort" alignment="0" pref="213" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="-2" pref="20" max="-2" attributes="0"/>
|
||||
<Component id="radioEnergyScan" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="radioCameraScan" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="radioCrystalScan" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jPanel5" max="32767" attributes="0"/>
|
||||
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btAbort" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="btAbort">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Abort"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btAbortActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="radioEnergyScan">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="buttonGroup1"/>
|
||||
</Property>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" value="Energy Scan"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="radioEnergyScanActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="radioCameraScan">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="buttonGroup1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="Camera Scan"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="radioCameraScanActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JRadioButton" name="radioCrystalScan">
|
||||
<Properties>
|
||||
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||
<ComponentRef name="buttonGroup1"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" value="Crystal Height Scan"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="radioCrystalScanActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="jPanel5">
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="panelScan" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="panelScan" max="32767" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="panelScan">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="panelEnergyScan">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
|
||||
<CardConstraints cardName="energy"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel7" linkSize="7" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spToEn" linkSize="8" min="-2" pref="80" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel6" linkSize="7" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spFromEn" linkSize="8" min="-2" pref="80" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel8" linkSize="7" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spStepsEn" linkSize="8" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel9" linkSize="7" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spShotsEn" linkSize="8" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="btStartEn" alignment="1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel6" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spFromEn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spToEn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel8" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spStepsEn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel9" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spShotsEn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="btStartEn" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JSpinner" name="spFromEn">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="7200.0" maximum="20000.0" minimum="1.0" numberType="java.lang.Double" stepSize="10.0" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel6">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" value="Range From:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel7">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" value="Range To:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spToEn">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="7340.0" maximum="20000.0" minimum="1.0" numberType="java.lang.Double" stepSize="10.0" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spStepsEn">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="20" maximum="1000" minimum="1" numberType="java.lang.Integer" stepSize="1" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel8">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" value="Steps:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel9">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" value="Num Shots:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spShotsEn">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="100" maximum="1000" minimum="1" numberType="java.lang.Integer" stepSize="1" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btStartEn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Start Energy Scan"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btStartEnActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="panelCameraScan">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
|
||||
<CardConstraints cardName="camera"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel11" linkSize="10" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spToCam" linkSize="11" min="-2" pref="80" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel10" linkSize="10" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spFromCam" linkSize="11" min="-2" pref="80" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel12" linkSize="10" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spStepsCam" linkSize="11" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel13" linkSize="10" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spShotsCam" linkSize="11" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="btStartCam" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel10" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spFromCam" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel11" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spToCam" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel12" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spStepsCam" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel13" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spShotsCam" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="btStartCam" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel10">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" value="Range From:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spFromCam">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="-17.0" maximum="30.0" minimum="-30.0" numberType="java.lang.Double" stepSize="1.0" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel11">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" value="Range To:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spToCam">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="-11.0" maximum="30.0" minimum="-30.0" numberType="java.lang.Double" stepSize="1.0" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel12">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" value="Steps:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spStepsCam">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="20" maximum="1000" minimum="1" numberType="java.lang.Integer" stepSize="1" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel13">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" value="Num Shots:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spShotsCam">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="100" maximum="1000" minimum="1" numberType="java.lang.Integer" stepSize="1" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btStartCam">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Start Camera Scan"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btStartCamActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="panelCrystalScan">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
|
||||
<CardConstraints cardName="crystal"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jLabel3" linkSize="6" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spToCr" linkSize="9" min="-2" pref="80" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel2" linkSize="6" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spFromCr" linkSize="9" min="-2" pref="80" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jLabel4" linkSize="6" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spStepsCr" linkSize="9" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jLabel5" linkSize="6" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="spShotsCr" linkSize="9" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="btStartCr" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spFromCr" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spToCr" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel4" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spStepsCr" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="spShotsCr" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="btStartCr" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" value="Range From:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spFromCr">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="-0.8" maximum="10.0" minimum="-10.0" numberType="java.lang.Double" stepSize="0.1" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel3">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" value="Range To:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spToCr">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="-1.7" maximum="10.0" minimum="-10.0" numberType="java.lang.Double" stepSize="0.1" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel4">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" value="Steps:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spStepsCr">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="20" maximum="1000" minimum="1" numberType="java.lang.Integer" stepSize="1" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel5">
|
||||
<Properties>
|
||||
<Property name="horizontalAlignment" type="int" value="11"/>
|
||||
<Property name="text" type="java.lang.String" value="Num Shots:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSpinner" name="spShotsCr">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
|
||||
<SpinnerModel initial="100" maximum="1000" minimum="1" numberType="java.lang.Integer" stepSize="1" type="number"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btStartCr">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Start Crystal Height Scan"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btStartCrActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="ch.psi.pshell.plot.LinePlotJFree" name="plotScan">
|
||||
<Properties>
|
||||
<Property name="title" type="java.lang.String" value=""/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
760
plugins/PSSS.java
Executable file
760
plugins/PSSS.java
Executable file
@@ -0,0 +1,760 @@
|
||||
import ch.psi.pshell.bs.PipelineServer;
|
||||
import ch.psi.pshell.core.Context;
|
||||
import ch.psi.pshell.epics.ChannelDouble;
|
||||
import ch.psi.pshell.imaging.RendererMode;
|
||||
import ch.psi.pshell.plot.Plot;
|
||||
import ch.psi.pshell.plot.LinePlotJFree;
|
||||
import ch.psi.pshell.ui.Panel;
|
||||
import ch.psi.utils.Convert;
|
||||
import ch.psi.utils.State;
|
||||
import ch.psi.utils.Str;
|
||||
import java.awt.CardLayout;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PSSS extends Panel {
|
||||
|
||||
final String CAMERA_NAME = "SARFE10-PSSS059";
|
||||
PipelineServer pipelineServer;
|
||||
volatile boolean updatingPlot;
|
||||
volatile boolean updatingImage;
|
||||
|
||||
public PSSS() {
|
||||
initComponents();
|
||||
plot.getAxis(Plot.AxisId.X).setLabel(null);
|
||||
plot.getAxis(Plot.AxisId.Y).setLabel(null);
|
||||
renderer.setMode(RendererMode.Stretch);
|
||||
}
|
||||
|
||||
//Overridable callbacks
|
||||
@Override
|
||||
public void onInitialize(int runCount) {
|
||||
startTimer(1000);
|
||||
|
||||
try {
|
||||
setGlobalVar("PSSS_PLOT", plot);
|
||||
setGlobalVar("HISTORY_PLOT", history);
|
||||
setGlobalVar("PSSS_RENDERER", renderer);
|
||||
|
||||
pipelineServer = (PipelineServer) getDevice("cam_server");
|
||||
((LinePlotJFree)histogramGeneratorPanelCenter.getPlot()).setLegendVisible(true);
|
||||
((LinePlotJFree)histogramGeneratorFwhm.getPlot()).setLegendVisible(true);
|
||||
histogramGeneratorPanelCenter.getPlot().getAxis(Plot.AxisId.Y).setRange(0, 100);
|
||||
histogramGeneratorFwhm.getPlot().getAxis(Plot.AxisId.Y).setRange(0, 100);
|
||||
//setImageEnabled(true);
|
||||
tabStateChanged(null);
|
||||
|
||||
spinnerAverage.setValue(( (Number) eval("get_psss_averaging()", true)).intValue());
|
||||
|
||||
try{
|
||||
Double energy = (((ChannelDouble)getDevice("energy_machine")).take(-1));
|
||||
energy=Convert.roundDouble(energy, 0);
|
||||
spFromEn.setValue(energy-150);
|
||||
spToEn.setValue(energy+150);
|
||||
} catch (Exception ex) {
|
||||
getLogger().log(Level.WARNING, null, ex);
|
||||
}
|
||||
|
||||
|
||||
} catch (Exception ex) {
|
||||
getLogger().log(Level.WARNING, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateChange(State state, State former) {
|
||||
this.btStartCr.setEnabled(state == State.Ready);
|
||||
this.btStartEn.setEnabled(state == State.Ready);
|
||||
this.btStartCam.setEnabled(state == State.Ready);
|
||||
radioEnergyScan.setEnabled(state == State.Ready);
|
||||
radioCrystalScan.setEnabled(state == State.Ready);
|
||||
radioCameraScan.setEnabled(state == State.Ready);
|
||||
this.btAbort.setEnabled(state.isRunning());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExecutedFile(String fileName, Object result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimer() {
|
||||
try {
|
||||
if (!updatingPlot){
|
||||
updatingPlot = true;
|
||||
//evalAsync("plot_psss(PSSS_PLOT, HISTORY_PLOT, " + spinnerAverage.getValue() + ")", true).handle((ret,ex)->{
|
||||
evalAsync("plot_psss(PSSS_PLOT, HISTORY_PLOT)", true).handle((ret,ex)->{
|
||||
updatingPlot = false;
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
if (isImageEnabled()){
|
||||
if (!updatingImage){
|
||||
updatingImage = true;
|
||||
evalAsync("update_psss_image(PSSS_RENDERER)", true).handle((ret,ex)->{
|
||||
updatingImage = false;
|
||||
return ret;
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
getLogger().log(Level.WARNING, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
//Callback to perform update - in event thread
|
||||
@Override
|
||||
protected void doUpdate() {
|
||||
}
|
||||
|
||||
void setImageEnabled(boolean enabled){
|
||||
try{
|
||||
imageEnabled = enabled;
|
||||
evalAsync("enable_psss_image(" + Str.capitalizeFirst(String.valueOf(enabled)) + ", PSSS_RENDERER)", true);
|
||||
} catch (Exception ex) {
|
||||
getLogger().log(Level.WARNING, null, ex);
|
||||
}
|
||||
}
|
||||
volatile boolean imageEnabled;
|
||||
|
||||
boolean isImageEnabled(){
|
||||
return imageEnabled;
|
||||
}
|
||||
|
||||
|
||||
void runScan(String name, Map args){
|
||||
try {
|
||||
args.put("PLOT", plotScan);
|
||||
this.runAsync(name, args).handle((ret,ex)->{
|
||||
if (ex!=null){
|
||||
if (!getContext().isAborted()){
|
||||
showException((Exception)ex);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
} catch (Context.ContextStateException ex) {
|
||||
showException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
buttonGroup1 = new javax.swing.ButtonGroup();
|
||||
tab = new javax.swing.JTabbedPane();
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
plot = new ch.psi.pshell.plot.LinePlotJFree();
|
||||
history = new ch.psi.pshell.plot.TimePlotJFree();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
spinnerAverage = new javax.swing.JSpinner();
|
||||
histogramGeneratorPanelCenter = new ch.psi.pshell.swing.HistogramGeneratorPanel();
|
||||
histogramGeneratorFwhm = new ch.psi.pshell.swing.HistogramGeneratorPanel();
|
||||
jPanel4 = new javax.swing.JPanel();
|
||||
renderer = new ch.psi.pshell.imaging.Renderer();
|
||||
jPanel3 = new javax.swing.JPanel();
|
||||
jPanel2 = new javax.swing.JPanel();
|
||||
btAbort = new javax.swing.JButton();
|
||||
radioEnergyScan = new javax.swing.JRadioButton();
|
||||
radioCameraScan = new javax.swing.JRadioButton();
|
||||
radioCrystalScan = new javax.swing.JRadioButton();
|
||||
jPanel5 = new javax.swing.JPanel();
|
||||
panelScan = new javax.swing.JPanel();
|
||||
panelEnergyScan = new javax.swing.JPanel();
|
||||
spFromEn = new javax.swing.JSpinner();
|
||||
jLabel6 = new javax.swing.JLabel();
|
||||
jLabel7 = new javax.swing.JLabel();
|
||||
spToEn = new javax.swing.JSpinner();
|
||||
spStepsEn = new javax.swing.JSpinner();
|
||||
jLabel8 = new javax.swing.JLabel();
|
||||
jLabel9 = new javax.swing.JLabel();
|
||||
spShotsEn = new javax.swing.JSpinner();
|
||||
btStartEn = new javax.swing.JButton();
|
||||
panelCameraScan = new javax.swing.JPanel();
|
||||
jLabel10 = new javax.swing.JLabel();
|
||||
spFromCam = new javax.swing.JSpinner();
|
||||
jLabel11 = new javax.swing.JLabel();
|
||||
spToCam = new javax.swing.JSpinner();
|
||||
jLabel12 = new javax.swing.JLabel();
|
||||
spStepsCam = new javax.swing.JSpinner();
|
||||
jLabel13 = new javax.swing.JLabel();
|
||||
spShotsCam = new javax.swing.JSpinner();
|
||||
btStartCam = new javax.swing.JButton();
|
||||
panelCrystalScan = new javax.swing.JPanel();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
spFromCr = new javax.swing.JSpinner();
|
||||
jLabel3 = new javax.swing.JLabel();
|
||||
spToCr = new javax.swing.JSpinner();
|
||||
jLabel4 = new javax.swing.JLabel();
|
||||
spStepsCr = new javax.swing.JSpinner();
|
||||
jLabel5 = new javax.swing.JLabel();
|
||||
spShotsCr = new javax.swing.JSpinner();
|
||||
btStartCr = new javax.swing.JButton();
|
||||
plotScan = new ch.psi.pshell.plot.LinePlotJFree();
|
||||
|
||||
tab.addChangeListener(new javax.swing.event.ChangeListener() {
|
||||
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
tabStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
plot.setTitle("");
|
||||
|
||||
jLabel1.setText("Average:");
|
||||
|
||||
spinnerAverage.setModel(new javax.swing.SpinnerNumberModel(1, 1, 100, 1));
|
||||
spinnerAverage.addChangeListener(new javax.swing.event.ChangeListener() {
|
||||
public void stateChanged(javax.swing.event.ChangeEvent evt) {
|
||||
spinnerAverageStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
histogramGeneratorPanelCenter.setDeviceName("histo_center");
|
||||
|
||||
histogramGeneratorFwhm.setDeviceName("histo_fwhm");
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spinnerAverage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(history, javax.swing.GroupLayout.DEFAULT_SIZE, 453, Short.MAX_VALUE)
|
||||
.addComponent(plot, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addGap(12, 12, 12)
|
||||
.addComponent(histogramGeneratorFwhm, javax.swing.GroupLayout.PREFERRED_SIZE, 372, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(histogramGeneratorPanelCenter, javax.swing.GroupLayout.PREFERRED_SIZE, 372, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(0, 0, 0))
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel1)
|
||||
.addComponent(spinnerAverage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGap(6, 6, 6)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(histogramGeneratorPanelCenter, javax.swing.GroupLayout.DEFAULT_SIZE, 194, Short.MAX_VALUE)
|
||||
.addComponent(plot, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(history, javax.swing.GroupLayout.DEFAULT_SIZE, 194, Short.MAX_VALUE)
|
||||
.addComponent(histogramGeneratorFwhm, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)))
|
||||
);
|
||||
|
||||
tab.addTab("Spectrum", jPanel1);
|
||||
|
||||
javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
|
||||
jPanel4.setLayout(jPanel4Layout);
|
||||
jPanel4Layout.setHorizontalGroup(
|
||||
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 843, Short.MAX_VALUE)
|
||||
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(renderer, javax.swing.GroupLayout.DEFAULT_SIZE, 843, Short.MAX_VALUE))
|
||||
);
|
||||
jPanel4Layout.setVerticalGroup(
|
||||
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 432, Short.MAX_VALUE)
|
||||
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(renderer, javax.swing.GroupLayout.DEFAULT_SIZE, 432, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
tab.addTab("Camera", jPanel4);
|
||||
|
||||
btAbort.setText("Abort");
|
||||
btAbort.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btAbortActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonGroup1.add(radioEnergyScan);
|
||||
radioEnergyScan.setSelected(true);
|
||||
radioEnergyScan.setText("Energy Scan");
|
||||
radioEnergyScan.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
radioEnergyScanActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonGroup1.add(radioCameraScan);
|
||||
radioCameraScan.setText("Camera Scan");
|
||||
radioCameraScan.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
radioCameraScanActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonGroup1.add(radioCrystalScan);
|
||||
radioCrystalScan.setText("Crystal Height Scan");
|
||||
radioCrystalScan.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
radioCrystalScanActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
panelScan.setLayout(new java.awt.CardLayout());
|
||||
|
||||
spFromEn.setModel(new javax.swing.SpinnerNumberModel(7200.0d, 1.0d, 20000.0d, 10.0d));
|
||||
|
||||
jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
|
||||
jLabel6.setText("Range From:");
|
||||
|
||||
jLabel7.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
|
||||
jLabel7.setText("Range To:");
|
||||
|
||||
spToEn.setModel(new javax.swing.SpinnerNumberModel(7340.0d, 1.0d, 20000.0d, 10.0d));
|
||||
|
||||
spStepsEn.setModel(new javax.swing.SpinnerNumberModel(20, 1, 1000, 1));
|
||||
|
||||
jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
|
||||
jLabel8.setText("Steps:");
|
||||
|
||||
jLabel9.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
|
||||
jLabel9.setText("Num Shots:");
|
||||
|
||||
spShotsEn.setModel(new javax.swing.SpinnerNumberModel(100, 1, 1000, 1));
|
||||
|
||||
btStartEn.setText("Start Energy Scan");
|
||||
btStartEn.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btStartEnActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout panelEnergyScanLayout = new javax.swing.GroupLayout(panelEnergyScan);
|
||||
panelEnergyScan.setLayout(panelEnergyScanLayout);
|
||||
panelEnergyScanLayout.setHorizontalGroup(
|
||||
panelEnergyScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(panelEnergyScanLayout.createSequentialGroup()
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(panelEnergyScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(panelEnergyScanLayout.createSequentialGroup()
|
||||
.addComponent(jLabel7)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spToEn, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(panelEnergyScanLayout.createSequentialGroup()
|
||||
.addComponent(jLabel6)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spFromEn, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(panelEnergyScanLayout.createSequentialGroup()
|
||||
.addComponent(jLabel8)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spStepsEn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(panelEnergyScanLayout.createSequentialGroup()
|
||||
.addComponent(jLabel9)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spShotsEn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addContainerGap())
|
||||
.addComponent(btStartEn, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
panelEnergyScanLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel6, jLabel7, jLabel8, jLabel9});
|
||||
|
||||
panelEnergyScanLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {spFromEn, spShotsEn, spStepsEn, spToEn});
|
||||
|
||||
panelEnergyScanLayout.setVerticalGroup(
|
||||
panelEnergyScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(panelEnergyScanLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(panelEnergyScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel6)
|
||||
.addComponent(spFromEn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(panelEnergyScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel7)
|
||||
.addComponent(spToEn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(panelEnergyScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel8)
|
||||
.addComponent(spStepsEn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(panelEnergyScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel9)
|
||||
.addComponent(spShotsEn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btStartEn)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
panelScan.add(panelEnergyScan, "energy");
|
||||
|
||||
jLabel10.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
|
||||
jLabel10.setText("Range From:");
|
||||
|
||||
spFromCam.setModel(new javax.swing.SpinnerNumberModel(-17.0d, -30.0d, 30.0d, 1.0d));
|
||||
|
||||
jLabel11.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
|
||||
jLabel11.setText("Range To:");
|
||||
|
||||
spToCam.setModel(new javax.swing.SpinnerNumberModel(-11.0d, -30.0d, 30.0d, 1.0d));
|
||||
|
||||
jLabel12.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
|
||||
jLabel12.setText("Steps:");
|
||||
|
||||
spStepsCam.setModel(new javax.swing.SpinnerNumberModel(20, 1, 1000, 1));
|
||||
|
||||
jLabel13.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
|
||||
jLabel13.setText("Num Shots:");
|
||||
|
||||
spShotsCam.setModel(new javax.swing.SpinnerNumberModel(100, 1, 1000, 1));
|
||||
|
||||
btStartCam.setText("Start Camera Scan");
|
||||
btStartCam.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btStartCamActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout panelCameraScanLayout = new javax.swing.GroupLayout(panelCameraScan);
|
||||
panelCameraScan.setLayout(panelCameraScanLayout);
|
||||
panelCameraScanLayout.setHorizontalGroup(
|
||||
panelCameraScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(panelCameraScanLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(panelCameraScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(panelCameraScanLayout.createSequentialGroup()
|
||||
.addComponent(jLabel11)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spToCam, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(panelCameraScanLayout.createSequentialGroup()
|
||||
.addComponent(jLabel10)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spFromCam, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(panelCameraScanLayout.createSequentialGroup()
|
||||
.addComponent(jLabel12)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spStepsCam, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(panelCameraScanLayout.createSequentialGroup()
|
||||
.addComponent(jLabel13)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spShotsCam, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addComponent(btStartCam, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
panelCameraScanLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel10, jLabel11, jLabel12, jLabel13});
|
||||
|
||||
panelCameraScanLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {spFromCam, spShotsCam, spStepsCam, spToCam});
|
||||
|
||||
panelCameraScanLayout.setVerticalGroup(
|
||||
panelCameraScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(panelCameraScanLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(panelCameraScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel10)
|
||||
.addComponent(spFromCam, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(panelCameraScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel11)
|
||||
.addComponent(spToCam, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(panelCameraScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel12)
|
||||
.addComponent(spStepsCam, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(panelCameraScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel13)
|
||||
.addComponent(spShotsCam, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btStartCam)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
panelScan.add(panelCameraScan, "camera");
|
||||
|
||||
jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
|
||||
jLabel2.setText("Range From:");
|
||||
|
||||
spFromCr.setModel(new javax.swing.SpinnerNumberModel(-0.8d, -10.0d, 10.0d, 0.1d));
|
||||
|
||||
jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
|
||||
jLabel3.setText("Range To:");
|
||||
|
||||
spToCr.setModel(new javax.swing.SpinnerNumberModel(-1.7d, -10.0d, 10.0d, 0.1d));
|
||||
|
||||
jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
|
||||
jLabel4.setText("Steps:");
|
||||
|
||||
spStepsCr.setModel(new javax.swing.SpinnerNumberModel(20, 1, 1000, 1));
|
||||
|
||||
jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
|
||||
jLabel5.setText("Num Shots:");
|
||||
|
||||
spShotsCr.setModel(new javax.swing.SpinnerNumberModel(100, 1, 1000, 1));
|
||||
|
||||
btStartCr.setText("Start Crystal Height Scan");
|
||||
btStartCr.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btStartCrActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout panelCrystalScanLayout = new javax.swing.GroupLayout(panelCrystalScan);
|
||||
panelCrystalScan.setLayout(panelCrystalScanLayout);
|
||||
panelCrystalScanLayout.setHorizontalGroup(
|
||||
panelCrystalScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(panelCrystalScanLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(panelCrystalScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(panelCrystalScanLayout.createSequentialGroup()
|
||||
.addComponent(jLabel3)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spToCr, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(panelCrystalScanLayout.createSequentialGroup()
|
||||
.addComponent(jLabel2)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spFromCr, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(panelCrystalScanLayout.createSequentialGroup()
|
||||
.addComponent(jLabel4)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spStepsCr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addGroup(panelCrystalScanLayout.createSequentialGroup()
|
||||
.addComponent(jLabel5)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(spShotsCr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addComponent(btStartCr, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
panelCrystalScanLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel2, jLabel3, jLabel4, jLabel5});
|
||||
|
||||
panelCrystalScanLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {spFromCr, spShotsCr, spStepsCr, spToCr});
|
||||
|
||||
panelCrystalScanLayout.setVerticalGroup(
|
||||
panelCrystalScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(panelCrystalScanLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(panelCrystalScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel2)
|
||||
.addComponent(spFromCr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(panelCrystalScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel3)
|
||||
.addComponent(spToCr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(panelCrystalScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel4)
|
||||
.addComponent(spStepsCr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(panelCrystalScanLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel5)
|
||||
.addComponent(spShotsCr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btStartCr)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
panelScan.add(panelCrystalScan, "crystal");
|
||||
|
||||
javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
|
||||
jPanel5.setLayout(jPanel5Layout);
|
||||
jPanel5Layout.setHorizontalGroup(
|
||||
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel5Layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(panelScan, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0)))
|
||||
);
|
||||
jPanel5Layout.setVerticalGroup(
|
||||
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel5Layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(panelScan, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGap(0, 0, 0)))
|
||||
);
|
||||
|
||||
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
|
||||
jPanel2.setLayout(jPanel2Layout);
|
||||
jPanel2Layout.setHorizontalGroup(
|
||||
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel2Layout.createSequentialGroup()
|
||||
.addGap(12, 12, 12)
|
||||
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
|
||||
.addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(radioCrystalScan)
|
||||
.addComponent(radioCameraScan)
|
||||
.addComponent(radioEnergyScan)
|
||||
.addComponent(btAbort, javax.swing.GroupLayout.DEFAULT_SIZE, 213, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
jPanel2Layout.setVerticalGroup(
|
||||
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
|
||||
.addGap(20, 20, 20)
|
||||
.addComponent(radioEnergyScan)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(radioCameraScan)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(radioCrystalScan)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(btAbort)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
plotScan.setTitle("");
|
||||
|
||||
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
|
||||
jPanel3.setLayout(jPanel3Layout);
|
||||
jPanel3Layout.setHorizontalGroup(
|
||||
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel3Layout.createSequentialGroup()
|
||||
.addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, 0)
|
||||
.addComponent(plotScan, javax.swing.GroupLayout.DEFAULT_SIZE, 614, Short.MAX_VALUE))
|
||||
);
|
||||
jPanel3Layout.setVerticalGroup(
|
||||
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(plotScan, javax.swing.GroupLayout.DEFAULT_SIZE, 432, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
tab.addTab("Alignment", jPanel3);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(tab)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(tab, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void tabStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_tabStateChanged
|
||||
setImageEnabled(tab.getSelectedIndex()==1);
|
||||
}//GEN-LAST:event_tabStateChanged
|
||||
|
||||
private void btAbortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btAbortActionPerformed
|
||||
try {
|
||||
abort();
|
||||
} catch (Exception ex) {
|
||||
showException(ex);
|
||||
}
|
||||
}//GEN-LAST:event_btAbortActionPerformed
|
||||
|
||||
private void btStartCrActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btStartCrActionPerformed
|
||||
Map args = new HashMap();
|
||||
args.put("RANGE_FROM", spFromCr.getValue());
|
||||
args.put("RANGE_TO", spToCr.getValue());
|
||||
args.put("STEPS", spStepsCr.getValue());
|
||||
args.put("NUM_SHOTS", spShotsCr.getValue());
|
||||
runScan("psss/CrystalHeightScan",args);
|
||||
}//GEN-LAST:event_btStartCrActionPerformed
|
||||
|
||||
private void btStartCamActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btStartCamActionPerformed
|
||||
Map args = new HashMap();
|
||||
args.put("RANGE_FROM", spFromCam.getValue());
|
||||
args.put("RANGE_TO", spToCam.getValue());
|
||||
args.put("STEPS", spStepsCam.getValue());
|
||||
args.put("NUM_SHOTS", spShotsCam.getValue());
|
||||
runScan("psss/CameraScan",args);
|
||||
}//GEN-LAST:event_btStartCamActionPerformed
|
||||
|
||||
private void btStartEnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btStartEnActionPerformed
|
||||
Map args = new HashMap();
|
||||
args.put("RANGE_OFF", null);
|
||||
args.put("RANGE_FROM", spFromEn.getValue());
|
||||
args.put("RANGE_TO", spToEn.getValue());
|
||||
args.put("STEPS", spStepsEn.getValue());
|
||||
args.put("NUM_SHOTS", spShotsEn.getValue());
|
||||
runScan("psss/EnergyScan",args);
|
||||
}//GEN-LAST:event_btStartEnActionPerformed
|
||||
|
||||
private void radioEnergyScanActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_radioEnergyScanActionPerformed
|
||||
((CardLayout)panelScan.getLayout()).show(panelScan, "energy");
|
||||
}//GEN-LAST:event_radioEnergyScanActionPerformed
|
||||
|
||||
private void radioCameraScanActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_radioCameraScanActionPerformed
|
||||
((CardLayout)panelScan.getLayout()).show(panelScan, "camera");
|
||||
}//GEN-LAST:event_radioCameraScanActionPerformed
|
||||
|
||||
private void radioCrystalScanActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_radioCrystalScanActionPerformed
|
||||
((CardLayout)panelScan.getLayout()).show(panelScan, "crystal");
|
||||
}//GEN-LAST:event_radioCrystalScanActionPerformed
|
||||
|
||||
private void spinnerAverageStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerAverageStateChanged
|
||||
try {
|
||||
eval("set_psss_averaging(" + spinnerAverage.getValue() + ")", true);
|
||||
} catch (Exception ex) {
|
||||
showException(ex);
|
||||
}
|
||||
}//GEN-LAST:event_spinnerAverageStateChanged
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton btAbort;
|
||||
private javax.swing.JButton btStartCam;
|
||||
private javax.swing.JButton btStartCr;
|
||||
private javax.swing.JButton btStartEn;
|
||||
private javax.swing.ButtonGroup buttonGroup1;
|
||||
private ch.psi.pshell.swing.HistogramGeneratorPanel histogramGeneratorFwhm;
|
||||
private ch.psi.pshell.swing.HistogramGeneratorPanel histogramGeneratorPanelCenter;
|
||||
private ch.psi.pshell.plot.TimePlotJFree history;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel10;
|
||||
private javax.swing.JLabel jLabel11;
|
||||
private javax.swing.JLabel jLabel12;
|
||||
private javax.swing.JLabel jLabel13;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JLabel jLabel3;
|
||||
private javax.swing.JLabel jLabel4;
|
||||
private javax.swing.JLabel jLabel5;
|
||||
private javax.swing.JLabel jLabel6;
|
||||
private javax.swing.JLabel jLabel7;
|
||||
private javax.swing.JLabel jLabel8;
|
||||
private javax.swing.JLabel jLabel9;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
private javax.swing.JPanel jPanel2;
|
||||
private javax.swing.JPanel jPanel3;
|
||||
private javax.swing.JPanel jPanel4;
|
||||
private javax.swing.JPanel jPanel5;
|
||||
private javax.swing.JPanel panelCameraScan;
|
||||
private javax.swing.JPanel panelCrystalScan;
|
||||
private javax.swing.JPanel panelEnergyScan;
|
||||
private javax.swing.JPanel panelScan;
|
||||
private ch.psi.pshell.plot.LinePlotJFree plot;
|
||||
private ch.psi.pshell.plot.LinePlotJFree plotScan;
|
||||
private javax.swing.JRadioButton radioCameraScan;
|
||||
private javax.swing.JRadioButton radioCrystalScan;
|
||||
private javax.swing.JRadioButton radioEnergyScan;
|
||||
private ch.psi.pshell.imaging.Renderer renderer;
|
||||
private javax.swing.JSpinner spFromCam;
|
||||
private javax.swing.JSpinner spFromCr;
|
||||
private javax.swing.JSpinner spFromEn;
|
||||
private javax.swing.JSpinner spShotsCam;
|
||||
private javax.swing.JSpinner spShotsCr;
|
||||
private javax.swing.JSpinner spShotsEn;
|
||||
private javax.swing.JSpinner spStepsCam;
|
||||
private javax.swing.JSpinner spStepsCr;
|
||||
private javax.swing.JSpinner spStepsEn;
|
||||
private javax.swing.JSpinner spToCam;
|
||||
private javax.swing.JSpinner spToCr;
|
||||
private javax.swing.JSpinner spToEn;
|
||||
private javax.swing.JSpinner spinnerAverage;
|
||||
private javax.swing.JTabbedPane tab;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
587
script/Lib/builtin_classes.py
Normal file
587
script/Lib/builtin_classes.py
Normal file
@@ -0,0 +1,587 @@
|
||||
from builtin_utils import *
|
||||
|
||||
import ch.psi.utils.Threading as Threading
|
||||
import ch.psi.utils.State as State
|
||||
import ch.psi.utils.Convert as Convert
|
||||
import ch.psi.utils.Str as Str
|
||||
import ch.psi.utils.Sys as Sys
|
||||
import ch.psi.utils.Arr as Arr
|
||||
import ch.psi.utils.IO as IO
|
||||
import ch.psi.utils.Chrono as Chrono
|
||||
import ch.psi.utils.Folder as Folder
|
||||
import ch.psi.utils.Histogram as Histogram
|
||||
import ch.psi.utils.History as History
|
||||
import ch.psi.utils.Condition as Condition
|
||||
import ch.psi.utils.ArrayProperties as ArrayProperties
|
||||
import ch.psi.utils.Audio as Audio
|
||||
import ch.psi.utils.BitMask as BitMask
|
||||
import ch.psi.utils.Config as Config
|
||||
import ch.psi.utils.Inventory as Inventory
|
||||
import ch.psi.utils.DataAPI as DataAPI
|
||||
import ch.psi.utils.DispatcherAPI as DispatcherAPI
|
||||
import ch.psi.utils.EpicsBootInfoAPI as EpicsBootInfoAPI
|
||||
import ch.psi.utils.Mail as Mail
|
||||
import ch.psi.utils.Posix as Posix
|
||||
import ch.psi.utils.ProcessFactory as ProcessFactory
|
||||
import ch.psi.utils.Range as Range
|
||||
import ch.psi.utils.Reflection as Reflection
|
||||
import ch.psi.utils.Serializer as Serializer
|
||||
import ch.psi.utils.Windows as Windows
|
||||
import ch.psi.utils.NumberComparator as NumberComparator
|
||||
|
||||
|
||||
import ch.psi.pshell.core.CommandSource as CommandSource
|
||||
import ch.psi.pshell.core.ContextAdapter as ContextListener
|
||||
import ch.psi.pshell.core.Context
|
||||
import ch.psi.pshell.core.InlineDevice as InlineDevice
|
||||
|
||||
import ch.psi.pshell.data.DataSlice as DataSlice
|
||||
import ch.psi.pshell.data.PlotDescriptor as PlotDescriptor
|
||||
import ch.psi.pshell.data.Table as Table
|
||||
import ch.psi.pshell.data.Provider as Provider
|
||||
import ch.psi.pshell.data.ProviderHDF5 as ProviderHDF5
|
||||
import ch.psi.pshell.data.ProviderText as ProviderText
|
||||
import ch.psi.pshell.data.ProviderCSV as ProviderCSV
|
||||
import ch.psi.pshell.data.ProviderFDA as ProviderFDA
|
||||
import ch.psi.pshell.data.Converter as DataConverter
|
||||
import ch.psi.pshell.data.Layout as Layout
|
||||
import ch.psi.pshell.data.LayoutBase as LayoutBase
|
||||
import ch.psi.pshell.data.LayoutDefault as LayoutDefault
|
||||
import ch.psi.pshell.data.LayoutTable as LayoutTable
|
||||
import ch.psi.pshell.data.LayoutFDA as LayoutFDA
|
||||
import ch.psi.pshell.data.LayoutSF as LayoutSF
|
||||
|
||||
import ch.psi.pshell.device.Device as Device
|
||||
import ch.psi.pshell.device.DeviceBase as DeviceBase
|
||||
import ch.psi.pshell.device.GenericDevice as GenericDevice
|
||||
import ch.psi.pshell.device.DeviceConfig as DeviceConfig
|
||||
import ch.psi.pshell.device.PositionerConfig as PositionerConfig
|
||||
import ch.psi.pshell.device.RegisterConfig as RegisterConfig
|
||||
import ch.psi.pshell.device.ReadonlyProcessVariableConfig as ReadonlyProcessVariableConfig
|
||||
import ch.psi.pshell.device.ProcessVariableConfig as ProcessVariableConfig
|
||||
import ch.psi.pshell.device.MotorConfig as MotorConfig
|
||||
import ch.psi.pshell.device.Register as Register
|
||||
import ch.psi.pshell.device.RegisterBase as RegisterBase
|
||||
import ch.psi.pshell.device.ProcessVariableBase as ProcessVariableBase
|
||||
import ch.psi.pshell.device.ControlledVariableBase as ControlledVariableBase
|
||||
import ch.psi.pshell.device.PositionerBase as PositionerBase
|
||||
import ch.psi.pshell.device.MasterPositioner as MasterPositioner
|
||||
import ch.psi.pshell.device.MotorBase as MotorBase
|
||||
import ch.psi.pshell.device.DiscretePositionerBase as DiscretePositionerBase
|
||||
import ch.psi.pshell.device.MotorGroupBase as MotorGroupBase
|
||||
import ch.psi.pshell.device.MotorGroupDiscretePositioner as MotorGroupDiscretePositioner
|
||||
import ch.psi.pshell.device.ReadonlyRegisterBase as ReadonlyRegisterBase
|
||||
import ch.psi.pshell.device.ReadonlyAsyncRegisterBase as ReadonlyAsyncRegisterBase
|
||||
import ch.psi.pshell.device.Register as Register
|
||||
import ch.psi.pshell.device.Register.RegisterArray as RegisterArray
|
||||
import ch.psi.pshell.device.Register.RegisterNumber as RegisterNumber
|
||||
import ch.psi.pshell.device.Register.RegisterBoolean as RegisterBoolean
|
||||
import ch.psi.pshell.device.RegisterCache as RegisterCache
|
||||
import ch.psi.pshell.device.ReadonlyRegister.ReadonlyRegisterArray as ReadonlyRegisterArray
|
||||
import ch.psi.pshell.device.ReadonlyRegister.ReadonlyRegisterMatrix as ReadonlyRegisterMatrix
|
||||
import ch.psi.pshell.device.DummyPositioner as DummyPositioner
|
||||
import ch.psi.pshell.device.DummyMotor as DummyMotor
|
||||
import ch.psi.pshell.device.DummyRegister as DummyRegister
|
||||
import ch.psi.pshell.device.Timestamp as Timestamp
|
||||
import ch.psi.pshell.device.Interlock as Interlock
|
||||
import ch.psi.pshell.device.Readable as Readable
|
||||
import ch.psi.pshell.device.Readable.ReadableArray as ReadableArray
|
||||
import ch.psi.pshell.device.Readable.ReadableMatrix as ReadableMatrix
|
||||
import ch.psi.pshell.device.Readable.ReadableCalibratedArray as ReadableCalibratedArray
|
||||
import ch.psi.pshell.device.Readable.ReadableCalibratedMatrix as ReadableCalibratedMatrix
|
||||
import ch.psi.pshell.device.ArrayCalibration as ArrayCalibration
|
||||
import ch.psi.pshell.device.MatrixCalibration as MatrixCalibration
|
||||
import ch.psi.pshell.device.Writable as Writable
|
||||
import ch.psi.pshell.device.Writable.WritableArray as WritableArray
|
||||
import ch.psi.pshell.device.Stoppable as Stoppable
|
||||
import ch.psi.pshell.device.Averager as Averager
|
||||
import ch.psi.pshell.device.ArrayAverager as ArrayAverager
|
||||
import ch.psi.pshell.device.Delta as Delta
|
||||
import ch.psi.pshell.device.DeviceAdapter as DeviceListener
|
||||
import ch.psi.pshell.device.ReadbackDeviceAdapter as ReadbackDeviceListener
|
||||
import ch.psi.pshell.device.MotorAdapter as MotorListener
|
||||
import ch.psi.pshell.device.MoveMode as MoveMode
|
||||
import ch.psi.pshell.device.SettlingCondition as SettlingCondition
|
||||
import ch.psi.pshell.device.HistogramGenerator as HistogramGenerator
|
||||
|
||||
import ch.psi.pshell.epics.Epics as Epics
|
||||
import ch.psi.pshell.epics.EpicsScan as EpicsScan
|
||||
import ch.psi.pshell.epics.ChannelSettlingCondition as ChannelSettlingCondition
|
||||
import ch.psi.pshell.epics.AreaDetector as AreaDetector
|
||||
import ch.psi.pshell.epics.BinaryPositioner as BinaryPositioner
|
||||
import ch.psi.pshell.epics.ChannelByte as ChannelByte
|
||||
import ch.psi.pshell.epics.ChannelByteArray as ChannelByteArray
|
||||
import ch.psi.pshell.epics.ChannelByteMatrix as ChannelByteMatrix
|
||||
import ch.psi.pshell.epics.ChannelDouble as ChannelDouble
|
||||
import ch.psi.pshell.epics.ChannelDoubleArray as ChannelDoubleArray
|
||||
import ch.psi.pshell.epics.ChannelDoubleMatrix as ChannelDoubleMatrix
|
||||
import ch.psi.pshell.epics.ChannelFloat as ChannelFloat
|
||||
import ch.psi.pshell.epics.ChannelFloatArray as ChannelFloatArray
|
||||
import ch.psi.pshell.epics.ChannelFloatMatrix as ChannelFloatMatrix
|
||||
import ch.psi.pshell.epics.ChannelInteger as ChannelInteger
|
||||
import ch.psi.pshell.epics.ChannelIntegerArray as ChannelIntegerArray
|
||||
import ch.psi.pshell.epics.ChannelIntegerMatrix as ChannelIntegerMatrix
|
||||
import ch.psi.pshell.epics.ChannelShort as ChannelShort
|
||||
import ch.psi.pshell.epics.ChannelShortArray as ChannelShortArray
|
||||
import ch.psi.pshell.epics.ChannelShortMatrix as ChannelShortMatrix
|
||||
import ch.psi.pshell.epics.ChannelString as ChannelString
|
||||
import ch.psi.pshell.epics.ControlledVariable as ControlledVariable
|
||||
import ch.psi.pshell.epics.DiscretePositioner as DiscretePositioner
|
||||
import ch.psi.pshell.epics.GenericChannel as GenericChannel
|
||||
import ch.psi.pshell.epics.GenericArray as GenericArray
|
||||
import ch.psi.pshell.epics.GenericMatrix as GenericMatrix
|
||||
import ch.psi.pshell.epics.Manipulator as Manipulator
|
||||
import ch.psi.pshell.epics.Motor as EpicsMotor
|
||||
import ch.psi.pshell.epics.Positioner as Positioner
|
||||
import ch.psi.pshell.epics.ProcessVariable as ProcessVariable
|
||||
import ch.psi.pshell.epics.ReadonlyProcessVariable as ReadonlyProcessVariable
|
||||
import ch.psi.pshell.epics.Scaler as Scaler
|
||||
import ch.psi.pshell.epics.Scienta as Scienta
|
||||
import ch.psi.pshell.epics.Slit as Slit
|
||||
import ch.psi.pshell.epics.AreaDetectorSource as AreaDetectorSource
|
||||
import ch.psi.pshell.epics.ArraySource as ArraySource
|
||||
import ch.psi.pshell.epics.ByteArraySource as ByteArraySource
|
||||
import ch.psi.pshell.epics.PsiCamera as PsiCamera
|
||||
import ch.psi.pshell.epics.CAS as CAS
|
||||
|
||||
import ch.psi.pshell.serial.SerialPortDevice as SerialPortDevice
|
||||
import ch.psi.pshell.serial.TcpDevice as TcpDevice
|
||||
import ch.psi.pshell.serial.UdpDevice as UdpDevice
|
||||
import ch.psi.pshell.serial.SerialPortDeviceConfig as SerialPortDeviceConfig
|
||||
import ch.psi.pshell.serial.SocketDeviceConfig as SocketDeviceConfig
|
||||
|
||||
import ch.psi.pshell.modbus.ModbusTCP as ModbusTCP
|
||||
import ch.psi.pshell.modbus.ModbusUDP as ModbusUDP
|
||||
import ch.psi.pshell.modbus.ModbusSerial as ModbusSerial
|
||||
import ch.psi.pshell.modbus.AnalogInput as ModbusAI
|
||||
import ch.psi.pshell.modbus.AnalogInputArray as ModbusMAI
|
||||
import ch.psi.pshell.modbus.AnalogOutput as ModbusAO
|
||||
import ch.psi.pshell.modbus.AnalogOutputArray as ModbusMAO
|
||||
import ch.psi.pshell.modbus.DigitalInput as ModbusDO
|
||||
import ch.psi.pshell.modbus.DigitalInputArray as ModbusMDI
|
||||
import ch.psi.pshell.modbus.DigitalOutput as ModbusDO
|
||||
import ch.psi.pshell.modbus.DigitalOutputArray as ModbusMDO
|
||||
import ch.psi.pshell.modbus.Register as ModbusReg
|
||||
import ch.psi.pshell.modbus.ReadonlyProcessVariable as ModbusROPV
|
||||
import ch.psi.pshell.modbus.ProcessVariable as ModbusPV
|
||||
import ch.psi.pshell.modbus.ControlledVariable as ModbusCB
|
||||
import ch.psi.pshell.modbus.ModbusDeviceConfig as ModbusDeviceConfig
|
||||
|
||||
import ch.psi.pshell.imaging.Source as Source
|
||||
import ch.psi.pshell.imaging.SourceBase as SourceBase
|
||||
import ch.psi.pshell.imaging.DirectSource as DirectSource
|
||||
import ch.psi.pshell.imaging.RegisterArraySource as RegisterArraySource
|
||||
import ch.psi.pshell.imaging.RegisterMatrixSource as RegisterMatrixSource
|
||||
import ch.psi.pshell.imaging.ImageListener as ImageListener
|
||||
import ch.psi.pshell.imaging.ImageMeasurement as ImageMeasurement
|
||||
import ch.psi.pshell.imaging.CameraSource as CameraSource
|
||||
import ch.psi.pshell.imaging.ColormapAdapter as ColormapAdapter
|
||||
import ch.psi.pshell.imaging.FileSource as FileSource
|
||||
import ch.psi.pshell.imaging.MjpegSource as MjpegSource
|
||||
import ch.psi.pshell.imaging.Webcam as Webcam
|
||||
import ch.psi.pshell.imaging.Filter as Filter
|
||||
import ch.psi.pshell.imaging.Utils as ImagingUtils
|
||||
import ch.psi.pshell.imaging.Overlay as Overlay
|
||||
import ch.psi.pshell.imaging.Overlays as Overlays
|
||||
import ch.psi.pshell.imaging.Pen as Pen
|
||||
import ch.psi.pshell.imaging.Data as Data
|
||||
import ch.psi.pshell.imaging.Colormap as Colormap
|
||||
import ch.psi.pshell.imaging.Renderer as Renderer
|
||||
|
||||
|
||||
import ch.psi.pshell.plot.Plot as Plot
|
||||
import ch.psi.pshell.plot.Plot.AxisId as AxisId
|
||||
import ch.psi.pshell.plot.LinePlot.Style as LinePlotStyle
|
||||
import ch.psi.pshell.plot.RangeSelectionPlot as RangeSelectionPlot
|
||||
import ch.psi.pshell.plot.RangeSelectionPlot.RangeSelectionPlotListener as RangeSelectionPlotListener
|
||||
import ch.psi.pshell.plot.LinePlot as LinePlot
|
||||
import ch.psi.pshell.plot.MatrixPlot as MatrixPlot
|
||||
import ch.psi.pshell.plot.TimePlot as TimePlot
|
||||
import ch.psi.pshell.plot.SlicePlot as SlicePlot
|
||||
|
||||
import ch.psi.pshell.plot.LinePlotJFree as LinePlotJFree
|
||||
import ch.psi.pshell.plot.MatrixPlotJFree as MatrixPlotJFree
|
||||
import ch.psi.pshell.plot.TimePlotJFree as TimePlotJFree
|
||||
import ch.psi.pshell.plot.SlicePlotDefault as SlicePlotDefault
|
||||
|
||||
import ch.psi.pshell.plot.LinePlotSeries as LinePlotSeries
|
||||
import ch.psi.pshell.plot.LinePlotErrorSeries as LinePlotErrorSeries
|
||||
import ch.psi.pshell.plot.MatrixPlotSeries as MatrixPlotSeries
|
||||
import ch.psi.pshell.plot.TimePlotSeries as TimePlotSeries
|
||||
import ch.psi.pshell.plot.SlicePlotSeries as SlicePlotSeries
|
||||
|
||||
import ch.psi.pshell.scan.ScanBase as ScanBase
|
||||
import ch.psi.pshell.scan.LineScan
|
||||
import ch.psi.pshell.scan.ContinuousScan
|
||||
import ch.psi.pshell.scan.AreaScan
|
||||
import ch.psi.pshell.scan.VectorScan
|
||||
import ch.psi.pshell.scan.ManualScan
|
||||
import ch.psi.pshell.scan.HardwareScan
|
||||
import ch.psi.pshell.scan.RegionScan
|
||||
import ch.psi.pshell.scan.TimeScan
|
||||
import ch.psi.pshell.scan.MonitorScan
|
||||
import ch.psi.pshell.scan.BinarySearch
|
||||
import ch.psi.pshell.scan.HillClimbingSearch
|
||||
import ch.psi.pshell.scan.ScanResult
|
||||
import ch.psi.pshell.scan.Otf as Otf
|
||||
import ch.psi.pshell.scan.ScanCallbacks as ScanCallbacks
|
||||
|
||||
import ch.psi.pshell.crlogic.CrlogicPositioner as CrlogicPositioner
|
||||
import ch.psi.pshell.crlogic.CrlogicSensor as CrlogicSensor
|
||||
|
||||
import ch.psi.pshell.scan.ScanAbortedException as ScanAbortedException
|
||||
|
||||
import ch.psi.pshell.bs.BsScan
|
||||
import ch.psi.pshell.bs.Stream as Stream
|
||||
import ch.psi.pshell.bs.Provider as Provider
|
||||
import ch.psi.pshell.bs.Dispatcher as Dispatcher
|
||||
import ch.psi.pshell.bs.Scalar as Scalar
|
||||
import ch.psi.pshell.bs.Waveform as Waveform
|
||||
import ch.psi.pshell.bs.Matrix as Matrix
|
||||
import ch.psi.pshell.bs.StreamCamera as StreamCamera
|
||||
import ch.psi.pshell.bs.CameraServer as CameraServer
|
||||
import ch.psi.pshell.bs.PipelineServer as PipelineServer
|
||||
import ch.psi.pshell.bs.ProviderConfig as ProviderConfig
|
||||
import ch.psi.pshell.bs.StreamConfig as StreamConfig
|
||||
import ch.psi.pshell.bs.ScalarConfig as ScalarConfig
|
||||
import ch.psi.pshell.bs.WaveformConfig as WaveformConfig
|
||||
import ch.psi.pshell.bs.MatrixConfig as MatrixConfig
|
||||
|
||||
import ch.psi.pshell.detector.DetectorConfig as DetectorConfig
|
||||
|
||||
import ch.psi.pshell.ui.App as App
|
||||
|
||||
import ch.psi.pshell.scripting.ViewPreference as Preference
|
||||
import ch.psi.pshell.scripting.ScriptUtils as ScriptUtils
|
||||
import ch.psi.pshell.scripting.ScriptType as ScriptType
|
||||
|
||||
from ch.psi.pshell.device.Record import *
|
||||
from javax.swing.SwingUtilities import invokeLater, invokeAndWait
|
||||
|
||||
import org.jfree.ui.RectangleAnchor as RectangleAnchor
|
||||
import org.jfree.ui.TextAnchor as TextAnchor
|
||||
|
||||
|
||||
def string_to_obj(o):
|
||||
if is_string(o):
|
||||
o=str(o)
|
||||
if "://" in o:
|
||||
return InlineDevice(o)
|
||||
ret = get_context().getInterpreterVariable(o)
|
||||
if ret is None:
|
||||
try:
|
||||
return get_context().scriptManager.evalBackground(o).result
|
||||
except:
|
||||
return None
|
||||
return ret
|
||||
elif is_list(o):
|
||||
ret = []
|
||||
for i in o:
|
||||
ret.append(string_to_obj(i))
|
||||
return ret
|
||||
return o
|
||||
|
||||
def json_to_obj(o):
|
||||
if is_string(o):
|
||||
import json
|
||||
return json.loads(o)
|
||||
elif is_list(o):
|
||||
ret = []
|
||||
for i in o:
|
||||
ret.append(json_to_obj(i))
|
||||
return ret
|
||||
return o
|
||||
|
||||
###################################################################################################
|
||||
#Scan classes
|
||||
###################################################################################################
|
||||
|
||||
def __no_args(f):
|
||||
ret = f.func_code.co_argcount
|
||||
return (ret-1) if type(f)==PyMethod else ret
|
||||
|
||||
def __before_readout(scan, pos):
|
||||
try:
|
||||
if scan.before_read != None:
|
||||
args = __no_args(scan.before_read)
|
||||
if args==0: scan.before_read()
|
||||
elif args==1: scan.before_read(pos.tolist())
|
||||
elif args==2: scan.before_read(pos.tolist(), scan)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def __after_readout(scan, record):
|
||||
try:
|
||||
if scan.after_read != None:
|
||||
args = __no_args(scan.after_read)
|
||||
if args==0: scan.after_read()
|
||||
elif args==1: scan.after_read(record)
|
||||
elif args==2: scan.after_read(record, scan)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def __before_pass(scan, num_pass):
|
||||
try:
|
||||
if scan.before_pass != None:
|
||||
args = __no_args(scan.before_pass)
|
||||
if args==0:scan.before_pass()
|
||||
elif args==1:scan.before_pass(num_pass)
|
||||
elif args==2:scan.before_pass(num_pass, scan)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def __after_pass(scan, num_pass):
|
||||
try:
|
||||
if scan.after_pass != None:
|
||||
args = __no_args(scan.after_pass)
|
||||
if args==0:scan.after_pass()
|
||||
elif args==1:scan.after_pass(num_pass)
|
||||
elif args==2:scan.after_pass(num_pass, scan)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def __before_region(scan, num_region):
|
||||
try:
|
||||
if scan.before_region != None:
|
||||
args = __no_args(scan.before_region)
|
||||
if args==0:scan.before_region()
|
||||
elif args==1:scan.before_region(num_region)
|
||||
elif args==2:scan.before_region(num_region, scan)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
class LineScan(ch.psi.pshell.scan.LineScan):
|
||||
def onBeforeReadout(self, pos): __before_readout(self, pos)
|
||||
def onAfterReadout(self, rec): __after_readout(self, rec)
|
||||
def onBeforePass(self, num): __before_pass(self, num)
|
||||
def onAfterPass(self, num): __after_pass(self, num)
|
||||
|
||||
class AreaScan(ch.psi.pshell.scan.AreaScan):
|
||||
def onBeforeReadout(self, pos): __before_readout(self, pos)
|
||||
def onAfterReadout(self, rec): __after_readout(self, rec)
|
||||
def onBeforePass(self, num): __before_pass(self, num)
|
||||
def onAfterPass(self, num): __after_pass(self, num)
|
||||
|
||||
class RegionScan(ch.psi.pshell.scan.RegionScan):
|
||||
def onBeforeReadout(self, pos): __before_readout(self, pos)
|
||||
def onAfterReadout(self, rec): __after_readout(self, rec)
|
||||
def onBeforePass(self, num): __before_pass(self, num)
|
||||
def onAfterPass(self, num): __after_pass(self, num)
|
||||
def onBeforeRegion(self, num): __before_region(self,num)
|
||||
|
||||
class VectorScan(ch.psi.pshell.scan.VectorScan):
|
||||
def onBeforeReadout(self, pos): __before_readout(self, pos)
|
||||
def onAfterReadout(self, rec): __after_readout(self, rec)
|
||||
def onBeforePass(self, num): __before_pass(self, num)
|
||||
def onAfterPass(self, num): __after_pass(self, num)
|
||||
|
||||
class ContinuousScan(ch.psi.pshell.scan.ContinuousScan):
|
||||
def onBeforeReadout(self, pos): __before_readout(self, pos)
|
||||
def onAfterReadout(self, rec): __after_readout(self, rec)
|
||||
def onBeforePass(self, num): __before_pass(self, num)
|
||||
def onAfterPass(self, num): __after_pass(self, num)
|
||||
|
||||
class TimeScan(ch.psi.pshell.scan.TimeScan):
|
||||
def onBeforeReadout(self, pos): __before_readout(self, pos)
|
||||
def onAfterReadout(self, rec): __after_readout(self, rec)
|
||||
def onBeforePass(self, num): __before_pass(self, num)
|
||||
def onAfterPass(self, num): __after_pass(self, num)
|
||||
|
||||
class MonitorScan(ch.psi.pshell.scan.MonitorScan):
|
||||
def onBeforeReadout(self, pos): __before_readout(self, pos)
|
||||
def onAfterReadout(self, rec): __after_readout(self, rec)
|
||||
def onBeforePass(self, num): __before_pass(self, num)
|
||||
def onAfterPass(self, num): __after_pass(self, num)
|
||||
|
||||
class BsScan(ch.psi.pshell.bs.BsScan):
|
||||
def onBeforeReadout(self, pos): __before_readout(self, pos)
|
||||
def onAfterReadout(self, rec): __after_readout(self, rec)
|
||||
def onBeforePass(self, num): __before_pass(self, num)
|
||||
def onAfterPass(self, num): __after_pass(self, num)
|
||||
|
||||
class ManualScan (ch.psi.pshell.scan.ManualScan):
|
||||
def __init__(self, writables, readables, start = None, end = None, steps = None, relative = False, dimensions = None, **pars):
|
||||
ch.psi.pshell.scan.ManualScan.__init__(self, writables, readables, start, end, steps, relative)
|
||||
self._dimensions = dimensions
|
||||
processScanPars(self, pars)
|
||||
|
||||
def append(self,setpoints, positions, values, timestamps=None):
|
||||
ch.psi.pshell.scan.ManualScan.append(self, to_array(setpoints), to_array(positions), to_array(values), None if (timestamps is None) else to_array(timestamps))
|
||||
|
||||
def getDimensions(self):
|
||||
if self._dimensions == None:
|
||||
return ch.psi.pshell.scan.ManualScan.getDimensions(self)
|
||||
else:
|
||||
return self._dimensions
|
||||
|
||||
class BinarySearch(ch.psi.pshell.scan.BinarySearch):
|
||||
def onBeforeReadout(self, pos): __before_readout(self, pos)
|
||||
def onAfterReadout(self, rec): __after_readout(self, rec)
|
||||
|
||||
class HillClimbingSearch(ch.psi.pshell.scan.HillClimbingSearch):
|
||||
def onBeforeReadout(self, pos): __before_readout(self, pos)
|
||||
def onAfterReadout(self, rec): __after_readout(self, rec)
|
||||
|
||||
def processScanPars(scan, pars):
|
||||
scan.before_read = pars.pop("before_read",None)
|
||||
scan.after_read = pars.pop("after_read",None)
|
||||
scan.before_pass = pars.pop("before_pass",None)
|
||||
scan.after_pass = pars.pop("after_pass",None)
|
||||
scan.before_region= pars.pop("before_region",None)
|
||||
scan.setPlotTitle(pars.pop("title",None))
|
||||
scan.setHidden(pars.pop("hidden",False))
|
||||
scan.setSettleTimeout (pars.pop("settle_timeout",ScanBase.getScansSettleTimeout()))
|
||||
scan.setUseWritableReadback (pars.pop("use_readback",ScanBase.getScansUseWritableReadback()))
|
||||
scan.setInitialMove(pars.pop("initial_move",ScanBase.getScansTriggerInitialMove()))
|
||||
scan.setParallelPositioning(pars.pop("parallel_positioning",ScanBase.getScansParallelPositioning()))
|
||||
scan.setAbortOnReadableError(pars.pop("abort_on_error",ScanBase.getAbortScansOnReadableError()))
|
||||
scan.setRestorePosition (pars.pop("restore_position",ScanBase.getRestorePositionOnRelativeScans()))
|
||||
scan.setCheckPositions(pars.pop("check_positions",ScanBase.getScansCheckPositions()))
|
||||
scan.setMonitors(to_list(string_to_obj(pars.pop("monitors",None))))
|
||||
scan.setSnaps(to_list(string_to_obj(pars.pop("snaps",None))))
|
||||
scan.setDiags(to_list(string_to_obj(pars.pop("diags",None))))
|
||||
scan.setMeta(pars.pop("meta",None))
|
||||
get_context().setCommandPars(scan, pars)
|
||||
|
||||
|
||||
|
||||
###################################################################################################
|
||||
#Simple EPICS Channel abstraction
|
||||
###################################################################################################
|
||||
|
||||
def create_channel(name, type=None, size=None):
|
||||
return Epics.newChannel(name, Epics.getChannelType(type), size)
|
||||
|
||||
#Not using finalizer: closing channels in garbage collection generate errors
|
||||
class Channel(java.beans.PropertyChangeListener, Writable, Readable, DeviceBase):
|
||||
def __init__(self, channel_name, type = None, size = None, callback=None, alias = None, monitored=None, name = None):
|
||||
""" Create an object that encapsulates an Epics PV connection.
|
||||
Args:
|
||||
channel_name(str):name of the channel
|
||||
type(str, optional): type of PV. By default gets the PV standard field type.
|
||||
Scalar values: 'b', 'i', 'l', 'd', 's'.
|
||||
Array values: '[b', '[i,', '[l', '[d', '[s'.
|
||||
size(int, optional): the size of the channel
|
||||
callback(function, optional): The monitor callback.
|
||||
alias(str): name to be used on scans.
|
||||
"""
|
||||
super(DeviceBase, self).__init__(name if (name is not None) else channel_name.replace(":","_").replace(".","_"))
|
||||
self.channel = create_channel(channel_name, type, size)
|
||||
self.callback = callback
|
||||
self._alias = alias
|
||||
if monitored is not None:self.setMonitored(monitored)
|
||||
self.initialize()
|
||||
|
||||
def get_channel_name(self):
|
||||
"""Return the name of the channel.
|
||||
"""
|
||||
return self.channel.name
|
||||
|
||||
def get_size(self):
|
||||
"""Return the size of the channel.
|
||||
"""
|
||||
return self.channel.size
|
||||
|
||||
def set_size(self, size):
|
||||
"""Set the size of the channel.
|
||||
"""
|
||||
self.channel.size = size
|
||||
|
||||
def is_connected(self):
|
||||
"""Return True if channel is connected.
|
||||
"""
|
||||
return self.channel.connected
|
||||
|
||||
def doSetMonitored(self, value):
|
||||
self.channel.monitored = value
|
||||
if (value):
|
||||
self.channel.addPropertyChangeListener(self)
|
||||
else:
|
||||
self.channel.removePropertyChangeListener(self)
|
||||
|
||||
|
||||
def is_monitored(self):
|
||||
"""Return True if channel is monitored
|
||||
"""
|
||||
return self.channel.monitored
|
||||
|
||||
def set_monitored(self, value):
|
||||
"""Set a channel monitor to trigger the callback function defined in the constructor.
|
||||
"""
|
||||
self.setMonitored(value)
|
||||
|
||||
def propertyChange(self, pce):
|
||||
if pce.getPropertyName() == "value":
|
||||
value=pce.getNewValue()
|
||||
self.setCache(value, None)
|
||||
if self.callback is not None:
|
||||
self.callback(value)
|
||||
|
||||
def put(self, value, timeout=None):
|
||||
"""Write to channel and wait value change. In the case of a timeout throws a TimeoutException.
|
||||
Args:
|
||||
value(obj): value to be written
|
||||
timeout(float, optional): timeout in seconds. If none waits forever.
|
||||
"""
|
||||
if (timeout==None):
|
||||
self.channel.setValue(value)
|
||||
else:
|
||||
self.channel.setValueAsync(value).get(int(timeout*1000), java.util.concurrent.TimeUnit.MILLISECONDS)
|
||||
self.setCache(value, None)
|
||||
|
||||
def putq(self, value):
|
||||
"""Write to channel and don't wait.
|
||||
"""
|
||||
self.channel.setValueNoWait(value)
|
||||
|
||||
def get(self, force = False):
|
||||
"""Get channel value.
|
||||
"""
|
||||
ret = self.channel.getValue(force)
|
||||
self.setCache(ret, None)
|
||||
return ret
|
||||
|
||||
def wait_for_value(self, value, timeout=None, comparator=None):
|
||||
"""Wait channel to reach a value, using a given comparator. In the case of a timeout throws a TimeoutException.
|
||||
Args:
|
||||
value(obj): value to be verified.
|
||||
timeout(float, optional): timeout in seconds. If None waits forever.
|
||||
comparator (java.util.Comparator, optional). If None, uses Object.equals.
|
||||
"""
|
||||
if comparator is None:
|
||||
if timeout is None:
|
||||
self.channel.waitForValue(value)
|
||||
else:
|
||||
self.channel.waitForValue(value, int(timeout*1000))
|
||||
self.setCache(value, None)
|
||||
else:
|
||||
if timeout is None:
|
||||
self.channel.waitForValue(value, comparator)
|
||||
else:
|
||||
self.channel.waitForValue(value, comparator, int(timeout*1000))
|
||||
|
||||
def doUpdate(self):
|
||||
self.get()
|
||||
|
||||
def close(self):
|
||||
"""Close the channel.
|
||||
"""
|
||||
Epics.closeChannel(self.channel)
|
||||
|
||||
def setAlias(self, alias):
|
||||
self._alias = alias
|
||||
|
||||
def getAlias(self):
|
||||
return self._alias if self._alias else self.getName()
|
||||
|
||||
def write(self, value):
|
||||
self.put(value)
|
||||
|
||||
def read(self):
|
||||
return self.get()
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.close()
|
||||
1895
script/Lib/builtin_functions.py
Normal file
1895
script/Lib/builtin_functions.py
Normal file
File diff suppressed because it is too large
Load Diff
174
script/Lib/builtin_utils.py
Normal file
174
script/Lib/builtin_utils.py
Normal file
@@ -0,0 +1,174 @@
|
||||
import sys
|
||||
import time
|
||||
import math
|
||||
import os.path
|
||||
from operator import add, mul, sub, truediv
|
||||
from time import sleep
|
||||
from array import array
|
||||
import jarray
|
||||
|
||||
import java.lang.Class as Class
|
||||
import java.lang.Object as Object
|
||||
import java.lang.System as System
|
||||
import java.beans.PropertyChangeListener
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.List
|
||||
import java.util.ArrayList
|
||||
import java.lang.reflect.Array
|
||||
import java.lang.Thread
|
||||
import java.awt.image.BufferedImage as BufferedImage
|
||||
import java.awt.Color as Color
|
||||
import java.awt.Point as Point
|
||||
import java.awt.Dimension as Dimension
|
||||
import java.awt.Rectangle as Rectangle
|
||||
import java.awt.Font as Font
|
||||
import org.python.core.PyArray as PyArray
|
||||
import org.python.core.PyFunction as PyFunction
|
||||
import org.python.core.PyMethod as PyMethod
|
||||
import org.python.core.PyGenerator as PyGenerator
|
||||
|
||||
import java.lang.Boolean
|
||||
import java.lang.Integer
|
||||
import java.lang.Float
|
||||
import java.lang.Double
|
||||
import java.lang.Short
|
||||
import java.lang.Byte
|
||||
import java.lang.Long
|
||||
import java.lang.String
|
||||
|
||||
import ch.psi.pshell.core.Context
|
||||
import ch.psi.pshell.scripting.ScriptUtils as ScriptUtils
|
||||
import ch.psi.utils.Convert as Convert
|
||||
import ch.psi.utils.Arr as Arr
|
||||
|
||||
|
||||
###################################################################################################
|
||||
#Type conversion and checking
|
||||
###################################################################################################
|
||||
|
||||
def to_array(obj, type = None, primitive = True):
|
||||
"""Convert Python list to Java array.
|
||||
|
||||
Args:
|
||||
obj(list): Original data.
|
||||
type(str): array type 'b' = byte, 'h' = short, 'i' = int, 'l' = long, 'f' = float, 'd' = double,
|
||||
'c' = char, 'z' = boolean, 's' = String, 'o' = Object
|
||||
Returns:
|
||||
Java array.
|
||||
"""
|
||||
if obj is None:
|
||||
return None
|
||||
if type is None:
|
||||
type = 'o'
|
||||
enforceArrayType=False
|
||||
else:
|
||||
enforceArrayType=True
|
||||
if type[0] == '[':
|
||||
type = type[1:]
|
||||
element_type = ScriptUtils.getPrimitiveType(type) if primitive else ScriptUtils.getType(type)
|
||||
|
||||
def convert_1d_array(obj):
|
||||
try:
|
||||
if primitive:
|
||||
#If primitive, first try converting with jarray.array
|
||||
return jarray.array(obj,type)
|
||||
except:
|
||||
pass
|
||||
|
||||
if type == 'c':
|
||||
ret = java.lang.reflect.Array.newInstance(element_type,len(obj))
|
||||
for i in range(len(obj)): ret[i] = chr(obj[i])
|
||||
return ret
|
||||
if type == 'z':
|
||||
ret = java.lang.reflect.Array.newInstance(element_type,len(obj))
|
||||
for i in range(len(obj)):
|
||||
ret[i]= True if obj[i] else False
|
||||
return ret
|
||||
if type == 'o':
|
||||
ret = java.lang.reflect.Array.newInstance(element_type,len(obj))
|
||||
for i in range(len(obj)):
|
||||
ret[i]= obj[i]
|
||||
return ret
|
||||
if type == "s":
|
||||
return Convert.toStringArray(obj)
|
||||
if primitive:
|
||||
ret = Convert.toPrimitiveArray(obj, element_type)
|
||||
else:
|
||||
ret = java.lang.reflect.Array.newInstance(element_type,len(obj))
|
||||
for i in range(len(obj)): ret[i] = Convert.toType(obj[i],element_type)
|
||||
return ret
|
||||
|
||||
if isinstance(obj,PyArray):
|
||||
if enforceArrayType:
|
||||
if Arr.getComponentType(obj) != element_type:
|
||||
rank = Arr.getRank(obj)
|
||||
if (rank== 1):
|
||||
obj=convert_1d_array(obj)
|
||||
elif (rank>1):
|
||||
pars, aux = [element_type], obj
|
||||
for i in range(rank):
|
||||
pars.append(len(aux))
|
||||
aux = aux[0]
|
||||
ret = java.lang.reflect.Array.newInstance(*pars)
|
||||
for i in range(len(obj)):
|
||||
ret[i]=to_array(obj[i], type)
|
||||
obj = ret
|
||||
elif is_list(obj):
|
||||
if type=='o':
|
||||
ret = java.lang.reflect.Array.newInstance(element_type, len(obj))
|
||||
for i in range (len(obj)):
|
||||
if is_list(obj[i]) or isinstance(obj[i],PyArray):
|
||||
ret[i] = to_array(obj[i],type)
|
||||
else:
|
||||
ret[i] = obj[i]
|
||||
obj=ret
|
||||
elif len(obj)>0 and (is_list(obj[0]) or isinstance(obj[0],PyArray)):
|
||||
pars, aux = [element_type], obj
|
||||
while len(aux)>0 and (is_list(aux[0]) or isinstance(aux[0],PyArray)):
|
||||
pars.append(len(aux))
|
||||
aux = aux[0]
|
||||
pars.append(0)
|
||||
ret = java.lang.reflect.Array.newInstance(*pars)
|
||||
for i in range(len(obj)):
|
||||
ret[i]=to_array(obj[i], type)
|
||||
obj=ret
|
||||
else:
|
||||
obj= convert_1d_array(obj)
|
||||
return obj
|
||||
|
||||
def to_list(obj):
|
||||
"""Convert an object into a Python List.
|
||||
|
||||
Args:
|
||||
obj(tuple or array or List): Original data.
|
||||
|
||||
Returns:
|
||||
List.
|
||||
"""
|
||||
if obj is None:
|
||||
return None
|
||||
if isinstance(obj,tuple) or isinstance(obj,java.util.List) :
|
||||
return list(obj)
|
||||
#if isinstance(obj,PyArray):
|
||||
# return obj.tolist()
|
||||
if not isinstance(obj,list):
|
||||
return [obj,]
|
||||
return obj
|
||||
|
||||
def is_list(obj):
|
||||
return isinstance(obj,tuple) or isinstance(obj,list) or isinstance (obj, java.util.List)
|
||||
|
||||
def is_string(obj):
|
||||
return (type(obj) is str) or (type(obj) is unicode)
|
||||
|
||||
def is_interpreter_thread():
|
||||
return java.lang.Thread.currentThread().name == "MainThread"
|
||||
|
||||
###################################################################################################
|
||||
#Access to context singleton
|
||||
###################################################################################################
|
||||
def get_context():
|
||||
return ch.psi.pshell.core.Context.getInstance()
|
||||
|
||||
|
||||
|
||||
1032
script/Lib/diffutils.py
Normal file
1032
script/Lib/diffutils.py
Normal file
File diff suppressed because it is too large
Load Diff
782
script/Lib/ijutils.py
Normal file
782
script/Lib/ijutils.py
Normal file
@@ -0,0 +1,782 @@
|
||||
####################################################################################################
|
||||
# Facade to ImageJ functionality
|
||||
####################################################################################################
|
||||
|
||||
#More information on:
|
||||
# Image: https://imagej.nih.gov/ij/docs/guide/146-28.html#toc-Section-28
|
||||
# Process: https://imagej.nih.gov/ij/docs/guide/146-29.html#toc-Section-29
|
||||
# Analyze: https://imagej.nih.gov/ij/docs/guide/146-30.html#toc-Section-30
|
||||
|
||||
import ch.psi.utils.Convert as Convert
|
||||
import ch.psi.pshell.imaging.Utils as ImagingUtils
|
||||
from startup import get_context, expand_path, is_string
|
||||
import java.awt.image.BufferedImage as BufferedImage
|
||||
import jarray
|
||||
import os
|
||||
|
||||
import ij.IJ as IJ
|
||||
import ij.ImageJ as ImageJ
|
||||
import ij.WindowManager as WindowManager
|
||||
import ij.ImagePlus as ImagePlus
|
||||
import ij.ImageStack as ImageStack
|
||||
import ij.Prefs as Prefs
|
||||
import ij.io.FileSaver as FileSaver
|
||||
import ij.io.Opener as Opener
|
||||
from ij.gui import Roi
|
||||
|
||||
import ij.process.ImageProcessor as ImageProcessor
|
||||
import ij.process.ByteProcessor as ByteProcessor
|
||||
import ij.process.ShortProcessor as ShortProcessor
|
||||
import ij.process.ColorProcessor as ColorProcessor
|
||||
import ij.process.FloatProcessor as FloatProcessor
|
||||
import ij.process.ImageConverter as ImageConverter
|
||||
import ij.process.AutoThresholder as AutoThresholder
|
||||
import ij.process.LUT as LUT
|
||||
import ij.measure.Measurements as Measurements
|
||||
import ij.measure.ResultsTable as ResultsTable
|
||||
import ij.plugin.filter.Analyzer as Analyzer
|
||||
import ij.plugin.filter.GaussianBlur as GaussianBlur
|
||||
import ij.plugin.filter.Filters as Filters
|
||||
import ij.plugin.filter.FFTFilter as FFTFilter
|
||||
import ij.plugin.filter.BackgroundSubtracter as BackgroundSubtracter
|
||||
import ij.plugin.filter.EDM as EDM
|
||||
import ij.plugin.filter.Shadows as Shadows
|
||||
import ij.plugin.filter.UnsharpMask as UnsharpMask
|
||||
import ij.plugin.filter.MaximumFinder as MaximumFinder
|
||||
import ij.plugin.filter.EDM as EDM
|
||||
import ij.plugin.filter.Shadows as Shadows
|
||||
import ij.plugin.filter.UnsharpMask as UnsharpMask
|
||||
import ij.plugin.filter.RankFilters as RankFilters
|
||||
import ij.plugin.filter.Convolver as Convolver
|
||||
import ij.plugin.filter.ParticleAnalyzer as ParticleAnalyzer
|
||||
|
||||
import ij.plugin.ContrastEnhancer as ContrastEnhancer
|
||||
import ij.plugin.Thresholder as Thresholder
|
||||
import ij.plugin.ImageCalculator as ImageCalculator
|
||||
import ij.plugin.FFT as FFT
|
||||
import ij.plugin.Concatenator as Concatenator
|
||||
|
||||
#ImageJ customizations
|
||||
import ch.psi.pshell.imaging.ij.FFTMath as FFTMath
|
||||
import ch.psi.pshell.imaging.ij.FFTFilter as FFTFilter
|
||||
import ch.psi.pshell.imaging.ij.Binary as Binary
|
||||
import ch.psi.pshell.imaging.ij.Slicer as Slicer
|
||||
|
||||
|
||||
#This eliminates the error messages due to the bug on ij.gui.ImageWindow row 555 (ij is null)
|
||||
if not "_image_j" in globals().keys():
|
||||
_image_j = ImageJ(None, ImageJ.NO_SHOW)
|
||||
|
||||
###################################################################################################
|
||||
#Image creation, copying & saving
|
||||
###################################################################################################
|
||||
def load_image(image, title = None):
|
||||
"""
|
||||
image: file name or BufferedImage
|
||||
"""
|
||||
if is_string(image):
|
||||
try:
|
||||
file = expand_path(image)
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
image = ImagingUtils.newImage(file)
|
||||
except:
|
||||
#try loading from assembly
|
||||
image = get_context().setup.getAssemblyImage(image)
|
||||
if title is None:
|
||||
title = os.path.basename(file)
|
||||
return ImagePlus("img" if title is None else title, image)
|
||||
|
||||
def load_array(array, width=None, height=None, title = "img"):
|
||||
"""
|
||||
array: 1d array if width and height defined , or else 2d array to be flattened.
|
||||
"""
|
||||
#2D
|
||||
if (width==None) and (height==None):
|
||||
if array.typecode == '[B': proc = ByteProcessor(len(array[0]), len(array), Convert.flatten(array))
|
||||
elif array.typecode == '[S': proc = ShortProcessor(len(array[0]), len(array), Convert.flatten(array), None)
|
||||
elif array.typecode in ['[I','[F', '[D']: proc = FloatProcessor(len(array[0]), len(array), Convert.flatten(array))
|
||||
else: raise Exception("Invalid array type")
|
||||
#1D
|
||||
else:
|
||||
if (len(array) > width*height):
|
||||
array = array[:(width*height)]
|
||||
if array.typecode == 'b': proc = ByteProcessor(width, height, array)
|
||||
elif array.typecode == 'h': proc = ShortProcessor(width, height, array, None)
|
||||
elif array.typecode in ['i','f','d']: proc = FloatProcessor(width, height, array)
|
||||
else: raise Exception("Invalid array type")
|
||||
return ImagePlus(title, proc)
|
||||
|
||||
def save_image(ip, path=None, format = None, metadata={}):
|
||||
"""
|
||||
Saves image or stack
|
||||
If parameters omitted, saves image again in same location, with same format.
|
||||
"""
|
||||
fs = FileSaver(ip)
|
||||
|
||||
info = ""
|
||||
for key,val in metadata.items():
|
||||
info = info + ("\n" if len(info)>0 else "") + str(key) + ": " + str(val)
|
||||
ip.setProperty("Info", info)
|
||||
|
||||
if path == None: fs.save()
|
||||
else:
|
||||
try:
|
||||
path = expandPath(path)
|
||||
except:
|
||||
pass
|
||||
if format == "bmp": fs.saveAsBmp(path)
|
||||
elif format == "fits": fs.saveAsFits(path)
|
||||
elif format == "gif": fs.saveAsGif(path)
|
||||
elif format == "jpeg": fs.saveAsJpeg(path)
|
||||
elif format == "lut": fs.saveAsLut(path)
|
||||
elif format == "pgm": fs.saveAsPgm(path)
|
||||
elif format == "png": fs.saveAsPng(path)
|
||||
elif format == "raw" and ip.getImageStackSize()>1: fs.saveAsRawStack(path)
|
||||
elif format == "raw": fs.saveAsRaw(path)
|
||||
elif format == "txt": fs.saveAsText(path)
|
||||
elif format == "tiff" and ip.getImageStackSize()>1: fs.saveAsTiffStack(path)
|
||||
elif format == "tiff": fs.saveAsTiff(path)
|
||||
elif format == "zip": fs.saveAsZip(path)
|
||||
|
||||
|
||||
def open_image(path, index=1):
|
||||
"""
|
||||
Open file using ij.io,Opener
|
||||
"""
|
||||
try:
|
||||
path = expand_path(path)
|
||||
except:
|
||||
pass
|
||||
opener = Opener()
|
||||
return opener.openImage(path, index)
|
||||
|
||||
def new_image(width, height, image_type="byte", title = "img", fill_color = None):
|
||||
"""
|
||||
type = "byte", "short", "color" or "float"
|
||||
"""
|
||||
if image_type == "byte": p=ByteProcessor(width, height)
|
||||
elif image_type == "short": p=ShortProcessor(width, height)
|
||||
elif image_type == "color": p=ColorProcessor(width, height)
|
||||
elif image_type == "float": p=FloatProcessor(width, height)
|
||||
else: raise Exception("Invalid image type " + str(image_type))
|
||||
ret = ImagePlus(title, p)
|
||||
if fill_color is not None:
|
||||
p.setColor(fill_color)
|
||||
p.resetRoi()
|
||||
p.fill()
|
||||
return ret
|
||||
|
||||
def get_ip_array(ip):
|
||||
"""
|
||||
Returns data array of ImagePlus
|
||||
"""
|
||||
if type(ip.getProcessor()) == FloatProcessor:
|
||||
return ip.getProcessor().getFloatArray()
|
||||
else:
|
||||
return ip.getProcessor().getIntArray()
|
||||
|
||||
|
||||
def sub_image(ip, x, y, width, height):
|
||||
"""
|
||||
Returns new ImagePlus
|
||||
"""
|
||||
ip.setRoi(x, y, width, height)
|
||||
p=ip.getProcessor().crop()
|
||||
return ImagePlus(ip.getTitle() + " subimage", p)
|
||||
|
||||
def copy_image(ip):
|
||||
return ip.duplicate()
|
||||
|
||||
def copy_image_to(ip_source, ip_dest, x, y):
|
||||
ip_source.deleteRoi()
|
||||
ip_source.copy()
|
||||
ip_dest.setRoi(x, y, ip_source.getWidth(), ip_source.getHeight())
|
||||
ip_dest.paste()
|
||||
ip_dest.changes = False
|
||||
ip_dest.deleteRoi()
|
||||
|
||||
def pad_image(ip, left=0, right=0, top=0, bottom=0, fill_color = None):
|
||||
p=ip.getProcessor()
|
||||
width = p.getWidth() + left + right
|
||||
height = p.getHeight() + top + bottom
|
||||
image_type = get_image_type(ip)
|
||||
ret = new_image(width, height, image_type, ip.getTitle() + " padded", fill_color)
|
||||
ip.deleteRoi()
|
||||
ip.copy()
|
||||
ret.setRoi(left, top, p.getWidth(), p.getHeight())
|
||||
ret.paste()
|
||||
ret.changes = False
|
||||
ret.deleteRoi()
|
||||
return ret
|
||||
|
||||
def get_image_type(ip):
|
||||
"""
|
||||
Returns: "byte", "short", "color" or "float"
|
||||
"""
|
||||
p=ip.getProcessor()
|
||||
if type(p) == ShortProcessor: return "short"
|
||||
elif type(p) == ColorProcessor: return "color"
|
||||
elif type(p) == FloatProcessor: return "float"
|
||||
return "byte"
|
||||
|
||||
###################################################################################################
|
||||
#Image measurements
|
||||
###################################################################################################
|
||||
|
||||
def get_measurement(ip, measurement):
|
||||
"""
|
||||
Return image measurement:
|
||||
"Area", "Mean", "StdDev", "Mode", "Min", "Max", "X", "Y", "XM", "YM", "Perim.", "BX", "BY",
|
||||
"Width", "Height", "Major", "Minor", "Angle", "Circ.", "Feret", "IntDen", "Median", "Skew",
|
||||
"Kurt", "%Area", "RawIntDen", "Ch", "Slice", "Frame", "FeretX", "FeretY", "FeretAngle",
|
||||
"MinFeret", "AR", "Round", "Solidity", "MinThr" or "MaxThr"
|
||||
"""
|
||||
return IJ.getValue(ip,measurement)
|
||||
|
||||
###################################################################################################
|
||||
#Image type conversion
|
||||
###################################################################################################
|
||||
def grayscale(ip, do_scaling=None, in_place=True):
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
ic = ImageConverter(ip)
|
||||
if do_scaling is not None:
|
||||
ic.setDoScaling(do_scaling)
|
||||
ic.convertToGray8()
|
||||
return ip
|
||||
|
||||
def get_channel(ip, channel):
|
||||
"""
|
||||
Return a channel from a color image as a new ImagePlus.
|
||||
channel: "red", "green","blue", "alpha", "brightness",
|
||||
"""
|
||||
proc = ip.getProcessor()
|
||||
if channel == "red": ret = proc.getChannel(1, None)
|
||||
elif channel == "green": ret = proc.getChannel(2, None)
|
||||
elif channel == "blue": ret = proc.getChannel(3, None)
|
||||
elif channel == "alpha": ret = proc.getChannel(4, None)
|
||||
elif channel == "brightness": ret = proc.getBrightness()
|
||||
else: raise Exception("Invalid channel " + str(channel))
|
||||
return ImagePlus(ip.getTitle() + " channel: " + channel, ret)
|
||||
|
||||
###################################################################################################
|
||||
#Thresholder
|
||||
###################################################################################################
|
||||
def threshold(ip, min_threshold, max_threshold, in_place=True):
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
ip.getProcessor().setThreshold(min_threshold, max_threshold, ImageProcessor.NO_LUT_UPDATE)
|
||||
WindowManager.setTempCurrentImage(ip)
|
||||
Thresholder().run("mask")
|
||||
return ip
|
||||
|
||||
def auto_threshold(ip, dark_background = False, method = AutoThresholder.getMethods()[0], in_place=True):
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
ip.getProcessor().setAutoThreshold(method, dark_background , ImageProcessor.NO_LUT_UPDATE)
|
||||
WindowManager.setTempCurrentImage(ip)
|
||||
thresholder=Thresholder().run("mask")
|
||||
return ip
|
||||
|
||||
###################################################################################################
|
||||
#Binary functions
|
||||
###################################################################################################
|
||||
def binary_op(ip, op, dark_background=False, iterations=1, count=1, in_place=True):
|
||||
"""
|
||||
op = "erode","dilate", "open","close", "outline", "fill holes", "skeletonize"
|
||||
"""
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
binary = Binary(count, iterations, dark_background )
|
||||
binary.setup(op, ip)
|
||||
binary.run(ip.getProcessor())
|
||||
return ip
|
||||
|
||||
def binary_erode(ip, dark_background=False, iterations=1, count=1, in_place=True):
|
||||
return binary_op(ip, "erode", dark_background, iterations, count, in_place)
|
||||
|
||||
def binary_dilate(ip, dark_background=False, iterations=1, count=1, in_place=True):
|
||||
return binary_op(ip, "dilate", dark_background, iterations, count, in_place)
|
||||
|
||||
def binary_open(ip, dark_background=False, iterations=1, count=1, in_place=True):
|
||||
return binary_op(ip, "open", dark_background, iterations, count, in_place)
|
||||
|
||||
def binary_close(ip, dark_background=False, iterations=1, count=1, in_place=True):
|
||||
return binary_op(ip, "close", dark_background, iterations, count)
|
||||
|
||||
def binary_outline(ip, dark_background=False, in_place=True):
|
||||
return binary_op(ip, "outline", dark_background, in_place=in_place)
|
||||
|
||||
def binary_fill_holes(ip, dark_background=False, in_place=True):
|
||||
return binary_op(ip, "fill holes", dark_background, in_place=in_place)
|
||||
|
||||
def binary_skeletonize(ip, dark_background=False, in_place=True):
|
||||
return binary_op(ip, "skeletonize", dark_background, in_place=in_place)
|
||||
|
||||
def analyse_particles(ip, min_size, max_size, fill_holes = True, exclude_edges = True, extra_measurements = 0, \
|
||||
print_table = False, output_image = "outlines", minCirc = 0.0, maxCirc = 1.0):
|
||||
"""
|
||||
Returns: tuple (ResultsTable results_table, ImagePlus output_image)
|
||||
output_image = "outlines", "overlay_outlines", "masks", "overlay_masks", "roi_masks" or None
|
||||
extra_measurements = mask with Measurements.CENTROID, PERIMETER, RECT, MIN_MAX, ELLIPSE, CIRCULARITY, AREA_FRACTION, INTEGRATED_DENSITY, INVERT_Y, FERET, KURTOSIS, MEDIAN, MODE, SKEWNESS, STD_DEV
|
||||
Measurements is a mask of flags: https://imagej.nih.gov/ij/developer/api/ij/measure/Measurements.html.
|
||||
Returned ResultsTable hold public fields: https://imagej.nih.gov/ij/developer/api/ij/measure/ResultsTable.html
|
||||
|
||||
"""
|
||||
rt = ResultsTable()
|
||||
show_summary = False
|
||||
options = ParticleAnalyzer.SHOW_RESULTS | ParticleAnalyzer.CLEAR_WORKSHEET
|
||||
"""
|
||||
ParticleAnalyzer.SHOW_ROI_MASKS | \
|
||||
#ParticleAnalyzer.RECORD_STARTS | \
|
||||
#ParticleAnalyzer.ADD_TO_MANAGER | \
|
||||
#ParticleAnalyzer.FOUR_CONNECTED | \
|
||||
#ParticleAnalyzer.IN_SITU_SHOW | \
|
||||
#ParticleAnalyzer.SHOW_NONE | \
|
||||
"""
|
||||
if show_summary: options = options | ParticleAnalyzer.DISPLAY_SUMMARY
|
||||
if output_image == "outlines": options = options | ParticleAnalyzer.SHOW_OUTLINES
|
||||
elif output_image == "overlay_outlines": options = options | ParticleAnalyzer.SHOW_OVERLAY_OUTLINES
|
||||
elif output_image == "masks": options = options | ParticleAnalyzer.SHOW_MASKS
|
||||
elif output_image == "overlay_masks": options = options | ParticleAnalyzer.SHOW_OVERLAY_MASKS
|
||||
elif output_image == "roi_masks": options = options | ParticleAnalyzer.SHOW_ROI_MASKS
|
||||
#ParticleAnalyzer.SHOW_ROI_MASKS
|
||||
if exclude_edges: options = options | ParticleAnalyzer.EXCLUDE_EDGE_PARTICLES
|
||||
if fill_holes: options = options | ParticleAnalyzer.INCLUDE_HOLES
|
||||
measurements = Measurements.AREA | Measurements.MEAN | Measurements.CENTER_OF_MASS | Measurements.RECT
|
||||
pa = ParticleAnalyzer(options, measurements, rt, min_size, max_size, minCirc, maxCirc)
|
||||
pa.setHideOutputImage(True)
|
||||
pa.setResultsTable(rt)
|
||||
if pa.analyze(ip):
|
||||
if print_table:
|
||||
print rt.getColumnHeadings()
|
||||
for row in range (rt.counter):
|
||||
print rt.getRowAsString(row)
|
||||
return (rt, pa.getOutputImage())
|
||||
|
||||
###################################################################################################
|
||||
#Image operators
|
||||
###################################################################################################
|
||||
def op_image(ip1, ip2, op, float_result=False, in_place=True):
|
||||
"""
|
||||
op = "add","subtract", "multiply","divide", "and", "or", "xor", "min", "max", "average", "difference" or "copy"
|
||||
"""
|
||||
ip1 = ip1 if in_place else ip1.duplicate()
|
||||
ic = ImageCalculator()
|
||||
pars = op
|
||||
if float_result:
|
||||
op = op + " float"
|
||||
ic.run(pars, ip1, ip2)
|
||||
return ip1
|
||||
|
||||
def op_const(ip, op, val, in_place=True):
|
||||
"""
|
||||
op = "add","subtract", "multiply","divide", "and", "or", "xor", "min", "max", "gamma", "set" or "log", "exp", "sqr", "sqrt","abs"
|
||||
"""
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
pr = ip.getProcessor()
|
||||
if op == 'add': pr.add(val)
|
||||
elif op == 'sub': pr.subtract(val)
|
||||
elif op == 'multiply': pr.multiply(val)
|
||||
elif op == 'divide' and val!=0: pr.multiply(1.0/val)
|
||||
elif op == 'and': pr.and(val)
|
||||
elif op == 'or': pr.or(val)
|
||||
elif op == 'xor': pr.xor(val)
|
||||
elif op == 'min': pr.min(val);pr.resetMinAndMax()
|
||||
elif op == 'max': pr.max(val);pr.resetMinAndMax()
|
||||
elif op == 'gamma' and 0.05 < val < 5.0: pr.gamma(val)
|
||||
elif op == 'set': pr.set(val)
|
||||
elif op == 'log': pr.log()
|
||||
elif op == 'exp': pr.exp()
|
||||
elif op == 'sqr': pr.sqr()
|
||||
elif op == 'sqrt': pr.sqrt()
|
||||
elif op == 'abs': pr.abs();pr.resetMinAndMax()
|
||||
else: raise Exception("Invalid operation " + str(op))
|
||||
return ip
|
||||
|
||||
def op_fft(ip1, ip2, op, do_inverse = True) :
|
||||
"""
|
||||
Images must have same sizes, and multiple of 2 height and width.
|
||||
op = "correlate" (complex conjugate multiply), "convolve" (Fourier domain multiply), "deconvolve" (Fourier domain divide)
|
||||
"""
|
||||
if op == "correlate": op_index = 0
|
||||
elif op == "convolve": op_index = 1
|
||||
elif op == "deconvolve": op_index = 2
|
||||
else: raise Exception("Invalid operation " + str(op))
|
||||
return FFTMath().doMath(ip1, ip2, op_index, do_inverse)
|
||||
|
||||
def op_rank(ip, op, kernel_radius =1 , dark_outliers = False ,threshold = 50, in_place=True):
|
||||
"""
|
||||
op = "mean", "min", "max", "variance", "median", "close_maxima", "open_maxima", "remove_outliers", "remove_nan", "despeckle"
|
||||
"""
|
||||
if op == "mean": filter_type = RankFilters.MEAN
|
||||
elif op == "min": filter_type = RankFilters.MIN
|
||||
elif op == "max": filter_type = RankFilters.MAX
|
||||
elif op == "variance": filter_type = RankFilters.VARIANCE
|
||||
elif op == "median": filter_type = RankFilters.MEDIAN
|
||||
elif op == "close_maxima": filter_type = RankFilters.CLOSE
|
||||
elif op == "open_maxima": filter_type = RankFilters.OPEN
|
||||
elif op == "remove_outliers": filter_type = RankFilters.OUTLIERS
|
||||
elif op == "remove_nan": filter_type = RankFilters.REMOVE_NAN
|
||||
elif op == "despeckle": filter_type, kernel_radius = RankFilters.MEDIAN, 1
|
||||
else: raise Exception("Invalid operation " + str(op))
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
RankFilters().rank(ip.getProcessor(), kernel_radius, filter_type, RankFilters.DARK_OUTLIERS if dark_outliers else RankFilters.BRIGHT_OUTLIERS ,threshold)
|
||||
return ip
|
||||
|
||||
def op_edm(ip, op="edm", dark_background=False, in_place=True):
|
||||
"""
|
||||
Euclidian distance map & derived operations
|
||||
op ="edm", "watershed","points", "voronoi"
|
||||
"""
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
pr = ip.getProcessor()
|
||||
edm=EDM()
|
||||
Prefs.blackBackground=dark_background
|
||||
if op=="edm":
|
||||
#pr.setPixels(0, edm.makeFloatEDM(pr, 0, False));
|
||||
#pr.resetMinAndMax();
|
||||
if dark_background:
|
||||
pr.invert()
|
||||
edm.toEDM(pr)
|
||||
else:
|
||||
edm.setup(op, ip)
|
||||
edm.run(pr)
|
||||
return ip
|
||||
|
||||
def watershed(ip, dark_background=False, in_place=True):
|
||||
return op_edm(ip, "watershed", dark_background, in_place)
|
||||
|
||||
def ultimate_points(ip, dark_background=False, in_place=True):
|
||||
return op_edm(ip, "points", dark_background, in_place)
|
||||
|
||||
def veronoi(ip, dark_background=False, in_place=True):
|
||||
return op_edm(ip, "voronoi", dark_background, in_place)
|
||||
|
||||
def edm(ip, dark_background=False, in_place=True):
|
||||
return op_edm(ip, "edm", dark_background, in_place)
|
||||
|
||||
def op_filter(ip, op, in_place=True):
|
||||
"""
|
||||
This is redundant as just calls processor methods.
|
||||
op ="invert", "smooth", "sharpen", "edge", "add"
|
||||
"""
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
f = Filters()
|
||||
f.setup(op, ip )
|
||||
f.run(ip.getProcessor())
|
||||
return ip
|
||||
|
||||
###################################################################################################
|
||||
#Other operations
|
||||
###################################################################################################
|
||||
def gaussian_blur(ip, sigma_x=3.0, sigma_y=3.0, accuracy = 0.01, in_place=True):
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
GaussianBlur().blurGaussian(ip.getProcessor(), sigma_x, sigma_y, accuracy)
|
||||
return ip
|
||||
|
||||
def find_maxima(ip, tolerance=25, threshold = ImageProcessor.NO_THRESHOLD, output_type=MaximumFinder.IN_TOLERANCE, exclude_on_edges = False, is_edm = False):
|
||||
"""
|
||||
Returns new ImagePlus
|
||||
tolerance: maxima are accepted only if protruding more than this value from the ridge to a higher maximum
|
||||
threshhold: minimum height of a maximum (uncalibrated);
|
||||
output_type = SINGLE_POINTS, IN_TOLERANCE or SEGMENTED. No output image is created for output types POINT_SELECTION, LIST and COUNT.
|
||||
"""
|
||||
byte_processor = MaximumFinder().findMaxima(ip.getProcessor(), tolerance, threshold, output_type, exclude_on_edges, is_edm)
|
||||
return ImagePlus(ip.getTitle() + " maxima", byte_processor)
|
||||
|
||||
|
||||
def get_maxima_points(ip, tolerance=25, exclude_on_edges = False):
|
||||
polygon = MaximumFinder().getMaxima(ip.getProcessor(), tolerance, exclude_on_edges)
|
||||
return (polygon.xpoints, polygon.ypoints)
|
||||
|
||||
def enhance_contrast(ip, equalize_histo = True, saturated_pixels = 0.5, normalize = False, stack_histo = False, in_place=True):
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
ce = ContrastEnhancer()
|
||||
if equalize_histo:
|
||||
ce.equalize(ip.getProcessor());
|
||||
else:
|
||||
ce.stretchHistogram(ip.getProcessor(), saturated_pixels)
|
||||
if normalize:
|
||||
ip.getProcessor().setMinAndMax(0,1.0 if (ip.getProcessor().getBitDepth()==32) else ip.getProcessor().maxValue())
|
||||
return ip
|
||||
|
||||
def shadows(ip, op, in_place=True):
|
||||
"""
|
||||
op ="north","northeast", "east", "southeast","south", "southwest", "west","northwest"
|
||||
"""
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
shadows= Shadows()
|
||||
shadows.setup(op, ip)
|
||||
shadows.run(ip.getProcessor())
|
||||
return ip
|
||||
|
||||
def unsharp_mask(ip, sigma, weight, in_place=True):
|
||||
"""
|
||||
Float processor
|
||||
"""
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
ip.getProcessor().snapshot()
|
||||
unsharp=UnsharpMask()
|
||||
USmask.setup(" ", ip)
|
||||
USmask.sharpenFloat( ip.getProcessor(),sigma, weight)
|
||||
return ip
|
||||
|
||||
def subtract_background(ip, radius = 50, create_background=False, dark_background=False, use_paraboloid =True, do_presmooth = True, correctCorners = True, rgb_brightness=False, in_place=True):
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
if rgb_brightness:
|
||||
BackgroundSubtracter().rollingBallBrightnessBackground(ip.getProcessor(), radius, create_background,not dark_background, use_paraboloid, do_presmooth, correctCorners)
|
||||
else:
|
||||
BackgroundSubtracter().rollingBallBackground(ip.getProcessor(), radius, create_background, not dark_background, use_paraboloid, do_presmooth, correctCorners)
|
||||
return ip
|
||||
|
||||
###################################################################################################
|
||||
#FFT
|
||||
###################################################################################################
|
||||
def image_fft(ip, show = True):
|
||||
WindowManager.setTempCurrentImage(ip)
|
||||
fft = FFT()
|
||||
fft.run("fft")
|
||||
#TODO: how to avoid it to be created?
|
||||
#ret = ImagePlus("FHT of " + ip.getTitle(), WindowManager.getCurrentImage().getProcessor())
|
||||
ret = WindowManager.getCurrentImage()
|
||||
if not show:
|
||||
WindowManager.getCurrentImage().hide()
|
||||
return ret
|
||||
|
||||
|
||||
def image_ffti(ip, show = True):
|
||||
WindowManager.setTempCurrentImage(ip)
|
||||
fft = FFT()
|
||||
fft.run("inverse")
|
||||
#WindowManager.getCurrentImage().hide()
|
||||
#TODO: how to avoid it to be created?
|
||||
#ret = WindowManager.getCurrentImage()
|
||||
#WindowManager.getCurrentImage().hide()
|
||||
#ret = ImagePlus(ip.getTitle() + " ffti", WindowManager.getCurrentImage().getProcessor())
|
||||
ret = WindowManager.getCurrentImage()
|
||||
if not show:
|
||||
WindowManager.getCurrentImage().hide()
|
||||
|
||||
return ret
|
||||
|
||||
def bandpass_filter(ip, small_dia_px, large_dia_px, suppress_stripes = 0, stripes_tolerance_direction = 5.0, autoscale_after_filtering = False, saturate_if_autoscale = False, display_filter = False, in_place=True):
|
||||
"""
|
||||
suppress_stripes = 0 for none, 1 for horizontal, 2 for vertical
|
||||
"""
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
filter= FFTFilter();
|
||||
FFTFilter.filterLargeDia = large_dia_px
|
||||
FFTFilter.filterSmallDia = small_dia_px
|
||||
FFTFilter.choiceIndex = suppress_stripes
|
||||
FFTFilter.toleranceDia = stripes_tolerance_direction
|
||||
FFTFilter.doScalingDia = autoscale_after_filtering
|
||||
FFTFilter.saturateDia = saturate_if_autoscale
|
||||
FFTFilter.displayFilter =display_filter
|
||||
filter.setup(None, ip);
|
||||
filter.run(ip.getProcessor())
|
||||
return ip
|
||||
|
||||
###################################################################################################
|
||||
#Convolution
|
||||
###################################################################################################
|
||||
|
||||
KERNEL_BLUR = [[0.1111, 0.1111, 0.1111], [0.1111, 0.1111, 0.1111], [0.1111, 0.1111, 0.1111]]
|
||||
KERNEL_SHARPEN = [[0.0, -0.75, 0.0], [-0.75, 4.0, -0.75], [0.0, -0.75, 0.0]]
|
||||
KERNEL_SHARPEN_2 = [[-1.0, -1.0, -1.0], [-1.0, 9.0, -1.0], [-1.0, -1.0, -1.0]]
|
||||
KERNEL_LIGHT = [[0.1, 0.1, 0.1], [0.1, 1.0, 0.1],[0.1, 0.1, 0.1]]
|
||||
KERNEL_DARK = [[0.01, 0.01, 0.01],[0.01, 0.5, 0.01],[0.01, 0.01, 0.01]]
|
||||
KERNEL_EDGE_DETECT = [[0.0, -0.75, 0.0], [-0.75, 3.0, -0.75], [0.0, -0.75, 0.0]]
|
||||
KERNEL_EDGE_DETECT_2 = [[-0.5, -0.5, -0.5], [-0.5, 4.0, -0.5], [-0.5, -0.5, -0.5]]
|
||||
KERNEL_DIFFERENTIAL_EDGE_DETECT = [[-1.0, 0.0, 1.0], [0.0, 0.0, 0.0], [1.0, 0.0, -1.0]]
|
||||
KERNEL_PREWITT = [[-2.0, -1.0, 0.0], [-1.0, 0.0, 1.0 ], [0.0, 1.0, 2.0]]
|
||||
KERNEL_SOBEL = [[2.0, 2.0, 0.0], [2.0, 0.0, -2.0 ], [0.0, -2.0, -2.0]]
|
||||
|
||||
|
||||
def convolve(ip, kernel, in_place=True):
|
||||
"""
|
||||
kernel: list of lists
|
||||
"""
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
kernel_width = len(kernel)
|
||||
kernel_height= len(kernel[0])
|
||||
kernel = [item for row in kernel for item in row]
|
||||
#Convolver().convolve(ip.getProcessor(), kernel, kernel_width, kernel_height)
|
||||
ip.getProcessor().convolve(kernel, kernel_width, kernel_height)
|
||||
return ip
|
||||
|
||||
|
||||
###################################################################################################
|
||||
#Shortcut to ImageProcessor methods
|
||||
###################################################################################################
|
||||
def invert(ip, in_place=True):
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
ip.getProcessor().invert()
|
||||
return ip
|
||||
|
||||
def smooth(ip, in_place=True):
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
ip.getProcessor().smooth()
|
||||
return ip
|
||||
|
||||
def sharpen(ip, in_place=True):
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
ip.getProcessor().sharpen()
|
||||
return ip
|
||||
|
||||
def edges(ip, in_place=True): #Sobel
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
ip.getProcessor().findEdges()
|
||||
return ip
|
||||
|
||||
def noise(ip, sigma = 25.0, in_place=True):
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
ip.getProcessor().noise(sigma)
|
||||
return ip
|
||||
|
||||
def remap(ip, min=None, max=None, in_place=True):
|
||||
ip = ip if in_place else ip.duplicate()
|
||||
if min is None or max is None:
|
||||
stats = get_statistics(ip, Measurements.MIN_MAX)
|
||||
if min is None: min = stats.min
|
||||
if max is None: max = stats.max
|
||||
ip.getProcessor().setMinAndMax(min, max)
|
||||
return ip
|
||||
|
||||
def set_lut(ip, r, g, b):
|
||||
"""
|
||||
r,g and b are lists of 256 integers
|
||||
"""
|
||||
r = [x if x<128 else x-256 for x in r]
|
||||
g = [x if x<128 else x-256 for x in g]
|
||||
b = [x if x<128 else x-256 for x in b]
|
||||
ip.setLut(LUT(jarray.array(r,'b'),jarray.array(g,'b'),jarray.array(b,'b')))
|
||||
|
||||
def resize(ip, width, height):
|
||||
"""
|
||||
Returns new ImagePlus
|
||||
"""
|
||||
p = ip.getProcessor().resize(width, height)
|
||||
return ImagePlus(ip.getTitle() + " resized", p)
|
||||
|
||||
def binning(ip, factor):
|
||||
p=ip.getProcessor().bin(factor)
|
||||
return ImagePlus(ip.getTitle() + " resized", p)
|
||||
|
||||
def get_histogram(ip, hist_min = 0, hist_max = 0, hist_bins = 256, roi=None):
|
||||
"""
|
||||
hist_min, hist_max, hist_bins used only for float images (otherwise fixed to 0,255,256)
|
||||
roi is list [x,y,w,h]
|
||||
"""
|
||||
if roi == None: ip.deleteRoi()
|
||||
else: ip.setRoi(roi[0],roi[1],roi[2],roi[3])
|
||||
image_statistics = ip.getStatistics(0, hist_bins, hist_min, hist_max)
|
||||
return image_statistics.getHistogram()
|
||||
|
||||
|
||||
def get_array(ip):
|
||||
return ip.getProcessor().getIntArray()
|
||||
|
||||
def get_line(ip, x1, y1, x2, y2):
|
||||
return ip.getProcessor().getLine(x1, y1, x2, y2)
|
||||
|
||||
def get_pixel_range(ip):
|
||||
return (ip.getProcessor().getMin(), ip.getProcessor().getMax())
|
||||
|
||||
def get_num_channels(ip):
|
||||
return ip.getProcessor().getNChannels()
|
||||
|
||||
def is_binary(ip):
|
||||
return ip.getProcessor().isBinary()
|
||||
|
||||
def get_pixel(ip, x, y):
|
||||
return ip.getProcessor().getPixel(x,y)
|
||||
|
||||
def get_pixel_array(ip, x, y):
|
||||
a = [0]*get_num_channels(ip)
|
||||
return ip.getProcessor().getPixel(x,y,a)
|
||||
|
||||
def get_pixels(ip):
|
||||
return ip.getProcessor().getPixels()
|
||||
|
||||
def get_width(ip):
|
||||
return ip.getProcessor().getWidth()
|
||||
|
||||
def get_height(ip):
|
||||
return ip.getProcessor().getHeight()
|
||||
|
||||
def get_row(ip, y):
|
||||
a = [0]*get_width(ip)
|
||||
array = jarray.array(a,'i')
|
||||
ip.getProcessor().getRow(0, y, array, get_width(ip))
|
||||
return array
|
||||
|
||||
def get_col(ip, x):
|
||||
a = [0]*get_height(ip)
|
||||
array = jarray.array(a,'i')
|
||||
ip.getProcessor().getColumn(x, 0, array, get_height(ip))
|
||||
return array
|
||||
|
||||
def get_statistics(ip, measurements = None):
|
||||
"""
|
||||
Measurements is a mask of flags: https://imagej.nih.gov/ij/developer/api/ij/measure/Measurements.html.
|
||||
Statistics object hold public fields: https://imagej.nih.gov/ij/developer/api/ij/process/ImageStatistics.html
|
||||
"""
|
||||
if measurements is None:
|
||||
return ip.getStatistics()
|
||||
else:
|
||||
return ip.getStatistics(measurements)
|
||||
|
||||
###################################################################################################
|
||||
#Image stack functions
|
||||
###################################################################################################
|
||||
def create_stack(ip_list, duplicate=True, title = None):
|
||||
stack = Concatenator().concatenate(ip_list, duplicate)
|
||||
if title is not None:
|
||||
stack.setTitle(title)
|
||||
return stack
|
||||
|
||||
def open_stack(path_list, title=None):
|
||||
"""
|
||||
Open list of files as a stack using ij.io,Opener
|
||||
"""
|
||||
ip_list = []
|
||||
for path in path_list:
|
||||
ip_list.append(open_image(path))
|
||||
return create_stack(ip_list, duplicate=False, title = "stack" if title is None else title)
|
||||
|
||||
def reslice(stack, start_at = "Top", vertically = True, flip = True, output_pixel_spacing=1.0, avoid_interpolation = True, title = None):
|
||||
ss = Slicer()
|
||||
ss.rotate = vertically
|
||||
ss.startAt = start_at
|
||||
ss.flip = flip
|
||||
ss.nointerpolate = avoid_interpolation
|
||||
ss.outputZSpacing = output_pixel_spacing
|
||||
stack = ss.reslice(stack)
|
||||
if title is not None:
|
||||
stack.setTitle(title)
|
||||
return stack
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
# ImagePlus list operations
|
||||
###############################################################################
|
||||
|
||||
def integrate_ips(ips, as_float=True):
|
||||
"""
|
||||
Integrate list if ImagePlus with the same size.
|
||||
"""
|
||||
aux = None
|
||||
for i in range(len(ips)):
|
||||
if i==0:
|
||||
img_type = "float" if as_float else "short"
|
||||
aux = new_image(ips[i].width, ips[i].height, image_type=img_type, title = "sum", fill_color = None)
|
||||
op_image(aux, ips[i], "add", float_result=as_float, in_place=True)
|
||||
return aux
|
||||
|
||||
def average_ips (ips, roi=None, as_float=True):
|
||||
"""
|
||||
Average list if ImagePlus with the same size.
|
||||
"""
|
||||
aux = integrate_ips(ips, as_float)
|
||||
op_const(aux, "divide", float(len(ips)), in_place=True)
|
||||
return aux
|
||||
239
script/Lib/jeputils.py
Normal file
239
script/Lib/jeputils.py
Normal file
@@ -0,0 +1,239 @@
|
||||
###################################################################################################
|
||||
# Facade to JEP: Embedded Python
|
||||
###################################################################################################
|
||||
|
||||
#Matplotlib won't work out of the box because it's default backend (Qt) uses signals, which only works in
|
||||
#the main thread. Ideally should find a fix, in order to mark the running thread as the main.
|
||||
#As a workaround, one can use the Tk backend:
|
||||
#
|
||||
#import matplotlib
|
||||
#matplotlib.use('TkAgg')
|
||||
|
||||
|
||||
#In principle just add JEP jar and library to the extensions folder.
|
||||
#
|
||||
#Alternatively on Linux:
|
||||
# Python 2:
|
||||
# - Add <python home>/lib/python3.X/site-packages/jep to LD_LIBRARY_PATH
|
||||
# - Add <python home>/lib/python3.X/site-packages/jep/jep-X.X.X.jar to the class path
|
||||
#
|
||||
#Python3:
|
||||
# - Add JEP library folder to LD_LIBRARY_PATH
|
||||
# - If using OpenJDK, add also python <python home>/lib folder to LD_LIBRARY_PATH
|
||||
# - Set LD_PRELOAD=<python home>/lib/libpython3.5m.so
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import jep.Jep
|
||||
import jep.SharedInterpreter
|
||||
import jep.NDArray
|
||||
import java.lang.Thread
|
||||
import org.python.core.PyArray as PyArray
|
||||
import java.lang.String as String
|
||||
import java.util.List
|
||||
import java.util.Map
|
||||
import java.util.HashMap
|
||||
import ch.psi.pshell.scripting.ScriptUtils as ScriptUtils
|
||||
|
||||
|
||||
from startup import to_array, get_context, _get_caller, Convert, Arr
|
||||
|
||||
__jep = {}
|
||||
|
||||
def __get_jep():
|
||||
t = java.lang.Thread.currentThread()
|
||||
if not t in __jep:
|
||||
init_jep()
|
||||
return __jep[t]
|
||||
|
||||
def __close_jep():
|
||||
t = java.lang.Thread.currentThread()
|
||||
if t in __jep:
|
||||
__jep[t].close()
|
||||
|
||||
def init_jep():
|
||||
#TODO: Should do it but generates errors
|
||||
#__close_jep()
|
||||
j = jep.SharedInterpreter()
|
||||
#Faster, but statements must be complete
|
||||
j.setInteractive(False)
|
||||
__jep[java.lang.Thread.currentThread()] = j
|
||||
j.eval("import sys")
|
||||
#sys.argv is not present in JEP and may be needed for certain modules (as Tkinter)
|
||||
j.eval("sys.argv = ['PShell']");
|
||||
#Add standard script path to python path
|
||||
j.eval("sys.path.append('" + get_context().setup.getScriptPath() + "')")
|
||||
|
||||
#Redirect stdout
|
||||
j.eval("class JepStdout:\n" +
|
||||
" def write(self, str):\n" +
|
||||
" self.str += str\n" +
|
||||
" def clear(self):\n" +
|
||||
" self.str = ''\n" +
|
||||
" def flush(self):\n" +
|
||||
" pass\n")
|
||||
j.eval("sys.stdout=JepStdout()");
|
||||
j.eval("sys.stderr=JepStdout()");
|
||||
j.eval("sys.stdout.clear()")
|
||||
j.eval("sys.stderr.clear()")
|
||||
|
||||
#Import reload on Python 3
|
||||
j.eval("try:\n" +
|
||||
" reload # Python 2.7\n" +
|
||||
"except NameError:\n" +
|
||||
" try:\n" +
|
||||
" from importlib import reload # Python 3.4+\n" +
|
||||
" except ImportError:\n" +
|
||||
" from imp import reload # Python 3.0 - 3.3\n")
|
||||
|
||||
def __print_stdout():
|
||||
j=__get_jep()
|
||||
output = None
|
||||
err = None
|
||||
try:
|
||||
output = j.getValue("sys.stdout.str")
|
||||
err = j.getValue("sys.stderr.str")
|
||||
j.eval("sys.stdout.clear()")
|
||||
j.eval("sys.stderr.clear()")
|
||||
except:
|
||||
pass
|
||||
if (output is not None) and len(output)>0:
|
||||
print output
|
||||
if (err is not None) and len(err)>0:
|
||||
print >> sys.stderr, err
|
||||
|
||||
def run_jep(script_name, vars = {}):
|
||||
global __jep
|
||||
script = get_context().scriptManager.library.resolveFile(script_name)
|
||||
if script is None :
|
||||
script= os.path.abspath(script_name)
|
||||
j=__get_jep()
|
||||
|
||||
for v in vars:
|
||||
j.set(v, vars[v])
|
||||
try:
|
||||
j.runScript(script)
|
||||
finally:
|
||||
__print_stdout()
|
||||
|
||||
def eval_jep(line):
|
||||
j=__get_jep()
|
||||
try:
|
||||
j.eval(line)
|
||||
finally:
|
||||
__print_stdout()
|
||||
|
||||
def set_jep(var, value):
|
||||
j=__get_jep()
|
||||
j.set(var, value)
|
||||
|
||||
def get_jep(var):
|
||||
j=__get_jep()
|
||||
return j.getValue(var)
|
||||
|
||||
def call_jep(module, function, args = [], kwargs = {}, reload=False):
|
||||
j=__get_jep()
|
||||
if "/" in module:
|
||||
script = get_context().scriptManager.library.resolveFile(module)
|
||||
if "\\" in script:
|
||||
#Windows paths
|
||||
module_path = script[0:script.rfind("\\")]
|
||||
module = script[script.rfind("\\")+1:]
|
||||
else:
|
||||
#Linux paths
|
||||
module_path = script[0:script.rfind("/")]
|
||||
module = script[script.rfind("/")+1:]
|
||||
eval_jep("import sys")
|
||||
eval_jep("sys.path.append('" + module_path + "')")
|
||||
if module.endswith(".py"):
|
||||
module = module[0:-3]
|
||||
|
||||
f = module+"_" + function+"_"+str(j.hashCode())
|
||||
try:
|
||||
if reload:
|
||||
eval_jep("import " + module)
|
||||
eval_jep("_=reload(" + module+")")
|
||||
eval_jep("from " + module + " import " + function + " as " + f)
|
||||
if (kwargs is not None) and (len(kwargs)>0):
|
||||
#invoke with kwargs only available in JEP>3.8
|
||||
hm=java.util.HashMap()
|
||||
hm.update(kwargs)
|
||||
#The only way to get the overloaded method...
|
||||
m = j.getClass().getMethod("invoke", [String, ScriptUtils.getType("[o"), java.util.Map])
|
||||
ret = m.invoke(j, [f, to_array(args,'o'), hm])
|
||||
else:
|
||||
ret = j.invoke(f, args)
|
||||
finally:
|
||||
__print_stdout()
|
||||
return ret
|
||||
|
||||
#Converts pythonlist or Java array to numpy array
|
||||
def to_npa(data, dimensions = None, type = None):
|
||||
if (not isinstance(data, PyArray)) or (type is not None):
|
||||
data = to_array(data,'d' if type is None else type)
|
||||
return jep.NDArray(data, dimensions)
|
||||
|
||||
#recursivelly converts all NumPy arrays to Java arrys
|
||||
def rec_from_npa(obj):
|
||||
if isinstance(obj, jep.NDArray):
|
||||
ret = obj.data
|
||||
if len(obj.dimensions)>1:
|
||||
ret=Convert.reshape(ret, obj.dimensions)
|
||||
return ret
|
||||
if isinstance(obj, java.util.List) or isinstance(obj,tuple) or isinstance(obj,list):
|
||||
ret=[]
|
||||
for i in range(len(obj)):
|
||||
ret.append(rec_from_npa(obj[i]))
|
||||
if isinstance(obj,tuple):
|
||||
return type(ret)
|
||||
return ret
|
||||
if isinstance(obj, java.util.Map) or isinstance(obj,dict):
|
||||
ret = {} if isinstance(obj,dict) else java.util.HashMap()
|
||||
for k in obj.keys():
|
||||
ret[k] = rec_from_npa(obj[k])
|
||||
return ret
|
||||
return obj
|
||||
|
||||
#recursivelly converts all Java arrays to NumPy arrys
|
||||
def rec_to_npa(obj):
|
||||
if isinstance(obj, PyArray):
|
||||
dimensions = Arr.getShape(obj)
|
||||
if len(dimensions)>1:
|
||||
obj = Convert.flatten(obj)
|
||||
return to_npa(obj, dimensions = dimensions)
|
||||
if isinstance(obj, java.util.List) or isinstance(obj,tuple) or isinstance(obj,list):
|
||||
ret=[]
|
||||
for i in range(len(obj)):
|
||||
ret.append(rec_to_npa(obj[i]))
|
||||
if isinstance(obj,tuple):
|
||||
return tuple(ret)
|
||||
return ret
|
||||
if isinstance(obj, java.util.Map) or isinstance(obj,dict):
|
||||
ret = {} if isinstance(obj,dict) else java.util.HashMap()
|
||||
for k in obj.keys():
|
||||
ret[k] = rec_to_npa(obj[k])
|
||||
return ret
|
||||
return obj
|
||||
|
||||
def call_py(module, function, reload_function, *args, **kwargs):
|
||||
"""
|
||||
Calls a CPython function recursively crecursively converting Java arrays in arguments to NumPy,
|
||||
and NumPy arrays in return values to Java arrays.
|
||||
"""
|
||||
ret = call_jep(module, function, rec_to_npa(args), rec_to_npa(kwargs), reload=reload_function)
|
||||
return rec_from_npa(ret)
|
||||
|
||||
def import_py(module, function):
|
||||
"""
|
||||
Adds a CPython function to globals, creating a wrapper call to JEP, with
|
||||
recurvive convertion of Java arrays in arguments to NumPy arrays,
|
||||
and NumPy arrays in return values to Java arrays.
|
||||
"""
|
||||
def jep_wrapper(*args, **kwargs):
|
||||
reload_function = jep_wrapper.reload
|
||||
jep_wrapper.reload = False
|
||||
return call_py(module, function, reload_function, *args, **kwargs)
|
||||
jep_wrapper.reload=True
|
||||
_get_caller().f_globals[function] = jep_wrapper
|
||||
|
||||
681
script/Lib/mathutils.py
Normal file
681
script/Lib/mathutils.py
Normal file
@@ -0,0 +1,681 @@
|
||||
###################################################################################################
|
||||
# Facade to Apache Commons Math
|
||||
###################################################################################################
|
||||
|
||||
import sys
|
||||
import math
|
||||
import operator
|
||||
|
||||
import java.util.List
|
||||
import java.lang.reflect.Array
|
||||
import java.lang.Class as Class
|
||||
import jarray
|
||||
import org.python.core.PyArray as PyArray
|
||||
import ch.psi.utils.Convert as Convert
|
||||
|
||||
import org.apache.commons.math3.util.FastMath as FastMath
|
||||
import org.apache.commons.math3.util.Pair as Pair
|
||||
import org.apache.commons.math3.complex.Complex as Complex
|
||||
|
||||
import org.apache.commons.math3.analysis.DifferentiableUnivariateFunction as DifferentiableUnivariateFunction
|
||||
import org.apache.commons.math3.analysis.function.Gaussian as Gaussian
|
||||
import org.apache.commons.math3.analysis.function.HarmonicOscillator as HarmonicOscillator
|
||||
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure as DerivativeStructure
|
||||
import org.apache.commons.math3.analysis.differentiation.FiniteDifferencesDifferentiator as FiniteDifferencesDifferentiator
|
||||
import org.apache.commons.math3.analysis.integration.SimpsonIntegrator as SimpsonIntegrator
|
||||
import org.apache.commons.math3.analysis.integration.TrapezoidIntegrator as TrapezoidIntegrator
|
||||
import org.apache.commons.math3.analysis.integration.RombergIntegrator as RombergIntegrator
|
||||
import org.apache.commons.math3.analysis.integration.MidPointIntegrator as MidPointIntegrator
|
||||
import org.apache.commons.math3.analysis.polynomials.PolynomialFunction as PolynomialFunction
|
||||
import org.apache.commons.math3.analysis.polynomials.PolynomialFunctionLagrangeForm as PolynomialFunctionLagrangeForm
|
||||
import org.apache.commons.math3.analysis.solvers.LaguerreSolver as LaguerreSolver
|
||||
import org.apache.commons.math3.analysis.UnivariateFunction as UnivariateFunction
|
||||
import org.apache.commons.math3.analysis.interpolation.SplineInterpolator as SplineInterpolator
|
||||
import org.apache.commons.math3.analysis.interpolation.LinearInterpolator as LinearInterpolator
|
||||
import org.apache.commons.math3.analysis.interpolation.NevilleInterpolator as NevilleInterpolator
|
||||
import org.apache.commons.math3.analysis.interpolation.LoessInterpolator as LoessInterpolator
|
||||
import org.apache.commons.math3.analysis.interpolation.DividedDifferenceInterpolator as DividedDifferenceInterpolator
|
||||
import org.apache.commons.math3.analysis.interpolation.AkimaSplineInterpolator as AkimaSplineInterpolator
|
||||
|
||||
import org.apache.commons.math3.fitting.GaussianCurveFitter as GaussianCurveFitter
|
||||
import org.apache.commons.math3.fitting.PolynomialCurveFitter as PolynomialCurveFitter
|
||||
import org.apache.commons.math3.fitting.HarmonicCurveFitter as HarmonicCurveFitter
|
||||
import org.apache.commons.math3.fitting.WeightedObservedPoint as WeightedObservedPoint
|
||||
import org.apache.commons.math3.fitting.leastsquares.MultivariateJacobianFunction as MultivariateJacobianFunction
|
||||
import org.apache.commons.math3.fitting.leastsquares.LeastSquaresBuilder as LeastSquaresBuilder
|
||||
import org.apache.commons.math3.fitting.leastsquares.LevenbergMarquardtOptimizer as LevenbergMarquardtOptimizer
|
||||
import org.apache.commons.math3.fitting.leastsquares.GaussNewtonOptimizer as GaussNewtonOptimizer
|
||||
|
||||
import org.apache.commons.math3.stat.regression.SimpleRegression as SimpleRegression
|
||||
|
||||
import org.apache.commons.math3.transform.FastFourierTransformer as FastFourierTransformer
|
||||
import org.apache.commons.math3.transform.DftNormalization as DftNormalization
|
||||
import org.apache.commons.math3.transform.TransformType as TransformType
|
||||
|
||||
import org.apache.commons.math3.linear.ArrayRealVector as ArrayRealVector
|
||||
import org.apache.commons.math3.linear.Array2DRowRealMatrix as Array2DRowRealMatrix
|
||||
import org.apache.commons.math3.linear.MatrixUtils as MatrixUtils
|
||||
|
||||
|
||||
|
||||
###################################################################################################
|
||||
#Derivative and interpolation
|
||||
###################################################################################################
|
||||
|
||||
def get_values(f, xdata):
|
||||
"""Return list of values of a function
|
||||
|
||||
Args:
|
||||
f(UnivariateFunction): function
|
||||
xdata(float array or list): Domain values
|
||||
Returns:
|
||||
List of doubles
|
||||
|
||||
"""
|
||||
v = []
|
||||
for x in xdata:
|
||||
v.append(f.value(x))
|
||||
return v
|
||||
|
||||
def interpolate(data, xdata = None, interpolation_type = "linear"):
|
||||
"""Interpolate data array or list to a UnivariateFunction
|
||||
|
||||
Args:
|
||||
data(float array or list): The values to interpolate
|
||||
xdata(float array or list, optional): Domain values
|
||||
interpolation_type(str , optional): "linear", "cubic", "akima", "neville", "loess", "newton"
|
||||
Returns:
|
||||
UnivariateDifferentiableFunction object
|
||||
|
||||
"""
|
||||
if xdata is None:
|
||||
from startup import frange
|
||||
xdata = frange(0, len(data), 1.0)
|
||||
else:
|
||||
#X must be ordered
|
||||
xy = sorted(zip(xdata,data), key=operator.itemgetter(0))
|
||||
xdata, data = zip(*xy)
|
||||
if len(data) != len(xdata) or len(data)<2:
|
||||
raise Exception("Dimension mismatch")
|
||||
|
||||
if interpolation_type == "cubic":
|
||||
i = SplineInterpolator()
|
||||
elif interpolation_type == "linear":
|
||||
i = LinearInterpolator()
|
||||
elif interpolation_type == "akima":
|
||||
i = AkimaSplineInterpolator()
|
||||
elif interpolation_type == "neville":
|
||||
i = NevilleInterpolator()
|
||||
elif interpolation_type == "loess":
|
||||
i = LoessInterpolator()
|
||||
elif interpolation_type == "newton":
|
||||
i = DividedDifferenceInterpolator()
|
||||
else:
|
||||
raise Exception("Invalid interpolation type")
|
||||
from startup import to_array
|
||||
return i.interpolate(to_array(xdata,'d'), to_array(data,'d'))
|
||||
|
||||
def deriv(f, xdata = None, interpolation_type = "linear"):
|
||||
"""Calculate derivative of UnivariateFunction, array or list.
|
||||
|
||||
Args:
|
||||
f(UnivariateFunction or array): The function object. If array it is interpolated.
|
||||
xdata(float array or list, optional): Domain values to process.
|
||||
interpolation_type(str , optional): "linear", "cubic", "akima", "neville", "loess", "newton"
|
||||
Returns:
|
||||
List with the derivative values for xdata
|
||||
|
||||
"""
|
||||
if not isinstance(f,UnivariateFunction):
|
||||
if xdata is None:
|
||||
from startup import frange
|
||||
xdata = frange(0, len(f), 1.0)
|
||||
f = interpolate(f, xdata, interpolation_type)
|
||||
if xdata is None:
|
||||
if isinstance(f,DifferentiableUnivariateFunction):
|
||||
return f.derivative()
|
||||
raise Exception("Domain range not defined")
|
||||
d = []
|
||||
for x in xdata:
|
||||
xds = DerivativeStructure(1, 2, 0, x)
|
||||
yds = f.value(xds)
|
||||
d.append( yds.getPartialDerivative(1))
|
||||
return d
|
||||
|
||||
def integrate(f, range = None, xdata = None, interpolation_type = "linear", integrator_type = "simpson"):
|
||||
"""Integrate UnivariateFunction, array or list in an interval.
|
||||
|
||||
Args:
|
||||
f(UnivariateFunction or array): The function object. If array it is interpolated.
|
||||
range(list, optional): integration range ([min, max]).
|
||||
xdata(float array or list, optional): disregarded if f is UnivariateFunction.
|
||||
interpolation_type(str , optional): "linear", "cubic", "akima", "neville", "loess", "newton"
|
||||
integrator_type(str , optional): "simpson", "trapezoid", "romberg" or "midpoint"
|
||||
Returns:
|
||||
Integrated value (Float)
|
||||
|
||||
"""
|
||||
if not isinstance(f, UnivariateFunction):
|
||||
from startup import frange
|
||||
if xdata is None:
|
||||
xdata = frange(0, len(f), 1.0)
|
||||
if range is None:
|
||||
range = xdata
|
||||
f = interpolate(f, xdata, interpolation_type)
|
||||
if range is None:
|
||||
raise Exception("Domain range not defined")
|
||||
d = []
|
||||
if integrator_type == "simpson":
|
||||
integrator = SimpsonIntegrator()
|
||||
elif integrator_type == "trapezoid":
|
||||
integrator = TrapezoidIntegrator()
|
||||
elif integrator_type == "romberg":
|
||||
integrator = RombergIntegrator()
|
||||
elif integrator_type == "midpoint":
|
||||
integrator = MidPointIntegrator()
|
||||
raise Exception("Invalid integrator type")
|
||||
lower = min(range)
|
||||
upper = max(range)
|
||||
return integrator.integrate(MAX_EVALUATIONS, f, lower, upper)
|
||||
|
||||
def trapz(y, xdata=None):
|
||||
"""Integrate an array or list using the composite trapezoidal rule.
|
||||
|
||||
Args:
|
||||
y(array or list)
|
||||
xdata(float array or list, optional)
|
||||
"""
|
||||
return integrate(y, range = None, xdata = xdata, interpolation_type = "linear", integrator_type = "trapezoid")
|
||||
|
||||
###################################################################################################
|
||||
#Fitting and peak search
|
||||
###################################################################################################
|
||||
|
||||
try:
|
||||
MAX_FLOAT = sys.float_info.max
|
||||
except: # Python 2.5
|
||||
MAX_FLOAT = 1.7976931348623157e+308
|
||||
|
||||
MAX_ITERATIONS = 1000
|
||||
MAX_EVALUATIONS = 1000000
|
||||
|
||||
def calculate_peaks(function, start_value, end_value = MAX_FLOAT, positive=True):
|
||||
"""Calculate peaks of a DifferentiableUnivariateFunction in a given range by finding the roots of the derivative
|
||||
|
||||
Args:
|
||||
function(DifferentiableUnivariateFunction): The function object.
|
||||
start_value(float): start of range
|
||||
end_value(float, optional): end of range
|
||||
positive (boolean, optional): True for searching positive peaks, False for negative.
|
||||
Returns:
|
||||
List of peaks in the interval
|
||||
|
||||
"""
|
||||
derivative = function.derivative()
|
||||
derivative2 = derivative.derivative()
|
||||
ret = []
|
||||
solver = LaguerreSolver()
|
||||
for complex in solver.solveAllComplex(derivative.coefficients, start_value):
|
||||
r = complex.real
|
||||
if start_value < r < end_value:
|
||||
if (positive and (derivative2.value(r) < 0)) or ( (not positive) and (derivative2.value(r) > 0)):
|
||||
ret.append(r)
|
||||
return ret
|
||||
|
||||
|
||||
def estimate_peak_indexes(data, xdata = None, threshold = None, min_peak_distance = None, positive = True):
|
||||
"""Estimation of peaks in an array by ordering local maxima according to given criteria.
|
||||
|
||||
Args:
|
||||
data(float array or list)
|
||||
xdata(float array or list, optional): if not None must have the same length as data.
|
||||
threshold(float, optional): if specified filter peaks below this value
|
||||
min_peak_distance(float, optional): if specified defines minimum distance between two peaks.
|
||||
if xdata == None, it represents index counts, otherwise in xdata units.
|
||||
positive (boolean, optional): True for searching positive peaks, False for negative.
|
||||
Returns:
|
||||
List of peaks indexes.
|
||||
"""
|
||||
peaks = []
|
||||
indexes = sorted(range(len(data)),key=lambda x:data[x])
|
||||
if positive:
|
||||
indexes = reversed(indexes)
|
||||
for index in indexes:
|
||||
first = (index == 0)
|
||||
last = (index == (len(data)-1))
|
||||
val=data[index]
|
||||
prev = float('NaN') if first else data[index-1]
|
||||
next = float('NaN') if last else data[index+1]
|
||||
|
||||
if threshold is not None:
|
||||
if (positive and (val<threshold)) or ((not positive) and (val>threshold)):
|
||||
break
|
||||
if ( positive and (first or val>prev ) and (last or val>=next ) ) or (
|
||||
(not positive) and (first or val<prev ) and (last or val<=next ) ):
|
||||
append = True
|
||||
if min_peak_distance is not None:
|
||||
for peak in peaks:
|
||||
if ((xdata is None) and (abs(peak-index) < min_peak_distance)) or (
|
||||
(xdata is not None) and (abs(xdata[peak]-xdata[index]) < min_peak_distance)):
|
||||
append = False
|
||||
break
|
||||
if append:
|
||||
peaks.append(index)
|
||||
return peaks
|
||||
|
||||
def _assert_valid_for_fit(y,x):
|
||||
if len(y)<2 or ((x is not None) and (len(x)>len(y))):
|
||||
raise Exception("Invalid data for fit")
|
||||
|
||||
def fit_gaussians(y, x, peak_indexes):
|
||||
"""Fits data on multiple gaussians on the given peak indexes.
|
||||
|
||||
Args:
|
||||
x(float array or list)
|
||||
y(float array or list)
|
||||
peak_indexes(list of int)
|
||||
Returns:
|
||||
List of tuples of gaussian parameters: (normalization, mean, sigma)
|
||||
"""
|
||||
_assert_valid_for_fit(y,x)
|
||||
ret = []
|
||||
|
||||
minimum = min(y)
|
||||
for peak in peak_indexes:
|
||||
#Copy data
|
||||
data = y[:]
|
||||
#Remover data from other peaks
|
||||
for p in peak_indexes:
|
||||
limit = int(round((p+peak)/2))
|
||||
if (p > peak):
|
||||
data[limit : len(y)] =[minimum] * (len(y)-limit)
|
||||
elif (p < peak):
|
||||
data[0:limit] = [minimum] *limit
|
||||
#Build fit point list
|
||||
values = create_fit_point_list(data, x)
|
||||
maximum = max(data)
|
||||
gaussian_fitter = GaussianCurveFitter.create().withStartPoint([(maximum-minimum)/2,x[peak],1.0]).withMaxIterations(MAX_ITERATIONS)
|
||||
#Fit return parameters: (normalization, mean, sigma)
|
||||
try:
|
||||
ret.append(gaussian_fitter.fit(values).tolist())
|
||||
except:
|
||||
ret.append(None) #Fitting error
|
||||
return ret
|
||||
|
||||
|
||||
def create_fit_point_list(y, x, weights = None):
|
||||
values = []
|
||||
for i in sorted(range(len(x)),key=lambda v:x[v]): #Creating list ordered by x, needed for gauss fit
|
||||
if weights is None:
|
||||
values.append(WeightedObservedPoint(1.0, x[i], y[i]))
|
||||
else:
|
||||
values.append(WeightedObservedPoint(weights[i], x[i], y[i]))
|
||||
return values
|
||||
|
||||
def fit_polynomial(y, x, order, start_point = None, weights = None):
|
||||
"""Fits data into a polynomial.
|
||||
|
||||
Args:
|
||||
x(float array or list): observed points x
|
||||
y(float array or list): observed points y
|
||||
order(int): if start_point is provided order parameter is disregarded - set to len(start_point)-1.
|
||||
start_point(optional tuple of float): initial parameters (a0, a1, a2, ...)
|
||||
weights(optional float array or list): weight for each observed point
|
||||
Returns:
|
||||
Tuples of polynomial parameters: (a0, a1, a2, ...)
|
||||
"""
|
||||
_assert_valid_for_fit(y,x)
|
||||
fit_point_list = create_fit_point_list(y, x, weights)
|
||||
if start_point is None:
|
||||
polynomial_fitter = PolynomialCurveFitter.create(order).withMaxIterations(MAX_ITERATIONS)
|
||||
else:
|
||||
polynomial_fitter = PolynomialCurveFitter.create(0).withStartPoint(start_point).withMaxIterations(MAX_ITERATIONS)
|
||||
try:
|
||||
return polynomial_fitter.fit(fit_point_list).tolist()
|
||||
except:
|
||||
raise Exception("Fitting failure")
|
||||
|
||||
def fit_gaussian(y, x, start_point = None, weights = None):
|
||||
"""Fits data into a gaussian.
|
||||
|
||||
Args:
|
||||
x(float array or list): observed points x
|
||||
y(float array or list): observed points y
|
||||
start_point(optional tuple of float): initial parameters (normalization, mean, sigma)
|
||||
If None, use a custom initial estimation.
|
||||
Set to "default" to force Commons.Math the default (GaussianCurveFitter.ParameterGuesser).
|
||||
weights(optional float array or list): weight for each observed point
|
||||
Returns:
|
||||
Tuples of gaussian parameters: (normalization, mean, sigma)
|
||||
"""
|
||||
_assert_valid_for_fit(y,x)
|
||||
fit_point_list = create_fit_point_list(y, x, weights)
|
||||
|
||||
#If start point not provided, start on peak
|
||||
if start_point is None:
|
||||
maximum, minimum = max(y), min(y)
|
||||
norm = maximum - minimum
|
||||
mean = x[y.index(maximum)]
|
||||
sigma = trapz([v-minimum for v in y], x) / (norm*math.sqrt(2*math.pi))
|
||||
start_point = (norm, mean, sigma)
|
||||
elif start_point == "simple":
|
||||
start_point = [(max(y)-min(y))/2, x[y.index(max(y))], 1.0]
|
||||
elif start_point == "default":
|
||||
start_point = GaussianCurveFitter.ParameterGuesser(fit_point_list).guess().tolist()
|
||||
gaussian_fitter = GaussianCurveFitter.create().withStartPoint(start_point).withMaxIterations(MAX_ITERATIONS)
|
||||
try:
|
||||
return gaussian_fitter.fit(fit_point_list).tolist() # (normalization, mean, sigma)
|
||||
except:
|
||||
raise Exception("Fitting failure")
|
||||
|
||||
def fit_harmonic(y, x, start_point = None, weights = None):
|
||||
"""Fits data into an harmonic.
|
||||
|
||||
Args:
|
||||
x(float array or list): observed points x
|
||||
y(float array or list): observed points y
|
||||
start_point(optional tuple of float): initial parameters (amplitude, angular_frequency, phase)
|
||||
weights(optional float array or list): weight for each observed point
|
||||
Returns:
|
||||
Tuples of harmonic parameters: (amplitude, angular_frequency, phase)
|
||||
"""
|
||||
_assert_valid_for_fit(y,x)
|
||||
fit_point_list = create_fit_point_list(y, x, weights)
|
||||
if start_point is None:
|
||||
harmonic_fitter = HarmonicCurveFitter.create().withMaxIterations(MAX_ITERATIONS)
|
||||
else:
|
||||
harmonic_fitter = HarmonicCurveFitter.create().withStartPoint(start_point).withMaxIterations(MAX_ITERATIONS)
|
||||
try:
|
||||
return harmonic_fitter.fit(fit_point_list).tolist() # (amplitude, angular_frequency, phase)
|
||||
except:
|
||||
raise Exception("Fitting failure")
|
||||
|
||||
|
||||
def fit_gaussian_offset(y, x, start_point = None, weights = None):
|
||||
"""Fits data into a gaussian with offset (constant background).
|
||||
f(x) = a + b * exp(-(pow((x - c), 2) / (2 * pow(d, 2))))
|
||||
|
||||
Args:
|
||||
x(float array or list): observed points x
|
||||
y(float array or list): observed points y
|
||||
start_point(optional tuple of float): initial parameters (normalization, mean, sigma)
|
||||
weights(optional float array or list): weight for each observed point
|
||||
Returns:
|
||||
Tuples of gaussian parameters: (offset, normalization, mean, sigma)
|
||||
"""
|
||||
|
||||
# For normalised gauss curve sigma=1/(amp*sqrt(2*pi))
|
||||
if start_point is None:
|
||||
off = min(y) # good enough starting point for offset
|
||||
com = x[y.index(max(y))]
|
||||
amp = max(y) - off
|
||||
sigma = trapz([v-off for v in y], x) / (amp*math.sqrt(2*math.pi))
|
||||
start_point = [off, amp, com , sigma]
|
||||
|
||||
class Model(MultivariateJacobianFunction):
|
||||
def value(self, variables):
|
||||
value = ArrayRealVector(len(x))
|
||||
jacobian = Array2DRowRealMatrix(len(x), 4)
|
||||
for i in range(len(x)):
|
||||
(a,b,c,d) = (variables.getEntry(0), variables.getEntry(1), variables.getEntry(2), variables.getEntry(3))
|
||||
v = math.exp(-(math.pow((x[i] - c), 2) / (2 * math.pow(d, 2))))
|
||||
model = a + b * v
|
||||
value.setEntry(i, model)
|
||||
jacobian.setEntry(i, 0, 1) # derivative with respect to p0 = a
|
||||
jacobian.setEntry(i, 1, v) # derivative with respect to p1 = b
|
||||
v2 = b*v*((x[i] - c)/math.pow(d, 2))
|
||||
jacobian.setEntry(i, 2, v2) # derivative with respect to p2 = c
|
||||
jacobian.setEntry(i, 3, v2*(x[i] - c)/d ) # derivative with respect to p3 = d
|
||||
return Pair(value, jacobian)
|
||||
|
||||
model = Model()
|
||||
target = [v for v in y] #the target is to have all points at the positios
|
||||
(parameters, residuals, rms, evals, iters) = optimize_least_squares(model, target, start_point, weights)
|
||||
return parameters
|
||||
|
||||
|
||||
def fit_gaussian_linear(y, x, start_point = None, weights = None):
|
||||
"""Fits data into a gaussian with linear background.
|
||||
f(x) = a * x + b + c * exp(-(pow((x - d), 2) / (2 * pow(e, 2))))
|
||||
|
||||
Args:
|
||||
x(float array or list): observed points x
|
||||
y(float array or list): observed points y
|
||||
start_point(optional tuple of float): initial parameters (normalization, mean, sigma)
|
||||
weights(optional float array or list): weight for each observed point
|
||||
Returns:
|
||||
Tuples of gaussian parameters: (a, b, normalization, mean, sigma)
|
||||
"""
|
||||
|
||||
# For normalised gauss curve sigma=1/(amp*sqrt(2*pi))
|
||||
if start_point is None:
|
||||
off = min(y) # good enough starting point for offset
|
||||
com = x[y.index(max(y))]
|
||||
amp = max(y) - off
|
||||
sigma = trapz([v-off for v in y], x) / (amp*math.sqrt(2*math.pi))
|
||||
start_point = [0, off, amp, com, sigma]
|
||||
|
||||
class Model(MultivariateJacobianFunction):
|
||||
def value(self, variables):
|
||||
value = ArrayRealVector(len(x))
|
||||
jacobian = Array2DRowRealMatrix(len(x), 5)
|
||||
for i in range(len(x)):
|
||||
(a,b,c,d,e) = (variables.getEntry(0), variables.getEntry(1), variables.getEntry(2), variables.getEntry(3), variables.getEntry(4))
|
||||
v = math.exp(-(math.pow((x[i] - d), 2) / (2 * math.pow(e, 2))))
|
||||
model = a*x[i] + b + c * v
|
||||
value.setEntry(i, model)
|
||||
jacobian.setEntry(i, 0, x[i]) # derivative with respect to p0 = a
|
||||
jacobian.setEntry(i, 1, 1) # derivative with respect to p1 = b
|
||||
jacobian.setEntry(i, 2, v) # derivative with respect to p2 = c
|
||||
v2 = c*v*((x[i] - d)/math.pow(e, 2))
|
||||
jacobian.setEntry(i, 3, v2) # derivative with respect to p3 = d
|
||||
jacobian.setEntry(i, 4, v2*(x[i] - d)/e ) # derivative with respect to p4 = e
|
||||
return Pair(value, jacobian)
|
||||
|
||||
model = Model()
|
||||
target = [v for v in y] #the target is to have all points at the positios
|
||||
(parameters, residuals, rms, evals, iters) = optimize_least_squares(model, target, start_point, weights)
|
||||
return parameters
|
||||
|
||||
def fit_gaussian_exp_bkg(y, x, start_point = None, weights = None):
|
||||
"""Fits data into a gaussian with exponential background.
|
||||
f(x) = a * math.exp(-(x/b)) + c * exp(-(pow((x - d), 2) / (2 * pow(e, 2))))
|
||||
|
||||
Args:
|
||||
x(float array or list): observed points x
|
||||
y(float array or list): observed points y
|
||||
start_point(optional tuple of float): initial parameters (normalization, mean, sigma)
|
||||
weights(optional float array or list): weight for each observed point
|
||||
Returns:
|
||||
Tuples of gaussian parameters: (a,b , normalization, mean, sigma)
|
||||
"""
|
||||
|
||||
# For normalised gauss curve sigma=1/(amp*sqrt(2*pi))
|
||||
if start_point is None:
|
||||
off = min(y) # good enough starting point for offset
|
||||
com = x[len(x)/2]
|
||||
#com = 11.9
|
||||
amp = max(y) - off
|
||||
sigma = trapz([v-off for v in y], x) / (amp*math.sqrt(2*math.pi))
|
||||
start_point = [1, 1, amp, com, sigma]
|
||||
|
||||
class Model(MultivariateJacobianFunction):
|
||||
def value(self, variables):
|
||||
value = ArrayRealVector(len(x))
|
||||
jacobian = Array2DRowRealMatrix(len(x), 5)
|
||||
for i in range(len(x)):
|
||||
(a,b,c,d,e) = (variables.getEntry(0), variables.getEntry(1), variables.getEntry(2), variables.getEntry(3), variables.getEntry(4))
|
||||
v = math.exp(-(math.pow((x[i] - d), 2) / (2 * math.pow(e, 2))))
|
||||
bkg=math.exp(-(x[i]/b))
|
||||
model = a*bkg + c * v
|
||||
value.setEntry(i, model)
|
||||
jacobian.setEntry(i, 0, bkg) # derivative with respect to p0 = a
|
||||
jacobian.setEntry(i, 1, a*x[i]*bkg/math.pow(b, 2)) # derivative with respect to p1 = b
|
||||
jacobian.setEntry(i, 2, v) # derivative with respect to p2 = c
|
||||
v2 = c*v*((x[i] - d)/math.pow(e, 2))
|
||||
jacobian.setEntry(i, 3, v2) # derivative with respect to p3 = d
|
||||
jacobian.setEntry(i, 4, v2*(x[i] - d)/e ) # derivative with respect to p4 = e
|
||||
return Pair(value, jacobian)
|
||||
|
||||
model = Model()
|
||||
target = [v for v in y] #the target is to have all points at the positios
|
||||
(parameters, residuals, rms, evals, iters) = optimize_least_squares(model, target, start_point, weights)
|
||||
return parameters
|
||||
|
||||
###################################################################################################
|
||||
#Functions
|
||||
###################################################################################################
|
||||
|
||||
class GaussianOffset(UnivariateFunction):
|
||||
def __init__(self, offset, normalization, mean_value, sigma):
|
||||
self.gaussian = Gaussian(normalization, mean_value, sigma)
|
||||
self.offset = offset
|
||||
def value(self,x):
|
||||
return self.gaussian.value(x) + self.offset
|
||||
|
||||
class GaussianLinear(UnivariateFunction):
|
||||
def __init__(self, a,b, normalization, mean_value, sigma):
|
||||
self.gaussian = Gaussian(normalization, mean_value, sigma)
|
||||
self.a = a
|
||||
self.b = b
|
||||
def value(self,x):
|
||||
return self.gaussian.value(x) + self.a * x + self.b
|
||||
|
||||
class GaussianExpBkg(UnivariateFunction):
|
||||
def __init__(self, a, b, normalization, mean_value, sigma):
|
||||
self.gaussian = Gaussian(normalization, mean_value, sigma)
|
||||
self.a = a
|
||||
self.b = b
|
||||
def value(self,x):
|
||||
return self.gaussian.value(x) + self.a * math.exp(-(x/self.b))
|
||||
|
||||
###################################################################################################
|
||||
#Least squares
|
||||
###################################################################################################
|
||||
|
||||
def optimize_least_squares(model, target, initial, weights):
|
||||
"""Fits a parametric model to a set of observed values by minimizing a cost function.
|
||||
|
||||
Args:
|
||||
model(MultivariateJacobianFunction): observed points x
|
||||
target(float array or list): observed data
|
||||
initial(optional tuple of float): initial guess
|
||||
weights(optional float array or list): weight for each observed point
|
||||
Returns:
|
||||
Tuples of harmonic parameters: (amplitude, angular_frequency, phase)
|
||||
"""
|
||||
if isinstance(weights,tuple) or isinstance(weights,list):
|
||||
weights = MatrixUtils.createRealDiagonalMatrix(weights)
|
||||
problem = LeastSquaresBuilder().start(initial).model(model).target(target).lazyEvaluation(False).maxEvaluations(MAX_EVALUATIONS).maxIterations(MAX_ITERATIONS).weight(weights).build()
|
||||
optimizer = LevenbergMarquardtOptimizer()
|
||||
optimum = optimizer.optimize(problem)
|
||||
|
||||
parameters=optimum.getPoint().toArray().tolist()
|
||||
residuals = optimum.getResiduals().toArray().tolist()
|
||||
rms = optimum.getRMS()
|
||||
evals = optimum.getEvaluations()
|
||||
iters = optimum.getIterations()
|
||||
return (parameters, residuals, rms, evals, iters)
|
||||
|
||||
|
||||
###################################################################################################
|
||||
#FFT
|
||||
###################################################################################################
|
||||
|
||||
def is_power(num, base):
|
||||
if base<=1: return num == 1
|
||||
power = int (math.log (num, base) + 0.5)
|
||||
return base ** power == num
|
||||
|
||||
def pad_to_power_of_two(data):
|
||||
if is_power(len(data),2):
|
||||
return data
|
||||
pad =(1 << len(data).bit_length()) - len(data)
|
||||
elem = complex(0,0) if type(data[0]) is complex else [0.0,]
|
||||
return data + elem * pad
|
||||
|
||||
def get_real(values):
|
||||
"""Returns real part of a complex numbers vector.
|
||||
Args:
|
||||
values: List of complex.
|
||||
Returns:
|
||||
List of float
|
||||
"""
|
||||
ret = []
|
||||
for c in values:
|
||||
ret.append(c.real)
|
||||
return ret
|
||||
|
||||
def get_imag(values):
|
||||
"""Returns imaginary part of a complex numbers vector.
|
||||
Args:
|
||||
values: List of complex.
|
||||
Returns:
|
||||
List of float
|
||||
"""
|
||||
ret = []
|
||||
for c in values:
|
||||
ret.append(c.imag)
|
||||
return ret
|
||||
|
||||
def get_modulus(values):
|
||||
"""Returns the modulus of a complex numbers vector.
|
||||
Args:
|
||||
values: List of complex.
|
||||
Returns:
|
||||
List of float
|
||||
"""
|
||||
ret = []
|
||||
for c in values:
|
||||
ret.append(math.hypot(c.imag,c.real))
|
||||
return ret
|
||||
|
||||
def get_phase(values):
|
||||
"""Returns the phase of a complex numbers vector.
|
||||
Args:
|
||||
values: List of complex.
|
||||
Returns:
|
||||
List of float
|
||||
"""
|
||||
ret = []
|
||||
for c in values:
|
||||
ret.append(math.atan(c.imag/c.real))
|
||||
return ret
|
||||
|
||||
def fft(f):
|
||||
"""Calculates the Fast Fourrier Transform of a vector, padding to the next power of 2 elements.
|
||||
Args:
|
||||
values(): List of float or complex
|
||||
Returns:
|
||||
List of complex
|
||||
"""
|
||||
f = pad_to_power_of_two(f)
|
||||
if type(f[0]) is complex:
|
||||
aux = []
|
||||
for c in f:
|
||||
aux.append(Complex(c.real, c.imag))
|
||||
f = aux
|
||||
fftt = FastFourierTransformer(DftNormalization.STANDARD)
|
||||
ret = []
|
||||
for c in fftt.transform(f,TransformType.FORWARD ):
|
||||
ret.append(complex(c.getReal(),c.getImaginary()))
|
||||
return ret
|
||||
|
||||
def ffti(f):
|
||||
"""Calculates the Inverse Fast Fourrier Transform of a vector, padding to the next power of 2 elements.
|
||||
Args:
|
||||
values(): List of float or complex
|
||||
Returns:
|
||||
List of complex
|
||||
"""
|
||||
f = pad_to_power_of_two(f)
|
||||
if type(f[0]) is complex:
|
||||
aux = []
|
||||
for c in f:
|
||||
aux.append(Complex(c.real, c.imag))
|
||||
f = aux
|
||||
fftt = FastFourierTransformer(DftNormalization.STANDARD)
|
||||
ret = []
|
||||
for c in fftt.transform(f,TransformType.INVERSE ):
|
||||
ret.append(complex(c.getReal(),c.getImaginary()))
|
||||
return ret
|
||||
119
script/Lib/plotutils.py
Normal file
119
script/Lib/plotutils.py
Normal file
@@ -0,0 +1,119 @@
|
||||
###################################################################################################
|
||||
# Plot utilities
|
||||
###################################################################################################
|
||||
|
||||
import ch.psi.pshell.plot.LinePlotSeries as LinePlotSeries
|
||||
import ch.psi.pshell.plot.LinePlotErrorSeries as LinePlotErrorSeries
|
||||
import math
|
||||
from startup import frange, to_array
|
||||
|
||||
def plot_function(plot, function, name, range, show_points = True, show_lines = True, color = None):
|
||||
"""Plots a function to a plot.
|
||||
|
||||
Args:
|
||||
plot(LinePlot)
|
||||
function(UnivariateFunction): Gaussian, PolynomialFunction, HarmonicOscillator...
|
||||
name(str): name of the series
|
||||
range(list or array of floats): x values to plot
|
||||
Returns:
|
||||
Tuples of harmonic parameters: (amplitude, angular_frequency, phase)
|
||||
"""
|
||||
if plot.style.isError():
|
||||
s = LinePlotErrorSeries(name, color)
|
||||
else:
|
||||
s = LinePlotSeries(name, color)
|
||||
plot.addSeries(s)
|
||||
s.setPointsVisible(show_points)
|
||||
s.setLinesVisible(show_lines)
|
||||
for x in range:
|
||||
s.appendData(x, function.value(x))
|
||||
return s
|
||||
|
||||
def plot_data(plot, data, name, xdata = None, error = None, show_points = True, show_lines = True, color = None):
|
||||
"""Plots a subscriptable object to a plot.
|
||||
|
||||
Args:
|
||||
plot(LinePlot)
|
||||
data(subscriptable): Y data
|
||||
name(str): name of the series
|
||||
xdata(subscriptable): X data
|
||||
error(subscriptable): Error data (only for error plots)
|
||||
Returns:
|
||||
Tuples of harmonic parameters: (amplitude, angular_frequency, phase)
|
||||
"""
|
||||
if plot.style.isError():
|
||||
s = LinePlotErrorSeries(name, color)
|
||||
else:
|
||||
s = LinePlotSeries(name, color)
|
||||
plot.addSeries(s)
|
||||
s.setPointsVisible(show_points)
|
||||
s.setLinesVisible(show_lines)
|
||||
if xdata is None:
|
||||
xdata = range(len(data))
|
||||
xdata = to_array(xdata, 'd')
|
||||
data = to_array(data, 'd')
|
||||
if plot.style.isError():
|
||||
error = to_array(error, 'd')
|
||||
s.setData(xdata, data, error)
|
||||
else:
|
||||
s.setData(xdata, data)
|
||||
return s
|
||||
|
||||
def plot_point(plot, x, y, size = 3, color = None, name = "Point"):
|
||||
s = LinePlotSeries(name, color)
|
||||
plot.addSeries(s)
|
||||
s.setPointSize(size)
|
||||
s.appendData(x, y)
|
||||
return s
|
||||
|
||||
def plot_line(plot, x1, y1, x2, y2, width = 1, color = None, name = "Line"):
|
||||
s = LinePlotSeries(name, color)
|
||||
plot.addSeries(s)
|
||||
s.setLineWidth(width)
|
||||
s.setPointsVisible(False)
|
||||
s.appendData(x1, y1)
|
||||
s.appendData(x2, y2)
|
||||
return s
|
||||
|
||||
def plot_cross(plot, x, y, size = 1.0, width = 1, color = None, name = "Cross"):
|
||||
size = float(size)
|
||||
s = LinePlotSeries(name, color)
|
||||
plot.addSeries(s)
|
||||
s.setLineWidth(width)
|
||||
s.setPointsVisible(False)
|
||||
s.appendData(float('nan'), float('nan'))
|
||||
s.appendData(x-size/2, y)
|
||||
s.appendData(x+size/2, y)
|
||||
s.appendData(float('nan'), float('nan'))
|
||||
s.appendData(x, y-size/2)
|
||||
s.appendData(x, y+size/2)
|
||||
return s
|
||||
|
||||
def plot_rectangle(plot, x1, y1, x2, y2, width = 1, color = None, name = "Rectangle"):
|
||||
s = LinePlotSeries(name, color)
|
||||
plot.addSeries(s)
|
||||
s.setLineWidth(width)
|
||||
s.setPointsVisible(False)
|
||||
s.appendData(x1, y1)
|
||||
s.appendData(x1, y2)
|
||||
s.appendData(x2, y2)
|
||||
s.appendData(x2, y1)
|
||||
s.appendData(x1, y1)
|
||||
return s
|
||||
|
||||
def plot_circle(plot, cx, cy, radius, width = 1, color = None, name = "Circle"):
|
||||
s = LinePlotSeries(name, color)
|
||||
plot.addSeries(s)
|
||||
s.setLineWidth(width)
|
||||
s.setPointsVisible(False)
|
||||
res=float(radius) / 100.0
|
||||
epson = 1e-12
|
||||
for xp in frange (cx+radius-epson , cx-radius+epson , -res):
|
||||
yp = math.sqrt(math.pow(radius, 2) - math.pow(xp - cx, 2)) + cy
|
||||
s.appendData(xp, yp)
|
||||
for xp in frange (cx-radius+epson , cx+radius-epson, res):
|
||||
yp = -math.sqrt(math.pow(radius, 2) - math.pow(xp - cx, 2)) + cy
|
||||
s.appendData(xp, yp)
|
||||
if s.getCount()>0:
|
||||
s.appendData(s.getX()[0], s.getY()[0])
|
||||
return s
|
||||
149
script/Lib/rsync.py
Normal file
149
script/Lib/rsync.py
Normal file
@@ -0,0 +1,149 @@
|
||||
####################################################################################################
|
||||
# Utilities for synchronizing folders with rsync
|
||||
# On RH7 (not SL6)
|
||||
# Change permission of the account, otherwise SSH keys are not accepted:
|
||||
# ~/.ssh from drwxr-S--- to drwx----
|
||||
# ~ : from drwxrws--- to drwxr-s---
|
||||
####################################################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import shutil
|
||||
import ch.psi.utils.Sys
|
||||
|
||||
from startup import exec_cmd, log
|
||||
|
||||
RSYNC_GENERATE_USER_KEY = True
|
||||
XTERM = "/opt/X11/bin/xterm" if ch.psi.utils.Sys.getOSFamily().name()=="Mac" else "xterm"
|
||||
|
||||
def rsync(src, dest, key):
|
||||
#cmd = 'rsync -e "ssh -i ' + key + ' -o LogLevel=quiet" --chmod=ug=rwx --verbose --modify-window=1 --times --recursive ' + src + ' ' + dest
|
||||
#ret = exec_cmd(cmd)
|
||||
cmd = 'rsync -e "ssh -i ' + key + '" --chmod=ug=rwx --verbose --modify-window=1 --times --recursive ' + src + ' ' + dest
|
||||
ret = exec_cmd(cmd, False)
|
||||
lines = ret.split("\n")
|
||||
lines = filter(lambda x: x != "", lines)
|
||||
if len(lines)<3:
|
||||
print "Invalid return from rsync:\n", ret
|
||||
raise Exception ("Invalid format")
|
||||
#files = lines[1:-2]
|
||||
files = []
|
||||
head,tail=os.path.split(src)
|
||||
for l in lines:
|
||||
f = os.path.join(head,l)
|
||||
if os.path.exists(f):
|
||||
files.append(f)
|
||||
try:
|
||||
stats = lines[-2].replace(",", "").replace(".", "")
|
||||
stats = [int(s) for s in stats.split() if s.isdigit()]
|
||||
bytes_sent, bytes_received = stats[0], stats[1]
|
||||
except:
|
||||
print "Invalid statistics from rsync:\n", ret
|
||||
bytes_sent, bytes_received = None, None
|
||||
|
||||
return files, bytes_sent, bytes_received
|
||||
|
||||
def sync_user_data(user, src, dest, host= "localhost", remove_local_folder=False, remove_local_files=False, do_log=True, do_print=True):
|
||||
try:
|
||||
if do_log:
|
||||
log("Start synchronizing %s to %s:%s" % (src, user, dest), False )
|
||||
key = os.path.expanduser("~/.ssh/" + ("ke" if RSYNC_GENERATE_USER_KEY else "id_rsa"))
|
||||
if not os.path.isfile(key):
|
||||
raise Exception ("Invalid key file")
|
||||
dest = "'" + dest.replace(" ", "\ ") + "'"
|
||||
dest = user + "@" + host + ":" + dest
|
||||
files, bytes_sent, bytes_received = rsync(src,dest,key)
|
||||
msg = "Transferred " + str(bytes_sent) + " bytes to " + user + ": "
|
||||
for f in files:
|
||||
msg = msg + "\n" + f
|
||||
if do_log:
|
||||
log(msg, False)
|
||||
if do_print:
|
||||
print msg
|
||||
if remove_local_folder:
|
||||
if do_log:
|
||||
log("Removing folder: " + src)
|
||||
shutil.rmtree(src)
|
||||
elif remove_local_files:
|
||||
for f in files:
|
||||
if not os.path.samefile(f, src):
|
||||
if os.path.isfile(f):
|
||||
if do_log:
|
||||
log("Removing file: " + f)
|
||||
os.remove(f)
|
||||
elif os.path.isdir(f):
|
||||
if do_log:
|
||||
log("Removing folder: " + f)
|
||||
shutil.rmtree(f)
|
||||
|
||||
except:
|
||||
msg = "Error transferring user data to " + user + ": " + str(sys.exc_info()[1])
|
||||
if do_log:
|
||||
log(msg, False)
|
||||
if do_print:
|
||||
print >> sys.stderr, msg
|
||||
return msg
|
||||
|
||||
def remove_user_key(do_print=True):
|
||||
cmd = "rm ~/.ssh/ke;"
|
||||
cmd = cmd + "rm ~/.ssh/ke.pub"
|
||||
ret = exec_cmd(cmd, False)
|
||||
if do_print:
|
||||
if not ret.strip():
|
||||
ret = "Success removing ssh keys"
|
||||
print ret
|
||||
|
||||
def reset_user_key(do_print=True):
|
||||
remove_user_key(do_print)
|
||||
cmd = "ssh-keygen -N '' -f ~/.ssh/ke -t rsa;"
|
||||
ret = exec_cmd(cmd)
|
||||
if do_print:
|
||||
print ret
|
||||
|
||||
def authorize_user(user, aux_file = os.path.expanduser("~/.rsync.tmp"), fix_permissions=True, do_print=True):
|
||||
if (os.path.isfile(aux_file)):
|
||||
os.remove(aux_file)
|
||||
with open(aux_file, "w") as fh:
|
||||
fh.write("Cannot access file: " + aux_file)
|
||||
os.chmod(aux_file, 0o777)
|
||||
|
||||
success_msg = 'Success transfering authorization key for: ' + user
|
||||
cmd = 'echo Authorizing: ' + user + ";"
|
||||
cmd = cmd + 'echo Invalid user or password > ' + aux_file + ";"
|
||||
cmd = cmd + "export PK_SUCCESS=FAILURE;"
|
||||
if RSYNC_GENERATE_USER_KEY:
|
||||
reset_user_key(do_print)
|
||||
cmd = cmd + "export PK=`cat ~/.ssh/ke.pub`;"
|
||||
else:
|
||||
cmd = cmd + "export PK=`cat ~/.ssh/id_rsa.pub`;"
|
||||
cmd = cmd + 'su - ' + user + ' bash -c "'
|
||||
cmd = cmd + 'echo $PK >> .ssh/authorized_keys;'
|
||||
#cmd = cmd + 'sort .ssh/authorized_keys | uniq > .ssh/authorized_keys.uniq;'
|
||||
#cmd = cmd + 'mv .ssh/authorized_keys.uniq .ssh/authorized_keys;'
|
||||
if fix_permissions:
|
||||
cmd = cmd + 'chmod g-w ~' + ";"
|
||||
cmd = cmd + 'echo ' + success_msg + ";"
|
||||
cmd = cmd + 'echo ' + success_msg + " > " + aux_file + ";"
|
||||
cmd = cmd + '"'
|
||||
#xterm_options = '-hold -T "Authentication" -into 44040199' #Get Winfow ID with 'wmctrl -lp'
|
||||
xterm_options = '-T "Authentication" -fa monaco -fs 14 -bg black -fg green -geometry 80x15+400+100'
|
||||
try:
|
||||
ret = exec_cmd(XTERM + " " + xterm_options + " -e '" + cmd + "'")
|
||||
with open (aux_file, "r") as myfile:
|
||||
ret=myfile.read()
|
||||
#;if [ "$depth" -eq "1" ]; then echo ' + success_msg + '; fi')
|
||||
if not success_msg in ret:
|
||||
raise Exception (ret)
|
||||
except:
|
||||
if RSYNC_GENERATE_USER_KEY:
|
||||
remove_user_key(do_print)
|
||||
raise Exception ("Error authenticating user: " + str(sys.exc_info()[1]))
|
||||
finally:
|
||||
if (os.path.isfile(aux_file)):
|
||||
os.remove(aux_file)
|
||||
return ret
|
||||
|
||||
def is_authorized():
|
||||
key = os.path.expanduser("~/.ssh/" + ("ke" if RSYNC_GENERATE_USER_KEY else "id_rsa"))
|
||||
return os.path.isfile(key)
|
||||
348
script/Lib/sessions.py
Normal file
348
script/Lib/sessions.py
Normal file
@@ -0,0 +1,348 @@
|
||||
from startup import get_context, set_exec_pars
|
||||
import ch.psi.utils.SciCat as SciCat
|
||||
import java.lang.Boolean
|
||||
|
||||
def _sm():
|
||||
return get_context().sessionManager
|
||||
|
||||
|
||||
def session_start(name, metadata=None):
|
||||
""" Starts new session. If a session os open, completes it first.
|
||||
|
||||
Args:
|
||||
name(str): Session name.
|
||||
metadata(dict): Map of initial metadata parameters
|
||||
If None(Default) use the default metadata definition.
|
||||
|
||||
Returns:
|
||||
session id (int)
|
||||
"""
|
||||
set_exec_pars(open=False)
|
||||
return _sm().start(name, metadata)
|
||||
|
||||
def session_complete():
|
||||
""" Completes current session, if started.
|
||||
"""
|
||||
set_exec_pars(open=False)
|
||||
return _sm().stop()
|
||||
|
||||
def session_pause():
|
||||
""" Pauses current session, if started.
|
||||
"""
|
||||
return _sm().pause()
|
||||
|
||||
def session_resume():
|
||||
""" Resumes current session, if paused.
|
||||
"""
|
||||
return _sm().resume()
|
||||
|
||||
def session_cancel():
|
||||
""" Cancels current session, if started and empty (no generated data).
|
||||
"""
|
||||
return _sm().cancel()
|
||||
|
||||
def session_restart(id):
|
||||
""" Reopens a completed if not yet archived and if belongs to the same user.
|
||||
|
||||
Args:
|
||||
id(int): Session id.
|
||||
"""
|
||||
return _sm().restart(id)
|
||||
|
||||
def session_move(origin, files, dest):
|
||||
""" Moves a list of run files (relative to root) to another session.
|
||||
Sessions must not be archived and belong to the same user.
|
||||
|
||||
Args:
|
||||
origin(int): Origin session id.
|
||||
files(list): file names
|
||||
dest(int): Destination session id.
|
||||
"""
|
||||
return _sm().move(origin, files, dest)
|
||||
|
||||
def session_detach(name, id, files):
|
||||
""" Detaches a list of run files (relative to root) to a new session.
|
||||
Session must not be archived and belong to the same user.
|
||||
|
||||
Args:
|
||||
name(str): Name of new session.
|
||||
id(int): Session id.
|
||||
files(list): file names
|
||||
|
||||
Returns:
|
||||
New session id (int)
|
||||
"""
|
||||
return _sm().detach(name, id, files)
|
||||
|
||||
|
||||
def session_create(name, files, metadata=None, root=None):
|
||||
""" Create a session from existing data files.
|
||||
|
||||
Args:
|
||||
name(str): Name of new session.
|
||||
files(list): file names relative to root
|
||||
metadata(dict): Map of initial metadata parameters
|
||||
If None(Default) use the default metadata definition.
|
||||
root(str): data root path. If None(Default) uses default data path.
|
||||
|
||||
Returns:
|
||||
New session id (int)
|
||||
"""
|
||||
return _sm().create(name, files, metadata, root)
|
||||
|
||||
def session_id():
|
||||
""" Returns current session id (0 if no session is started).
|
||||
|
||||
Returns:
|
||||
session id (int)
|
||||
"""
|
||||
return _sm().getCurrentSession()
|
||||
|
||||
|
||||
def session_name():
|
||||
""" Returns current session name ("unknown" if no session is started)
|
||||
|
||||
Returns:
|
||||
session name(str)
|
||||
"""
|
||||
return _sm().getCurrentName()
|
||||
|
||||
def session_started():
|
||||
""" Returns true if a session is started.
|
||||
|
||||
Returns:
|
||||
bool
|
||||
"""
|
||||
return _sm().isStarted()
|
||||
|
||||
def session_paused():
|
||||
""" Returns true if current session is paused.
|
||||
|
||||
Returns:
|
||||
bool
|
||||
"""
|
||||
return _sm().isPaused()
|
||||
|
||||
|
||||
def session_add_file(path):
|
||||
""" Adds additional file to session, if started.
|
||||
|
||||
Args:
|
||||
path(str): Relative to data path or absolute.
|
||||
"""
|
||||
return _sm().addAdditionalFile(path)
|
||||
|
||||
|
||||
def session_ids():
|
||||
""" Returns list of completed sessions.
|
||||
|
||||
Returns:
|
||||
list of int
|
||||
"""
|
||||
return _sm().getIDs()
|
||||
|
||||
def session_get_name(id=None):
|
||||
""" Return the name of a session.
|
||||
|
||||
Args:
|
||||
id(int): Session id. Default (None) is the current session.
|
||||
|
||||
Returns:
|
||||
session name (str)
|
||||
"""
|
||||
return _sm().getName() if id is None else _sm().getName(id)
|
||||
|
||||
|
||||
def session_get_state(id=None):
|
||||
""" Returns the session state
|
||||
|
||||
Args:
|
||||
id(int): Session id. Default (None) is the current session.
|
||||
|
||||
Returns:
|
||||
session state (str)
|
||||
"""
|
||||
return _sm().getState() if id is None else _sm().getState(id)
|
||||
|
||||
def session_get_start(id=None):
|
||||
""" Returns the start timestamp of a session.
|
||||
|
||||
Args:
|
||||
id(int): Session id. Default (None) is the current session.
|
||||
|
||||
Returns:
|
||||
long
|
||||
"""
|
||||
return _sm().getStart() if id is None else _sm().getStart(id)
|
||||
|
||||
def session_get_stop(id):
|
||||
""" Returns the stop timestamp of a completed session.
|
||||
|
||||
Args:
|
||||
id(int): Session id.
|
||||
Returns:
|
||||
Timestamp (long)
|
||||
"""
|
||||
return _sm().getStop(id)
|
||||
|
||||
def session_get_root(id=None):
|
||||
""" Returns the root data path of a session.
|
||||
|
||||
Args:
|
||||
id(int): Session id. Default (None) is the current session.
|
||||
|
||||
Returns:
|
||||
str
|
||||
"""
|
||||
return _sm().getRoot() if id is None else _sm().getRoot(id)
|
||||
|
||||
|
||||
def session_get_info(id=None):
|
||||
""" Returns the session information.
|
||||
|
||||
Args:
|
||||
id(int): Session id. Default (None) is the current session.
|
||||
|
||||
Returns:
|
||||
session info (dict)
|
||||
"""
|
||||
return _sm().getInfo() if id is None else _sm().getInfo(id)
|
||||
|
||||
|
||||
def session_get_metadata(id=None):
|
||||
""" Returns a session info metadata.
|
||||
|
||||
Args:
|
||||
id(int): Session id. Default (None) is the current session.
|
||||
|
||||
Returns:
|
||||
session metadata (dict)
|
||||
"""
|
||||
return _sm().getMetadata() if id is None else _sm().getMetadata(id)
|
||||
|
||||
|
||||
def session_set_metadata(key, value,id=None):
|
||||
""" Set session metadata entry.
|
||||
|
||||
Args:
|
||||
key(str): Metadata key
|
||||
value(obj): Metadata value
|
||||
id(int): Session id. Default (None) is the current session.
|
||||
"""
|
||||
return _sm().setMetadata(key, value) if id is None else _sm().setMetadata(id,key, value)
|
||||
|
||||
|
||||
def session_get_metadata_keys():
|
||||
""" Return the default metadata definition for samples.
|
||||
|
||||
Returns:
|
||||
list of map entries
|
||||
"""
|
||||
return [str(e.key) for e in _sm().getMetadataDefinition()]
|
||||
|
||||
|
||||
def session_get_metadata_type(key):
|
||||
""" Return the metadata type for a given key:
|
||||
String, Integer, Double, Boolean, List or Map.
|
||||
Args:
|
||||
key(str): Metadata key.
|
||||
|
||||
Returns:
|
||||
str
|
||||
"""
|
||||
return str(_sm().getMetadataType(key))
|
||||
|
||||
def session_get_metadata_default(key):
|
||||
""" Return the metadata default value for a given key.
|
||||
|
||||
Args:
|
||||
key(str): Metadata key.
|
||||
|
||||
Returns:
|
||||
Object
|
||||
"""
|
||||
return _sm().getMetadataDefault(key)
|
||||
|
||||
def session_get_runs(id=None, relative=True):
|
||||
""" Return the runs of a session.
|
||||
|
||||
Args:
|
||||
id(int): Session id. Default (None) is the current session.
|
||||
relative(bool): if True use relative file names (for files under the data root path)
|
||||
|
||||
Returns:
|
||||
List of dicts
|
||||
"""
|
||||
return _sm().getRuns(java.lang.Boolean(relative)) if id is None else _sm().getRuns(id, relative)
|
||||
|
||||
|
||||
def session_set_run_enabled(enabled, id=None, index=-1):
|
||||
""" Enable or disable a run.
|
||||
|
||||
Args:
|
||||
enabled(bool): true for enabling, false for disabling
|
||||
id(int): Session id. Default (None) is the current session.
|
||||
index: Index of the run. Default (-1) for the last run.
|
||||
|
||||
Returns:
|
||||
Object
|
||||
"""
|
||||
return _sm().setRunEnabled(index, enabled) if id is None else _sm().setRunEnabled(id, index, enabled)
|
||||
|
||||
def session_get_additional_files(id=None, relative=True):
|
||||
""" Return additional files of a session.
|
||||
|
||||
Args:
|
||||
id(int): Session id. Default (None) is the current session.
|
||||
relative(bool): if True use relative file names (for files under the data root path)
|
||||
|
||||
Returns:
|
||||
List of str
|
||||
"""
|
||||
return _sm().getAdditionalFiles(java.lang.Boolean(relative)) if id is None else _sm().getAdditionalFiles(id, relative)
|
||||
|
||||
def session_get_file_list(id=None, relative=True):
|
||||
""" Return complete list of data files of a session.
|
||||
|
||||
Args:
|
||||
id(int): Session id. Default (None) is the current session.
|
||||
relative(bool): if True use relative file names (for files under the data root path)
|
||||
|
||||
Returns:
|
||||
List of str
|
||||
"""
|
||||
return _sm().getFileList(java.lang.Boolean(relative)) if id is None else _sm().getFileList(id, relative)
|
||||
|
||||
def session_create_zip(file_name, id=None, preserve_folder_structure=True):
|
||||
""" Create ZIP file with session contents
|
||||
|
||||
Args:
|
||||
file_name(str): name of the zip file
|
||||
id(int): Session id. Default (None) is the current session.
|
||||
preserve_folder_structure: if False all data files are added to the root of the file.
|
||||
if True the folder structure under data root is preserved.
|
||||
"""
|
||||
return _sm().createZipFile(file_name, preserve_folder_structure) if id is None else _sm().createZipFile(id, file_name, preserve_folder_structure)
|
||||
|
||||
|
||||
def session_ingest_scicat(id, matadata={}):
|
||||
""" Ingest a completed session to SciCat
|
||||
|
||||
Args:
|
||||
id(int): Session id.
|
||||
matadata(dict): session metadata
|
||||
|
||||
Returns:
|
||||
Tuple (Dataset Name, Dataset ID) in case of success. Otherwise throws an exception.
|
||||
"""
|
||||
sciCat= SciCat()
|
||||
result = sciCat.ingest(id, matadata)
|
||||
print result.output
|
||||
if not result.success:
|
||||
raise Exception ("Error ingesting session " + str(id))
|
||||
return result.datasetName, result.datasetId
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
207
script/Lib/startup.py
Normal file
207
script/Lib/startup.py
Normal file
@@ -0,0 +1,207 @@
|
||||
###################################################################################################
|
||||
# Global definitions and built-in functions
|
||||
###################################################################################################
|
||||
|
||||
from builtin_utils import *
|
||||
from builtin_classes import *
|
||||
from builtin_functions import *
|
||||
|
||||
|
||||
###################################################################################################
|
||||
#Default empty callbacks
|
||||
###################################################################################################
|
||||
def on_command_started(info): pass
|
||||
def on_command_finished(info): pass
|
||||
def on_session_started(id): pass
|
||||
def on_session_finished(id): pass
|
||||
def on_change_data_path(path): pass
|
||||
|
||||
|
||||
###################################################################################################
|
||||
#Help and access to function documentation
|
||||
###################################################################################################
|
||||
def _getBuiltinFunctions(filter = None):
|
||||
ret = []
|
||||
for name in globals().keys():
|
||||
val = globals()[name]
|
||||
if type(val) is PyFunction:
|
||||
if filter is None or filter in name:
|
||||
#Only "public" documented functions
|
||||
if not name.startswith('_') and (val.__doc__ is not None):
|
||||
ret.append(val)
|
||||
return to_array(ret)
|
||||
|
||||
|
||||
def _getBuiltinFunctionNames(filter = None):
|
||||
ret = []
|
||||
for function in _getBuiltinFunctions(filter):
|
||||
ret.append(function.func_name)
|
||||
return to_array(ret)
|
||||
|
||||
def _getFunctionDoc(function):
|
||||
if is_string(function):
|
||||
if function not in globals():
|
||||
return
|
||||
function = globals()[function]
|
||||
if type(function) is PyFunction and '__doc__' in dir(function):
|
||||
ac = function.func_code.co_argcount
|
||||
var = function.func_code.co_varnames
|
||||
args = list(var)[:ac]
|
||||
defs = function.func_defaults
|
||||
if defs is not None:
|
||||
for i in range (len(defs)):
|
||||
index = len(args) - len(defs) + i
|
||||
args[index] = args[index] + " = " + str(defs[i])
|
||||
flags = function.func_code.co_flags
|
||||
if flags & 4 > 0:
|
||||
args.append('*' + var[ac])
|
||||
ac=ac+1
|
||||
if flags & 8 > 0:
|
||||
args.append('**' + var[ac])
|
||||
d = function.func_doc
|
||||
return function.func_name+ "(" + ", ".join(args) + ")" + "\n\n" + (d if (d is not None) else "")
|
||||
|
||||
def help(object = None):
|
||||
"""
|
||||
Print help message for function or object (if available).
|
||||
|
||||
Args:
|
||||
object (any, optional): function or object to get help.
|
||||
If null prints a list of the builtin functions.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
if object is None:
|
||||
print "Built-in functions:"
|
||||
for f in _getBuiltinFunctionNames():
|
||||
print "\t" + f
|
||||
else:
|
||||
if type(object) is PyFunction:
|
||||
print _getFunctionDoc(object)
|
||||
elif '__doc__' in dir(object):
|
||||
#The default doc is now shown
|
||||
import org.python.core.BuiltinDocs.object_doc
|
||||
if object.__doc__ != org.python.core.BuiltinDocs.object_doc:
|
||||
print object.__doc__
|
||||
|
||||
###################################################################################################
|
||||
#Variable injection
|
||||
###################################################################################################
|
||||
|
||||
def _get_caller():
|
||||
#Not doing inspect.currentframe().f_back because inspect is slow to load
|
||||
return sys._getframe(1).f_back if hasattr(sys, "_getframe") else None
|
||||
|
||||
def inject():
|
||||
"""Restore initial globals: re-inject devices and startup variables to the interpreter.
|
||||
|
||||
Args:
|
||||
None
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
if __name__ == "__main__":
|
||||
get_context().injectVars()
|
||||
else:
|
||||
_get_caller().f_globals.update(get_context().scriptManager.injections)
|
||||
|
||||
|
||||
###################################################################################################
|
||||
#Script evaluation and return values
|
||||
###################################################################################################
|
||||
|
||||
def run(script_name, args = None, locals = None):
|
||||
"""Run script: can be absolute path, relative, or short name to be search in the path.
|
||||
Args:
|
||||
args(Dict ot List): Sets sys.argv (if list) or gobal variables(if dict) to the script.
|
||||
locals(Dict): If not none sets the locals()for the runing script.
|
||||
If locals is used then script definitions will not go to global namespace.
|
||||
|
||||
Returns:
|
||||
The script return value (if set with set_return)
|
||||
"""
|
||||
script = get_context().scriptManager.library.resolveFile(script_name)
|
||||
if script is not None and os.path.isfile(script):
|
||||
info = get_context().startScriptExecution(script_name, args)
|
||||
try:
|
||||
set_return(None)
|
||||
if args is not None:
|
||||
if isinstance(args,list) or isinstance(args,tuple):
|
||||
sys.argv = list(args)
|
||||
globals()["args"] = sys.argv
|
||||
else:
|
||||
for arg in args.keys():
|
||||
globals()[arg] = args[arg]
|
||||
if (locals is None):
|
||||
execfile(script, globals())
|
||||
else:
|
||||
execfile(script, globals(), locals)
|
||||
ret = get_return()
|
||||
get_context().finishScriptExecution(info, ret)
|
||||
return ret
|
||||
except Exception, ex:
|
||||
get_context().finishScriptExecution(info, ex)
|
||||
raise ex
|
||||
raise IOError("Invalid script: " + str(script_name))
|
||||
|
||||
def abort():
|
||||
"""Abort the execution of ongoing task. It can be called from the script to quit.
|
||||
|
||||
Args:
|
||||
None
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
fork(get_context().abort) #Cannot be on script execution thread
|
||||
while True: sleep(10.0)
|
||||
|
||||
def set_return(value):
|
||||
"""Sets the script return value. This value is returned by the "run" function.
|
||||
|
||||
Args:
|
||||
value(Object): script return value.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
#In Jython, the output of last statement is not returned when running a file
|
||||
if __name__ == "__main__":
|
||||
global __THREAD_EXEC_RESULT__
|
||||
if is_interpreter_thread():
|
||||
global _
|
||||
_=value
|
||||
__THREAD_EXEC_RESULT__[java.lang.Thread.currentThread()]=value #Used when running file
|
||||
else:
|
||||
#if startup is imported, cannot set global
|
||||
caller = _get_caller()
|
||||
if is_interpreter_thread():
|
||||
caller.f_globals["_"]=value
|
||||
if not "__THREAD_EXEC_RESULT__" in caller.f_globals.keys():
|
||||
caller.f_globals["__THREAD_EXEC_RESULT__"] = {}
|
||||
caller.f_globals["__THREAD_EXEC_RESULT__"][java.lang.Thread.currentThread()]=value
|
||||
return value #Used when parsing file
|
||||
|
||||
def get_return():
|
||||
if __name__ == "__main__":
|
||||
global __THREAD_EXEC_RESULT__
|
||||
return __THREAD_EXEC_RESULT__[java.lang.Thread.currentThread()]
|
||||
else:
|
||||
return _get_caller().f_globals["__THREAD_EXEC_RESULT__"][java.lang.Thread.currentThread()]
|
||||
|
||||
|
||||
###################################################################################################
|
||||
#Executed on startup
|
||||
###################################################################################################
|
||||
|
||||
if __name__ == "__main__":
|
||||
ca_channel_path=os.path.join(get_context().setup.getStandardLibraryPath(), "epics")
|
||||
sys.path.append(ca_channel_path)
|
||||
#This is to destroy previous context of _ca (it is not shared with PShell)
|
||||
if run_count > 0:
|
||||
if sys.modules.has_key("_ca"):
|
||||
print
|
||||
import _ca
|
||||
_ca.initialize()
|
||||
2836
script/Lib/startup_c.py
Normal file
2836
script/Lib/startup_c.py
Normal file
File diff suppressed because it is too large
Load Diff
191
script/Lib/statsutils.py
Normal file
191
script/Lib/statsutils.py
Normal file
@@ -0,0 +1,191 @@
|
||||
###################################################################################################
|
||||
# Utilities for generating reports from command statistics files
|
||||
###################################################################################################
|
||||
|
||||
#CsvJdbc JAR file must be downloaded to extensions folder:
|
||||
#http://central.maven.org/maven2/net/sourceforge/csvjdbc/csvjdbc/1.0.34/csvjdbc-1.0.34.jar
|
||||
|
||||
|
||||
import java.sql.DriverManager as DriverManager
|
||||
import java.sql.ResultSet as ResultSet
|
||||
import java.util.Properties as Properties
|
||||
import java.lang.Class as Class
|
||||
import os
|
||||
from startup import get_context, expand_path
|
||||
import ch.psi.pshell.core.CommandManager.CommandStatisticsFileRange as CommandStatisticsFileRange
|
||||
|
||||
stmt = None
|
||||
STAT_COLUMN_NAMES = ["Command","Args","Source","Start","End","Background","Result","Return"]
|
||||
def get_stats_connection():
|
||||
global stmt
|
||||
Class.forName("org.relique.jdbc.csv.CsvDriver");
|
||||
db = os.path.abspath(expand_path("{home}/statistics"))
|
||||
props = Properties()
|
||||
props.put("fileExtension", ".csv")
|
||||
props.put("separator", ";")
|
||||
props.put("timestampFormat", "dd/MM/yy HH:mm:ss.SSS")
|
||||
props.put("indexedFiles", "true");
|
||||
props.put("columnTypes", "String,String,String,Timestamp,Timestamp,Boolean,String,String");
|
||||
|
||||
fileRange = get_context().commandManager.commandStatisticsConfig.fileRange
|
||||
if fileRange==CommandStatisticsFileRange.Daily:
|
||||
props.put("fileTailPattern", "(\\d+)_(\\d+)_(\\d+)");
|
||||
props.put("fileTailParts", "Year,Month,Day");
|
||||
elif fileRange==CommandStatisticsFileRange.Monthly:
|
||||
props.put("fileTailPattern", "(\\d+)_(\\d+)"); #props.put("fileTailPattern", "-(\\d+)_(\\d+)");
|
||||
props.put("fileTailParts", "Year,Month");
|
||||
elif fileRange==CommandStatisticsFileRange.Yearly:
|
||||
props.put("fileTailPattern", "(\\d+)");
|
||||
props.put("fileTailParts", "Year");
|
||||
|
||||
conn = DriverManager.getConnection("jdbc:relique:csv:" + db, props);
|
||||
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
|
||||
return conn
|
||||
|
||||
def _get_count(sql):
|
||||
ret = 0
|
||||
results = stmt.executeQuery("SELECT COUNT(*) AS count FROM . WHERE " + sql)
|
||||
if results.first():
|
||||
ret = results.getInt("count")
|
||||
return ret
|
||||
|
||||
def _add_sql_time(sql, start, end):
|
||||
if start:
|
||||
if len(start)==8:
|
||||
start = start + " 00:00:00.000"
|
||||
sql = sql + " AND Start>='" + start + "'"
|
||||
if end:
|
||||
if len(end)==8:
|
||||
end = end + " 00:00:00.000"
|
||||
sql = sql + " AND (\"End\"<'" + end + "')"
|
||||
return sql
|
||||
|
||||
def get_count(command= "%%", start = None, end = None, result= "%%"):
|
||||
sql = "Command LIKE '"+ command +"' AND Result LIKE '"+ result +"'"
|
||||
sql = _add_sql_time(sql, start, end)
|
||||
return _get_count(sql)
|
||||
|
||||
def get_return_count(command= "%%", start = None, end = None, ret= "%%"):
|
||||
sql = "Command LIKE '"+ command +"' AND Return = '"+ ret +"'"
|
||||
sql = _add_sql_time(sql, start, end)
|
||||
return _get_count(sql)
|
||||
|
||||
def get_cmd_stats(command = "%", start = None, end = None):
|
||||
s = get_count(command, start, end, "success")
|
||||
a = get_count(command, start, end, "abort")
|
||||
e = get_count(command, start, end, "error")
|
||||
return (s,a,e)
|
||||
|
||||
def get_errors(command = "%", start = None, end = None):
|
||||
sql = "SELECT Return, Count(Return) as count FROM . WHERE Command LIKE '"+ command +"' AND Result='error'"
|
||||
sql = _add_sql_time(sql, start, end)
|
||||
sql = sql + " GROUP BY Return ORDER BY count DESC"
|
||||
results = stmt.executeQuery(sql)
|
||||
ret = []
|
||||
while results.next():
|
||||
ret.append((results.getInt("count"), results.getString("Return")))
|
||||
return ret
|
||||
|
||||
|
||||
def get_cmd_records(command = "%", start = None, end = None, result= "%%"):
|
||||
sql = "SELECT * FROM . WHERE Command LIKE '"+ command +"' AND Result LIKE '"+ result +"'"
|
||||
sql = _add_sql_time(sql, start, end)
|
||||
results = stmt.executeQuery(sql)
|
||||
ret = []
|
||||
while results.next():
|
||||
rec={}
|
||||
for col in STAT_COLUMN_NAMES:
|
||||
rec[col]= results.getString(col)
|
||||
ret.append(rec)
|
||||
return ret
|
||||
|
||||
def get_commands(commands =None, start = None, end = None):
|
||||
ret = []
|
||||
if (commands is None) or (len(commands)==0):
|
||||
sql = "SELECT * FROM . WHERE Command != ''"
|
||||
sql = _add_sql_time(sql, start, end)
|
||||
sql = sql + " GROUP BY Command"
|
||||
results = stmt.executeQuery(sql)
|
||||
while results.next():
|
||||
cmd = results.getString("Command")
|
||||
if cmd and not " " in cmd:
|
||||
ret.append(cmd)
|
||||
else:
|
||||
for cmd in commands:
|
||||
if get_count(cmd, start, end) >0 :
|
||||
ret.append(cmd)
|
||||
return ret
|
||||
|
||||
def print_cmd_stats(command = "%", start = None, end = None):
|
||||
print "-----------------------------------------------------------"
|
||||
print "Statistics from ", start , " to ", end
|
||||
(s,a,e) = get_cmd_stats(command, start, end)
|
||||
t=s+a+e #get_count(command, start, end, "%")
|
||||
print "Command: " , command , " Records: ", t
|
||||
if t>0:
|
||||
print "%-10s %7.2f%% - %d" % ("Success", (float(s)/t) * 100, s)
|
||||
print "%-10s %7.2f%% - %d" % ("Abort", (float(a)/t) * 100, a)
|
||||
print "%-10s %7.2f%% - %d" % ("Error", (float(e)/t) * 100, e)
|
||||
|
||||
print "\nErrors:"
|
||||
print "%5s %s" % ("Count", "Error")
|
||||
errors = get_errors(command, start, end)
|
||||
for error in errors:
|
||||
print "%5d %s" % (error[0], error[1])
|
||||
print "-----------------------------------------------------------"
|
||||
|
||||
def print_cmd_records(command = "%", start = None, end = None, result= "%%"):
|
||||
print "-----------------------------------------------------------"
|
||||
print "Records from ", start , " to ", end
|
||||
info = get_cmd_records(command, start, end, result)
|
||||
print "Command: " , command , " Result: ", result, " Records: ", len(info)
|
||||
|
||||
for col in STAT_COLUMN_NAMES:
|
||||
print col+ "; " ,
|
||||
print
|
||||
|
||||
for cmd in info:
|
||||
s = ""
|
||||
for col in STAT_COLUMN_NAMES:
|
||||
s = s + cmd[col]+ "; "
|
||||
print s
|
||||
print "-----------------------------------------------------------"
|
||||
|
||||
def print_stats(commands = None, start = None, end = None):
|
||||
print "-----------------------------------------------------------"
|
||||
print "Statistics from ", start , " to ", end
|
||||
print "%-20s %-5s %8s %8s %8s" % ("Command", "Total", "Success", "Abort", "Error")
|
||||
cmds = get_commands(commands)
|
||||
for cmd in cmds:
|
||||
(s,a,e) = get_cmd_stats(cmd, start, end)
|
||||
t=s+a+e
|
||||
if t>0:
|
||||
print "%-20s %-5d %7.2f%% %7.2f%% %7.2f%%" % (cmd, t, (float(s)/t) * 100, (float(a)/t) * 100, (float(e)/t) * 100)
|
||||
else:
|
||||
print "%-20s %-5d" % (cmd, t)
|
||||
print "-----------------------------------------------------------"
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
conn = get_stats_connection()
|
||||
|
||||
#Print stats of all commands, with no time range
|
||||
print_stats()
|
||||
|
||||
cmds = ["%scan1%", "%scan2%"]
|
||||
start= "01/03/19"
|
||||
end= "01/04/19"
|
||||
|
||||
#Print stats all commands containing 'scan1' and 'scan2' in the month 03.2019
|
||||
print_stats(cmds, start, end)
|
||||
|
||||
#Print individual statistics, including error count, for commands containing 'scan1' and 'scan2'
|
||||
for cmd in cmds:
|
||||
print_cmd_stats (cmd, start, end)
|
||||
|
||||
#Print all records for commands containing 'scan1'
|
||||
print_cmd_records("%scan1%%", start, end, "error")
|
||||
conn.close()
|
||||
|
||||
7
script/local.py
Executable file
7
script/local.py
Executable file
@@ -0,0 +1,7 @@
|
||||
###################################################################################################
|
||||
# Deployment specific global definitions - executed after startup.py
|
||||
###################################################################################################
|
||||
|
||||
run("psss/psss")
|
||||
|
||||
|
||||
73
script/psss/CameraScan.py
Executable file
73
script/psss/CameraScan.py
Executable file
@@ -0,0 +1,73 @@
|
||||
#Scan the PSSS camera position
|
||||
#Purpose:
|
||||
#To set or confirm the camera is positioned with the measured spectrum in the centre of the spectral integration window
|
||||
|
||||
#If running from editor
|
||||
if get_exec_pars().source == CommandSource.ui:
|
||||
#User inputs - define travel range of camera
|
||||
RANGE_FROM = -17
|
||||
RANGE_TO = -11
|
||||
STEPS = 20
|
||||
NUM_SHOTS= 10 #100
|
||||
PLOT=None
|
||||
p = plot(None, title="Data")[0] if (PLOT is None) else PLOT
|
||||
p.clear()
|
||||
p.removeMarker(None)
|
||||
p.setLegendVisible(True)
|
||||
p.addSeries(LinePlotSeries("PSSS Spectrum Average"))
|
||||
|
||||
|
||||
run("cpython/wrapper")
|
||||
|
||||
if not is_dry_run():
|
||||
cam_x=Channel("SARFE10-PSSS059:MOTOR_X5.VAL", name="cam_x")
|
||||
else:
|
||||
cam_x=DummyRegister("cam_x")
|
||||
|
||||
av = create_averager(psss_spectrum_y, NUM_SHOTS, interval=-1, name="spectrum_average")
|
||||
av_samples = av.samples
|
||||
av_samples.alias = "spectrum_samples"
|
||||
|
||||
|
||||
#Scan and take data
|
||||
def after_read(record, scan):
|
||||
p.getSeries(0).setData(psss_spectrum_x.take(), record[av])
|
||||
p.setTitle("Cam X = %1.3f" %(record[cam_x]))
|
||||
|
||||
r = lscan(cam_x, (av, av_samples), RANGE_FROM, RANGE_TO, STEPS, latency=0.0, after_read = after_read, save=False)
|
||||
average, samples, cam_range = r.getReadable(0), r.getReadable(1), r.getPositions(0)
|
||||
|
||||
signal_centre, projection = get_signal_centre(samples, cam_range)
|
||||
|
||||
#Set max position
|
||||
cam_x.write(signal_centre)
|
||||
cam_x.close()
|
||||
|
||||
|
||||
|
||||
"""
|
||||
plt.figure(figsize=[10,5])
|
||||
plt.subplot(121)
|
||||
plt.title('PSSS scan of camera position')
|
||||
plt.pcolormesh(np.arange(0,Scan_spec.shape[2]), Cam_range, Scan_spec.mean(axis=1),cmap='CMRmap')
|
||||
plt.xlim([0,Scan_spec.shape[2]])
|
||||
plt.xlabel('Camera pixel dispersive direction')
|
||||
plt.ylabel('Set PSSS cam_x _pos [mm] \n'+PSSS_cam_x_PV_name[0:-4])
|
||||
plt.subplot(122)
|
||||
plt.plot(projection,Cam_range,linewidth = 2, color = 'orange',label ='projected signal')
|
||||
plt.title('Spectrum centred at %.1f [mm] (from signal max) \n trace should have hard edges'%signal_centre)
|
||||
plt.xticks([])
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
"""
|
||||
#PLOT.clear()
|
||||
#plot_data(PLOT, projection, "Data", xdata=cam_range, show_points = True, color=Color.BLUE)
|
||||
#p,pars = plot_gauss_fit(cam_range, projection, gauss_pars=None, p=PLOT, title = "Data")
|
||||
|
||||
p.clear()
|
||||
p.setTitle("")
|
||||
plot_data(p, projection, "Projection", xdata=cam_range, show_points = True, color=Color.BLUE)
|
||||
p.addMarker(signal_centre, None, "Signal Centre=" + str(round(signal_centre,2)), Color.LIGHT_GRAY)
|
||||
|
||||
|
||||
set_return(signal_centre)
|
||||
81
script/psss/CrystalHeightScan.py
Executable file
81
script/psss/CrystalHeightScan.py
Executable file
@@ -0,0 +1,81 @@
|
||||
###############################################################################
|
||||
#Scan the PSSS crystal height
|
||||
#Purpose:
|
||||
#The PSSS signal level is very sensitive to the crystal height. This script will scan the height and set the position to the maximum signal
|
||||
|
||||
if get_exec_pars().source == CommandSource.ui:
|
||||
#User inputs - define travel range of camera
|
||||
RANGE_FROM = -0.8
|
||||
RANGE_TO = -1.7
|
||||
STEPS = 10 #20
|
||||
NUM_SHOTS= 10 # 100
|
||||
PLOT=None
|
||||
|
||||
p = plot(None, title="Data")[0] if (PLOT is None) else PLOT
|
||||
p.clear()
|
||||
p.removeMarker(None)
|
||||
p.setLegendVisible(True)
|
||||
p.addSeries(LinePlotSeries("PSSS Spectrum Average"))
|
||||
|
||||
run("cpython/wrapper")
|
||||
|
||||
|
||||
#Setup and functions setup¶
|
||||
if not is_dry_run():
|
||||
xstal_height=Channel("SARFE10-PSSS059:MOTOR_Y3.VAL", name="xstal_height")
|
||||
else:
|
||||
xstal_height=DummyRegister("xstal_height")
|
||||
|
||||
av = create_averager(psss_spectrum_y, NUM_SHOTS, interval=-1, name="spectrum_average")
|
||||
av_samples = av.samples
|
||||
av_samples.alias = "spectrum_samples"
|
||||
|
||||
#Scan and take data
|
||||
def after_read(record, scan):
|
||||
p.getSeries(0).setData(psss_spectrum_x.take(), record[av])
|
||||
p.setTitle("Xtal Height = %1.3f" %(record[xstal_height]))
|
||||
|
||||
r = lscan(xstal_height, (av, av_samples), RANGE_FROM, RANGE_TO, STEPS, latency=2.0, after_read = after_read, save=False)
|
||||
|
||||
#User inputs - define travel range of crystal
|
||||
#It is unlikely these values need to be changed
|
||||
average, samples, xstal_range = r.getReadable(0), r.getReadable(1), r.getPositions(0)
|
||||
|
||||
#return maxium position
|
||||
[amp, mean_val, sigma, offset], projection = fit_crystal_height(RANGE_FROM, RANGE_TO, STEPS+1, samples)
|
||||
print(mean_val)
|
||||
|
||||
if not (RANGE_FROM < mean_val < RANGE_TO or RANGE_TO < mean_val < RANGE_FROM):
|
||||
raise Exception ("Invalid fit mean: " + str(mean_val))
|
||||
|
||||
|
||||
#Set max position
|
||||
#Cell below will push the maximum position to the xstal height
|
||||
xstal_height.write(mean_val)
|
||||
xstal_height.close()
|
||||
|
||||
#Plots
|
||||
"""
|
||||
plt.figure(figsize=[10,5])
|
||||
plt.subplot(121)
|
||||
plt.title('PSSS scan of crystal height')
|
||||
plt.pcolormesh(energy_axis, xstal_range, Scan_spec.mean(axis=1),cmap='CMRmap')
|
||||
plt.xlim([energy_axis[0],energy_axis[-1]])
|
||||
plt.ylim([xstal_range[0], xstal_range[-1]])
|
||||
plt.xlabel('PSSS energy axis')
|
||||
plt.ylabel('Set crystal position [mm] \n'+PSSS_xstal_height_name[0:-4])
|
||||
plt.subplot(122)
|
||||
plt.plot(projection,xstal_range,linewidth = 2, color = 'orange',label ='projected signal')
|
||||
plt.plot(gaus(xstal_range_fit,*popt),xstal_range_fit,'r:',label='fit')
|
||||
plt.ylim([xstal_range[0], xstal_range[-1]])
|
||||
plt.title('Signal max at %.3f [mm] (from fit)'%popt[1])
|
||||
plt.xticks([])
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
"""
|
||||
p.clear()
|
||||
p.setTitle("")
|
||||
plot_gauss_fit(xstal_range, projection, gauss_pars=(offset, amp, mean_val, sigma), p=p, title = "Data")
|
||||
|
||||
|
||||
set_return(mean_val)
|
||||
101
script/psss/EnergyScan.py
Executable file
101
script/psss/EnergyScan.py
Executable file
@@ -0,0 +1,101 @@
|
||||
###############################################################################
|
||||
#Scan the PSSS photon energy
|
||||
#Purpose: To find and centre the PSSS photon energy so the measured spectrum is centred on the camera chip
|
||||
|
||||
#PARAMETERS
|
||||
#User inputs - define energy range to scan below by running the appropiate cell
|
||||
#Below is for a large scan range assuming offset from machine upto $\pm$ 300 eV
|
||||
|
||||
#If running from editor
|
||||
if get_exec_pars().source == CommandSource.ui:
|
||||
RANGE_OFF = None
|
||||
RANGE_FROM = 11100
|
||||
RANGE_TO = 11300
|
||||
STEPS = 5 #60
|
||||
NUM_SHOTS= 10 #100
|
||||
PLOT=None
|
||||
p = plot(None, title="Data")[0] if (PLOT is None) else PLOT
|
||||
p.clear()
|
||||
p.removeMarker(None)
|
||||
p.setLegendVisible(True)
|
||||
p.addSeries(LinePlotSeries("PSSS Spectrum Average"))
|
||||
|
||||
if RANGE_OFF is not None:
|
||||
RANGE_FROM = energy_machine.read()-RANGE_OFF
|
||||
RANGE_TO = energy_machine.read()+RANGE_OFF
|
||||
|
||||
run("cpython/wrapper")
|
||||
|
||||
|
||||
|
||||
|
||||
#Scan and take data
|
||||
class PSSS_energy(Writable):
|
||||
def write(self, value):
|
||||
if not is_dry_run():
|
||||
psss_energy.write(value)
|
||||
exec_cpython("/ioc/modules/qt/PSSS_motion.py", args = ["-m1", "SARFE10-PSSS059"])
|
||||
# python / ioc / modules / qt / PSSS_motion.py - m1 SARFE10 - PSSS059
|
||||
time.sleep(1)
|
||||
print(value)
|
||||
|
||||
en = PSSS_energy()
|
||||
en.alias = "energy"
|
||||
|
||||
av = create_averager(psss_spectrum_y, NUM_SHOTS, interval=-1, name="spectrum_average")
|
||||
av_samples = av.samples
|
||||
av_samples.alias = "spectrum_samples"
|
||||
|
||||
|
||||
def after_read(record, scan):
|
||||
p.getSeries(0).setData(psss_spectrum_x.take(), record[av])
|
||||
p.setTitle("Energy = %1.3f" %(record[en]))
|
||||
|
||||
r = lscan(en, (av, av_samples), RANGE_FROM, RANGE_TO, STEPS, latency=0.0, after_read = after_read, save=False )
|
||||
average, samples, energy_range = r.getReadable(0), r.getReadable(1), r.getPositions(0)
|
||||
|
||||
[amp, mean_val, sigma, offset],centre_line_out = fit_energy(RANGE_FROM, RANGE_TO, STEPS+1, NUM_SHOTS, samples)
|
||||
|
||||
if not (RANGE_FROM < mean_val < RANGE_TO or RANGE_TO < mean_val < RANGE_FROM):
|
||||
raise Exception ("Invalid fit mean: " + str(mean_val))
|
||||
|
||||
|
||||
measured_offset = energy_machine.read() - mean_val
|
||||
#Set fitted energy
|
||||
print "measured offset", measured_offset
|
||||
|
||||
en.write(mean_val)
|
||||
|
||||
|
||||
#Plot
|
||||
"""
|
||||
plt.figure(figsize=[10,5])
|
||||
plt.subplot(121)
|
||||
plt.title('PSSS scan of set photon energy')
|
||||
plt.pcolormesh(np.arange(0,Scan_spec.shape[2]), Energy_range, Scan_spec.mean(axis=1),cmap='CMRmap')
|
||||
plt.vlines(int(Scan_spec.shape[2]/2), Energy_range[0], Energy_range[-1],linestyles='--', colors='orange')
|
||||
plt.xlim([0,Scan_spec.shape[2]])
|
||||
plt.xlabel('Camera pixel')
|
||||
plt.ylabel('Set PSSS energy [eV] \n SARFE10-PSSS059:ENERGY')
|
||||
|
||||
plt.subplot(122)
|
||||
plt.title('At camera centre pixel %1i \nCalibrated energy = %.1f [eV]\n Offset from machine = %.1f [eV]'%(int(Scan_spec.shape[2]/2),popt[1],measured_offset))
|
||||
plt.plot(centre_line_out,Energy_range,linewidth = 2, color = 'orange',label ='measured')
|
||||
plt.plot(gaus(Energy_range_fit,*popt),Energy_range_fit,'r:',label='fit')
|
||||
plt.xticks([])
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
"""
|
||||
|
||||
p.clear()
|
||||
p.setTitle("")
|
||||
plot_gauss_fit(energy_range, centre_line_out, gauss_pars=(offset, amp, mean_val, sigma), p=PLOT, title = "Data")
|
||||
|
||||
|
||||
set_return(mean_val)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
188
script/psss/psss.py
Executable file
188
script/psss/psss.py
Executable file
@@ -0,0 +1,188 @@
|
||||
import org.jfree.ui.RectangleAnchor as RectangleAnchor
|
||||
import org.jfree.ui.TextAnchor as TextAnchor
|
||||
import ch.psi.pshell.imaging.Overlay as Overlay
|
||||
import ch.psi.pshell.plot.RangeSelectionPlot as RangeSelectionPlot
|
||||
from collections import deque
|
||||
|
||||
PSSS_CAMERA_NAME = "SARFE10-PSSS059";
|
||||
|
||||
def integrate_arrays(arrays):
|
||||
if arrays is None or (len(arrays)==0):
|
||||
return None
|
||||
ret = arrays[0]
|
||||
for a in arrays[1:]:
|
||||
ret=arradd(ret, a)
|
||||
return ret
|
||||
|
||||
def average_arrays(arrays):
|
||||
ret = integrate_arrays(arrays)
|
||||
if ret is not None:
|
||||
s=len(arrays)
|
||||
ret = [x/s for x in ret]
|
||||
return ret
|
||||
|
||||
|
||||
def get_psss_data(average=1):
|
||||
ax,ay,ac,af=[],[],[],[]
|
||||
x = psss_spectrum_x.take()
|
||||
for i in range(average):
|
||||
y = psss_spectrum_y.take()
|
||||
center,fwhm = psss_center.take(), psss_fwhm.take()
|
||||
if average==1:
|
||||
return x,y,center,fwhm
|
||||
#ax.append(x)
|
||||
ay.append(y)
|
||||
ac.append(center)
|
||||
af.append(fwhm)
|
||||
if i < (average-1):
|
||||
psss_spectrum_y.waitCacheChange(2000)
|
||||
#psss_center.waitCacheChange(1)
|
||||
#psss_fwhm.waitCacheChange(1)
|
||||
#x=average_arrays(ax)
|
||||
y=average_arrays(ay)
|
||||
center=mean(ac)
|
||||
fwhm=mean(af)
|
||||
return x,y,center,fwhm
|
||||
|
||||
def plot_psss(p, h=None, average = None):
|
||||
"""
|
||||
if len(p.getMarkers())==0:
|
||||
m1=p.addMarker(0,None,"",Color.WHITE)
|
||||
m2=p.addMarker(0,None,"",Color.WHITE)
|
||||
m2.setLabelAnchor(RectangleAnchor.TOP)
|
||||
else:
|
||||
m1,m2 = p.getMarkers()
|
||||
"""
|
||||
|
||||
#Manipulate axis (use PSSS_PLOT for the global object):
|
||||
#p.getAxis(LinePlot.AxisId.X).
|
||||
|
||||
# Setup queues
|
||||
if p.getNumberOfSeries()==0:
|
||||
center_queue = deque(maxlen=100)
|
||||
fwhm_queue = deque(maxlen=100)
|
||||
|
||||
# Setup figures
|
||||
|
||||
if p.getNumberOfSeries()==0:
|
||||
p.addSeries(LinePlotSeries("spectrum"))
|
||||
p.addSeries(LinePlotSeries("average"))
|
||||
p.setLegendVisible(True)
|
||||
p.getAxis(LinePlot.AxisId.X)
|
||||
p.getAxis(LinePlot.AxisId.X).setLabel("Energy [eV]")
|
||||
p.getAxis(LinePlot.AxisId.Y).setLabel("Sum counts")
|
||||
if len(p.getMarkers())==0:
|
||||
paint = RangeSelectionPlot().getSelectionColor() #p.chart.getBackgroundPaint()
|
||||
m=p.addIntervalMarker(0,0, None,"", paint)
|
||||
m.setLabelAnchor(RectangleAnchor.BOTTOM)
|
||||
m.alpha=0.2
|
||||
m.setLabelPaint(Color.WHITE)
|
||||
else:
|
||||
m = p.getMarkers()[0]
|
||||
|
||||
|
||||
x,y, = psss_spectrum_x.take(), psss_spectrum_y.take()
|
||||
# update spectral plot
|
||||
if (x is None) or (y is None):
|
||||
p.getSeries(0).clear()
|
||||
else:
|
||||
p.getSeries(0).setData(x,y)
|
||||
if (x is None) or (y is None):
|
||||
p.getSeries(0).clear()
|
||||
else:
|
||||
p.getSeries(0).setData(x,y)
|
||||
|
||||
if average is not None:
|
||||
print "Average: ", average
|
||||
x,y, center,fwhm = get_psss_data(average)
|
||||
else:
|
||||
y = psss_spectrum_y_average.take()
|
||||
center = psss_center_average.take()
|
||||
fwhm = psss_fwhm_average.take()
|
||||
|
||||
if (x is None) or (y is None):
|
||||
p.getSeries(1).clear()
|
||||
else:
|
||||
p.getSeries(1).setData(x,y)
|
||||
|
||||
|
||||
if (center!= None) and (fwhm!=None):
|
||||
center=center.doubleValue()
|
||||
fwhm=fwhm.doubleValue()
|
||||
m.startValue, m.endValue = center - fwhm/2, center + fwhm/2
|
||||
m.label = str(center)
|
||||
|
||||
if h:
|
||||
if h.getNumberOfSeries()==0:
|
||||
h.addSeries(TimePlotSeries("centre"))
|
||||
h.addSeries(TimePlotSeries("Energy spread SS",2))
|
||||
h.addSeries(TimePlotSeries("Energy spread cum avg",2))
|
||||
h.setLegendVisible(True)
|
||||
h.setTimeAxisLabel("")
|
||||
h.getAxis(Timeplot.AxisId.Y1).setLabel("Central energy [eV]")
|
||||
per_mil = (fwhm/center)*1e3
|
||||
per_mil_avg = psss_fwhm_avg.take()
|
||||
h.getSeries(0).appendData(center)
|
||||
h.getSeries(1).appendData(per_mil)
|
||||
h.getSeries(2).appendData(per_mil_avg)
|
||||
return center,fwhm
|
||||
|
||||
ovmin, ovmax, ovavg = None, None, None
|
||||
|
||||
def update_psss_image(renderer):
|
||||
global ovmin, ovmax
|
||||
#if ovmin: ovmin.update(Point(0,psss_roi_min.take()))
|
||||
#if ovmax: ovmax.update(Point(0,psss_roi_max.take()))
|
||||
|
||||
|
||||
width=psss_spectrum_x.size
|
||||
if ovmin: ovmin.update(Point(0,psss_roi_min.take()), Point(width, psss_roi_min.take()))
|
||||
if ovmax: ovmax.update(Point(0,psss_roi_max.take()), Point(width, psss_roi_max.take()))
|
||||
try:
|
||||
data = renderer.data
|
||||
av = "%1.2f" %(data.integrate(False)/data.width/data.height)
|
||||
except:
|
||||
av = ""
|
||||
if ovavg: ovavg.update(av)
|
||||
|
||||
def enable_psss_image(enabled, renderer):
|
||||
global ovmin, ovmax, ovavg
|
||||
try:
|
||||
if (enabled):
|
||||
#Start or connect to ScreenPanel pipeline
|
||||
renderer.setDevice(cam_server)
|
||||
renderer.setProfile(renderer.Profile.Both)
|
||||
renderer.setShowProfileLimits(False)
|
||||
|
||||
#Changing colormap
|
||||
#print Colormap.values() #Check values
|
||||
cam_server.config.colormap=Colormap.Temperature
|
||||
|
||||
|
||||
cam_server.start(PSSS_CAMERA_NAME + "_sp", PSSS_CAMERA_NAME + "_sp1")
|
||||
#ovmin, ovmax= Overlays.Crosshairs(renderer.getPenMarker(), Dimension(-1,1)), \
|
||||
# Overlays.Crosshairs(renderer.getPenMarker(), Dimension(-1,1))
|
||||
ovmin, ovmax= Overlays.Line(renderer.getPenMarker()), Overlays.Line(renderer.getPenMarker())
|
||||
|
||||
ovavg = Overlays.Text(Pen(java.awt.Color.GREEN.darker()), "", \
|
||||
java.awt.Font("Verdana", java.awt.Font.PLAIN, 12), java.awt.Point(-50,20))
|
||||
ovavg.fixed=True
|
||||
ovavg.anchor=Overlay.ANCHOR_IMAGE_TOP_RIGHT
|
||||
renderer.addOverlays([ovmin, ovmax, ovavg])
|
||||
update_psss_image(renderer)
|
||||
else:
|
||||
ovmin, ovmax, ovavg = None, None, None
|
||||
renderer.setDevice(None)
|
||||
renderer.clearOverlays()
|
||||
cam_server.stop()
|
||||
except:
|
||||
log(sys.exc_info()[1])
|
||||
|
||||
|
||||
def get_psss_averaging():
|
||||
return psss_spectrum_y_average.config.measures
|
||||
|
||||
def set_psss_averaging(measures):
|
||||
psss_spectrum_y_average.config.measures=measures
|
||||
psss_center_average.config.measures=measures
|
||||
psss_fwhm_average.config.measures=measures
|
||||
Reference in New Issue
Block a user