moved files to top level
54
src/main/assembly/assembly.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
|
||||
|
||||
<id>bin</id>
|
||||
<!-- Generates a zip package containing the needed files -->
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
|
||||
<!-- Adds dependencies to zip package under lib directory -->
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<outputDirectory>lib</outputDirectory>
|
||||
<unpack>false</unpack>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
|
||||
<fileSets>
|
||||
<!-- Adds startup scripts to the root directory of zip package -->
|
||||
<fileSet>
|
||||
<fileMode>0755</fileMode>
|
||||
<directory>src/main/assembly/bin</directory>
|
||||
<outputDirectory>bin</outputDirectory>
|
||||
<includes>
|
||||
<include>*</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<!-- <fileSet>
|
||||
<directory>src/main/assembly/www</directory>
|
||||
<outputDirectory>www</outputDirectory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</fileSet> -->
|
||||
<!-- <fileSet>
|
||||
<fileMode>0755</fileMode>
|
||||
<directory>src/main/assembly/var</directory>
|
||||
<outputDirectory>var</outputDirectory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</fileSet> -->
|
||||
<!-- adds jar package to the root directory of zip package -->
|
||||
<!-- <fileSet>
|
||||
<directory>target</directory>
|
||||
<outputDirectory></outputDirectory>
|
||||
<includes>
|
||||
<include>*.jar</include>
|
||||
</includes>
|
||||
</fileSet> -->
|
||||
</fileSets>
|
||||
</assembly>
|
||||
40
src/main/assembly/bin/convert
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
CURRENTDIR=`pwd`
|
||||
|
||||
# Resolve symlinks
|
||||
BASEDIR=$0
|
||||
while [ -h "$BASEDIR" ]; do
|
||||
ls=`ls -ld "$BASEDIR"`
|
||||
link=`expr "$ls" : '^.*-> \(.*\)$' 2>/dev/null`
|
||||
if expr "$link" : '^/' 2> /dev/null >/dev/null; then
|
||||
BASEDIR="$link"
|
||||
else
|
||||
BASEDIR="`dirname "$BASEDIR"`/$link"
|
||||
fi
|
||||
done
|
||||
BASEDIR=`dirname "$BASEDIR"`
|
||||
|
||||
SCRIPTNAME=`basename ${0}`
|
||||
|
||||
APPLICATION_HOME=$BASEDIR/../..
|
||||
|
||||
LIB_DIR=`find $BASEDIR/../lib -name "*.jar"`
|
||||
LIB_DIR=`echo $LIB_DIR | sed -e 's/ /:/g'`
|
||||
|
||||
CLASSPATH=${APPLICATION_HOME}/config/:$LIB_DIR
|
||||
|
||||
ARGUMENTS=
|
||||
VM_ARGUMENTS=
|
||||
for i in $@
|
||||
do
|
||||
if [ `expr $i : '-D.*'` != '0' ] ;then
|
||||
# Extract VM options
|
||||
VM_ARGUMENTS="$VM_ARGUMENTS $i"
|
||||
else
|
||||
ARGUMENTS="$ARGUMENTS $i"
|
||||
fi
|
||||
done
|
||||
|
||||
# Execute java
|
||||
java -Xmx1024m -XX:MaxPermSize=128m -cp $CLASSPATH -Djava.util.logging.config.file=${APPLICATION_HOME}/config/logging.properties $VM_ARGUMENTS ch.psi.fda.ui.ConversionMain $ARGUMENTS
|
||||
40
src/main/assembly/bin/scan
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
CURRENTDIR=`pwd`
|
||||
|
||||
# Resolve symlinks
|
||||
BASEDIR=$0
|
||||
while [ -h "$BASEDIR" ]; do
|
||||
ls=`ls -ld "$BASEDIR"`
|
||||
link=`expr "$ls" : '^.*-> \(.*\)$' 2>/dev/null`
|
||||
if expr "$link" : '^/' 2> /dev/null >/dev/null; then
|
||||
BASEDIR="$link"
|
||||
else
|
||||
BASEDIR="`dirname "$BASEDIR"`/$link"
|
||||
fi
|
||||
done
|
||||
BASEDIR=`dirname "$BASEDIR"`
|
||||
|
||||
SCRIPTNAME=`basename ${0}`
|
||||
|
||||
APPLICATION_HOME=$BASEDIR/../..
|
||||
|
||||
LIB_DIR=`find $BASEDIR/../lib -name "*.jar"`
|
||||
LIB_DIR=`echo $LIB_DIR | sed -e 's/ /:/g'`
|
||||
|
||||
CLASSPATH=${APPLICATION_HOME}/config/:$LIB_DIR
|
||||
|
||||
ARGUMENTS=
|
||||
VM_ARGUMENTS=
|
||||
for i in $@
|
||||
do
|
||||
if [ `expr $i : '-D.*'` != '0' ] ;then
|
||||
# Extract VM options
|
||||
VM_ARGUMENTS="$VM_ARGUMENTS $i"
|
||||
else
|
||||
ARGUMENTS="$ARGUMENTS $i"
|
||||
fi
|
||||
done
|
||||
|
||||
# Execute java
|
||||
java -Xmx1024m -XX:MaxPermSize=128m -Dch.psi.fda.home=${APPLICATION_HOME} -Djava.util.logging.config.file=${APPLICATION_HOME}/config/logging.properties $VM_ARGUMENTS -cp $CLASSPATH ch.psi.fda.ui.RemoteAcquisitionMain $ARGUMENTS
|
||||
40
src/main/assembly/bin/scan_local
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
CURRENTDIR=`pwd`
|
||||
|
||||
# Resolve symlinks
|
||||
BASEDIR=$0
|
||||
while [ -h "$BASEDIR" ]; do
|
||||
ls=`ls -ld "$BASEDIR"`
|
||||
link=`expr "$ls" : '^.*-> \(.*\)$' 2>/dev/null`
|
||||
if expr "$link" : '^/' 2> /dev/null >/dev/null; then
|
||||
BASEDIR="$link"
|
||||
else
|
||||
BASEDIR="`dirname "$BASEDIR"`/$link"
|
||||
fi
|
||||
done
|
||||
BASEDIR=`dirname "$BASEDIR"`
|
||||
|
||||
SCRIPTNAME=`basename ${0}`
|
||||
|
||||
APPLICATION_HOME=$BASEDIR/../..
|
||||
|
||||
LIB_DIR=`find $BASEDIR/../lib -name "*.jar"`
|
||||
LIB_DIR=`echo $LIB_DIR | sed -e 's/ /:/g'`
|
||||
|
||||
CLASSPATH=${APPLICATION_HOME}/config/:$LIB_DIR
|
||||
|
||||
ARGUMENTS=
|
||||
VM_ARGUMENTS=
|
||||
for i in $@
|
||||
do
|
||||
if [ `expr $i : '-D.*'` != '0' ] ;then
|
||||
# Extract VM options
|
||||
VM_ARGUMENTS="$VM_ARGUMENTS $i"
|
||||
else
|
||||
ARGUMENTS="$ARGUMENTS $i"
|
||||
fi
|
||||
done
|
||||
|
||||
# Execute java
|
||||
java -Xmx1024m -XX:MaxPermSize=128m -Dch.psi.fda.home=${APPLICATION_HOME} -Djava.util.logging.config.file=${APPLICATION_HOME}/config/logging.properties $VM_ARGUMENTS -cp $CLASSPATH ch.psi.fda.ui.AcquisitionMain $ARGUMENTS
|
||||
42
src/main/assembly/bin/server
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
CURRENTDIR=`pwd`
|
||||
|
||||
# Resolve symlinks
|
||||
BASEDIR=$0
|
||||
while [ -h "$BASEDIR" ]; do
|
||||
ls=`ls -ld "$BASEDIR"`
|
||||
link=`expr "$ls" : '^.*-> \(.*\)$' 2>/dev/null`
|
||||
if expr "$link" : '^/' 2> /dev/null >/dev/null; then
|
||||
BASEDIR="$link"
|
||||
else
|
||||
BASEDIR="`dirname "$BASEDIR"`/$link"
|
||||
fi
|
||||
done
|
||||
BASEDIR=`dirname "$BASEDIR"`
|
||||
|
||||
SCRIPTNAME=`basename ${0}`
|
||||
|
||||
APPLICATION_HOME=$BASEDIR/../..
|
||||
|
||||
LIB_DIR=`find $BASEDIR/../lib -name "*.jar"`
|
||||
LIB_DIR=`echo $LIB_DIR | sed -e 's/ /:/g'`
|
||||
|
||||
CLASSPATH=${APPLICATION_HOME}/config/:$LIB_DIR
|
||||
|
||||
ARGUMENTS=
|
||||
VM_ARGUMENTS=
|
||||
for i in $@
|
||||
do
|
||||
if [ `expr $i : '-D.*'` != '0' ] ;then
|
||||
# Extract VM options
|
||||
VM_ARGUMENTS="$VM_ARGUMENTS $i"
|
||||
else
|
||||
ARGUMENTS="$ARGUMENTS $i"
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
#HUB_BASE=$BASEDIR/../
|
||||
#export HUB_BASE
|
||||
java $VM_ARGUMENTS -cp $CLASSPATH -Dch.psi.fda.home=${APPLICATION_HOME} -Djava.util.logging.config.file=${APPLICATION_HOME}/config/logging.properties ch.psi.fda.rest.FdaServer $ARGUMENTS
|
||||
40
src/main/assembly/bin/viewer
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
CURRENTDIR=`pwd`
|
||||
|
||||
# Resolve symlinks
|
||||
BASEDIR=$0
|
||||
while [ -h "$BASEDIR" ]; do
|
||||
ls=`ls -ld "$BASEDIR"`
|
||||
link=`expr "$ls" : '^.*-> \(.*\)$' 2>/dev/null`
|
||||
if expr "$link" : '^/' 2> /dev/null >/dev/null; then
|
||||
BASEDIR="$link"
|
||||
else
|
||||
BASEDIR="`dirname "$BASEDIR"`/$link"
|
||||
fi
|
||||
done
|
||||
BASEDIR=`dirname "$BASEDIR"`
|
||||
|
||||
SCRIPTNAME=`basename ${0}`
|
||||
|
||||
APPLICATION_HOME=$BASEDIR/../..
|
||||
|
||||
LIB_DIR=`find $BASEDIR/../lib -name "*.jar"`
|
||||
LIB_DIR=`echo $LIB_DIR | sed -e 's/ /:/g'`
|
||||
|
||||
CLASSPATH=${APPLICATION_HOME}/config/:$LIB_DIR
|
||||
|
||||
ARGUMENTS=
|
||||
VM_ARGUMENTS=
|
||||
for i in $@
|
||||
do
|
||||
if [ `expr $i : '-D.*'` != '0' ] ;then
|
||||
# Extract VM options
|
||||
VM_ARGUMENTS="$VM_ARGUMENTS $i"
|
||||
else
|
||||
ARGUMENTS="$ARGUMENTS $i"
|
||||
fi
|
||||
done
|
||||
|
||||
# Execute java
|
||||
java -Xmx1024m -XX:MaxPermSize=128m -cp $CLASSPATH -Djava.util.logging.config.file=${APPLICATION_HOME}/config/logging.properties $VM_ARGUMENTS ch.psi.fda.ui.VisualizationZMQMain $ARGUMENTS
|
||||
40
src/main/assembly/bin/visualize
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
CURRENTDIR=`pwd`
|
||||
|
||||
# Resolve symlinks
|
||||
BASEDIR=$0
|
||||
while [ -h "$BASEDIR" ]; do
|
||||
ls=`ls -ld "$BASEDIR"`
|
||||
link=`expr "$ls" : '^.*-> \(.*\)$' 2>/dev/null`
|
||||
if expr "$link" : '^/' 2> /dev/null >/dev/null; then
|
||||
BASEDIR="$link"
|
||||
else
|
||||
BASEDIR="`dirname "$BASEDIR"`/$link"
|
||||
fi
|
||||
done
|
||||
BASEDIR=`dirname "$BASEDIR"`
|
||||
|
||||
SCRIPTNAME=`basename ${0}`
|
||||
|
||||
APPLICATION_HOME=$BASEDIR/../..
|
||||
|
||||
LIB_DIR=`find $BASEDIR/../lib -name "*.jar"`
|
||||
LIB_DIR=`echo $LIB_DIR | sed -e 's/ /:/g'`
|
||||
|
||||
CLASSPATH=${APPLICATION_HOME}/config/:$LIB_DIR
|
||||
|
||||
ARGUMENTS=
|
||||
VM_ARGUMENTS=
|
||||
for i in $@
|
||||
do
|
||||
if [ `expr $i : '-D.*'` != '0' ] ;then
|
||||
# Extract VM options
|
||||
VM_ARGUMENTS="$VM_ARGUMENTS $i"
|
||||
else
|
||||
ARGUMENTS="$ARGUMENTS $i"
|
||||
fi
|
||||
done
|
||||
|
||||
# Execute java
|
||||
java -Xmx1024m -XX:MaxPermSize=128m -cp $CLASSPATH -Djava.util.logging.config.file=${APPLICATION_HOME}/config/logging.properties $VM_ARGUMENTS ch.psi.fda.ui.VisualizationMain $ARGUMENTS
|
||||
BIN
src/main/assembly/www/apple-touch-icon-114x114-precomposed.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/main/assembly/www/apple-touch-icon-144x144-precomposed.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/main/assembly/www/apple-touch-icon-57x57-precomposed.png
Normal file
|
After Width: | Height: | Size: 730 B |
BIN
src/main/assembly/www/apple-touch-icon-72x72-precomposed.png
Normal file
|
After Width: | Height: | Size: 854 B |
BIN
src/main/assembly/www/apple-touch-icon-precomposed.png
Normal file
|
After Width: | Height: | Size: 730 B |
BIN
src/main/assembly/www/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 730 B |
1109
src/main/assembly/www/css/bootstrap-responsive.css
vendored
Normal file
9
src/main/assembly/www/css/bootstrap-responsive.min.css
vendored
Normal file
6158
src/main/assembly/www/css/bootstrap.css
vendored
Normal file
9
src/main/assembly/www/css/bootstrap.min.css
vendored
Normal file
22
src/main/assembly/www/css/main.css
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
|
||||
/* ==========================================================================
|
||||
Author's custom styles
|
||||
========================================================================== */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
src/main/assembly/www/favicon.ico
Normal file
|
After Width: | Height: | Size: 766 B |
BIN
src/main/assembly/www/img/glyphicons-halflings-white.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
src/main/assembly/www/img/glyphicons-halflings.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
222
src/main/assembly/www/index.html
Normal file
@@ -0,0 +1,222 @@
|
||||
<!DOCTYPE html>
|
||||
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
|
||||
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
|
||||
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
|
||||
<!--[if gt IE 8]><!-->
|
||||
<html class="no-js">
|
||||
<!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title></title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
padding-top: 60px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="css/bootstrap-responsive.min.css">
|
||||
<link rel="stylesheet" href="css/main.css">
|
||||
|
||||
<script src="js/vendor/modernizr-2.6.2-respond-1.1.0.min.js"></script>
|
||||
<script src="js/jquery-2.0.0.min.js"></script>
|
||||
<script type='text/javascript'>
|
||||
var base = '../hub';
|
||||
var stream;
|
||||
|
||||
function getVersion() {
|
||||
$.get(base+'/version', function(data) {
|
||||
$('#version').empty();
|
||||
$('#version').append(data)
|
||||
});
|
||||
}
|
||||
|
||||
function getBeamlines() {
|
||||
$.get(base, function(data) {
|
||||
/* update beamlines selection */
|
||||
|
||||
$('#selectionBeamline').empty();
|
||||
for (var i in data){
|
||||
beamline = data[i];
|
||||
$('#selectionBeamline').append('<option value="'+beamline+'">'+beamline+'</option>')
|
||||
}
|
||||
/* $('#selectionBeamline')[0].selectedIndex=0; */
|
||||
connectStream(data[0]);
|
||||
});
|
||||
}
|
||||
|
||||
function updateKeys(beamline, keys){
|
||||
keytag = $('#beamlineKeys');
|
||||
keytag.empty();
|
||||
table='<table class="table table-hover"><thead><tr><td>Key</td><td>Value</td></tr></thead><tbody>';
|
||||
|
||||
for(k in keys){
|
||||
table=table+'<tr><td>'+k+'</td><td>'+
|
||||
'<div class="input-append">'+
|
||||
'<input type="text" value="'+keys[k]+'" onchange="setKey(\''+beamline+'\',\''+k+'\',$(this).val())">'+
|
||||
//'<button class="btn" type="button" onclick="setKey(\''+beamline+'\',\''+k+'\',$(this).prev().val())">Update</button>'+
|
||||
'<button class="btn" type="button" onclick="deleteKey(\''+beamline+'\',\''+k+'\')">Delete</button>'+
|
||||
'</div>'+
|
||||
'</td></tr>';
|
||||
}
|
||||
|
||||
table = table+'<tr>'+
|
||||
'<td><input id="keyToAdd" type="text" placeholder="Key"></td>'+
|
||||
'<td><div class="input-append">'+
|
||||
'<input id="valueToAdd"type="text" placeholder="Value">'+
|
||||
'<button class="btn" type="button" onclick="setKey(\''+beamline+'\',$(\'#keyToAdd\').val(),$(\'#valueToAdd\').val())">Add</button>'+
|
||||
'</div></td>'+
|
||||
'</tr>';
|
||||
|
||||
table = table+'</table></tbody>';
|
||||
keytag.append(table);
|
||||
}
|
||||
|
||||
function connectStream(beamline) {
|
||||
closeStream();
|
||||
stream = new EventSource(base + '/' + beamline + '/stream');
|
||||
stream.onmessage = function(event) {
|
||||
keys=JSON.parse(event.data)
|
||||
updateKeys(beamline, keys);
|
||||
|
||||
};
|
||||
getKeys(beamline);
|
||||
}
|
||||
|
||||
function closeStream() {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
function getKeys(beamline){
|
||||
$.get(base+'/'+beamline+'/keys', function(data) {
|
||||
updateKeys(beamline, data );
|
||||
});
|
||||
}
|
||||
|
||||
function setKey(beamline, key, value){
|
||||
$.ajax({
|
||||
url: base+'/'+beamline+'/keys/'+key,
|
||||
type: 'PUT',
|
||||
data: value,
|
||||
success: function(result) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function deleteKey(beamline, key){
|
||||
$.ajax({
|
||||
url: base+'/'+beamline+'/keys/'+key,
|
||||
type: 'DELETE',
|
||||
success: function(result) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addBeamline(beamline){
|
||||
getKeys(beamline); /*create beamline*/
|
||||
getBeamlines();
|
||||
}
|
||||
|
||||
function deleteBeamline(beamline){
|
||||
$.ajax({
|
||||
url: base+'/'+beamline,
|
||||
type: 'DELETE',
|
||||
success: function(result) {
|
||||
getBeamlines(); /* Update beamline list */
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- <script>
|
||||
var source = new EventSource('../server-sent-events/');
|
||||
source.onmessage = function(e) {
|
||||
$('#messagefield') = e.data;
|
||||
};
|
||||
</script> -->
|
||||
|
||||
<!--[if lt IE 7]>
|
||||
<p class="chromeframe">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">activate Google Chrome Frame</a> to improve your experience.</p>
|
||||
<![endif]-->
|
||||
|
||||
<!-- This code is taken from http://twitter.github.com/bootstrap/examples/hero.html -->
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="btn btn-navbar" data-toggle="collapse"
|
||||
data-target=".nav-collapse"> <span class="icon-bar"></span> <span
|
||||
class="icon-bar"></span> <span class="icon-bar"></span>
|
||||
</a> <a class="brand" href="#">hub</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<!-- Main hero unit for a primary marketing message or call to action -->
|
||||
<!-- <div class="hero-unit">
|
||||
<p>This is the central Hub administration page ...</p>
|
||||
</div> -->
|
||||
|
||||
<!-- Example row of columns -->
|
||||
<div class="row">
|
||||
<div class="span5">
|
||||
<h2>Key Group</h2>
|
||||
<div>
|
||||
<select id="selectionBeamline">
|
||||
<!-- <option value="sydney">Sydney</option> -->
|
||||
</select>
|
||||
</div>
|
||||
<div id="beamlineKeys"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="span5">
|
||||
<h2>Key Group Management</h2>
|
||||
<div class="input-append">
|
||||
<input class="span2" id="appendedInputButton" placeholder="Key Group" type="text">
|
||||
<button id="addBeamlineBtn" class="btn" type="button" onclick="addBeamline($(this).prev().val());$(this).prev().val('')">Add</button>
|
||||
<button id="addBeamlineBtn" class="btn" type="button" onclick="deleteBeamline($(this).prev().prev().val());$(this).prev().prev().val('')">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<footer>
|
||||
<p>Hub - Version <span id='version'></span> - © Paul Scherrer Institute 2013</p>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
<!-- /container -->
|
||||
|
||||
<script>
|
||||
/* update beamlines */
|
||||
getVersion();
|
||||
getBeamlines();
|
||||
$('#selectionBeamline').change(function(){connectStream($('#selectionBeamline').val())});
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
window.jQuery
|
||||
|| document
|
||||
.write('<script src="js/vendor/jquery-1.9.1.min.js"><\/script>')
|
||||
</script>
|
||||
|
||||
<script src="js/vendor/bootstrap.min.js"></script>
|
||||
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
6
src/main/assembly/www/js/jquery-2.0.0.min.js
vendored
Normal file
1
src/main/assembly/www/js/main.js
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
2268
src/main/assembly/www/js/vendor/bootstrap.js
vendored
Normal file
6
src/main/assembly/www/js/vendor/bootstrap.min.js
vendored
Normal file
5
src/main/assembly/www/js/vendor/jquery-1.9.1.min.js
vendored
Normal file
11
src/main/assembly/www/js/vendor/modernizr-2.6.2-respond-1.1.0.min.js
vendored
Normal file
24
src/main/java/ch/psi/fda/deserializer/DataDeserializer.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.deserializer;
|
||||
|
||||
public interface DataDeserializer {
|
||||
public void read();
|
||||
}
|
||||
589
src/main/java/ch/psi/fda/deserializer/DataDeserializerMDA.java
Normal file
@@ -0,0 +1,589 @@
|
||||
package ch.psi.fda.deserializer;
|
||||
|
||||
import hep.io.xdr.XDRInputStream;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.messages.Message;
|
||||
import ch.psi.fda.messages.Metadata;
|
||||
import ch.psi.fda.messages.StreamDelimiterMessage;
|
||||
|
||||
/**
|
||||
* Deserializer MDA file
|
||||
* TODO Need to be optimized as currently the while file is read into memory when creating this object.
|
||||
*/
|
||||
public class DataDeserializerMDA implements DataDeserializer {
|
||||
|
||||
private static Logger logger = Logger.getLogger(DataDeserializerMDA.class.getName());
|
||||
|
||||
private EventBus bus;
|
||||
private RecursiveReturnContainer c;
|
||||
|
||||
public DataDeserializerMDA(EventBus b, File file){
|
||||
this.bus = b;
|
||||
|
||||
try{
|
||||
c = read(new FileInputStream(file));
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private RecursiveReturnContainer read(InputStream in) throws IOException {
|
||||
logger.fine("Read MDA input stream");
|
||||
|
||||
XDRInputStream x = new XDRInputStream(in);
|
||||
|
||||
|
||||
/**
|
||||
* Read file header
|
||||
*/
|
||||
float version = x.readFloat();
|
||||
logger.fine("MDA - version:: "+version);
|
||||
int scanNumber = x.readInt();
|
||||
logger.fine("MDA - scan number:: "+scanNumber);
|
||||
int rank = x.readInt();
|
||||
logger.fine("MDA - rank:: "+rank);
|
||||
|
||||
for(int i=rank;i>0; i--){
|
||||
// Read dimension size
|
||||
int dimension = x.readInt();
|
||||
logger.fine("MDA - dimension["+i+"] :: "+dimension);
|
||||
}
|
||||
|
||||
int isRegular = x.readInt(); //(true=1, false=0)
|
||||
logger.fine("MDA - isRegular:: "+isRegular);
|
||||
int pExtra = x.readInt(); // Number of extra pvs
|
||||
logger.fine("MDA - pExtra:: "+pExtra);
|
||||
|
||||
|
||||
/**
|
||||
* Read data
|
||||
*/
|
||||
RecursiveReturnContainer container = readData(x);
|
||||
|
||||
/**
|
||||
* Read extra PVs
|
||||
*/
|
||||
if(pExtra > 0){
|
||||
int length;
|
||||
logger.fine("Extra PVs");
|
||||
|
||||
int numExtra = x.readInt();
|
||||
logger.fine("MDA - number of extra pvs:: "+numExtra);
|
||||
|
||||
for(int i = 0;i<numExtra; i++){
|
||||
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String pvName = x.readString();
|
||||
logger.fine("MDA - pv name:: "+pvName);
|
||||
}
|
||||
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String pvDescription = x.readString(); // description
|
||||
logger.fine("MDA - pv desciption:: "+pvDescription);
|
||||
}
|
||||
|
||||
int pvType = x.readInt();
|
||||
logger.fine("MDA - pv type:: "+pvType);
|
||||
|
||||
|
||||
int pvCount = 0;
|
||||
String pvUnit;
|
||||
if(pvType != 0){ // if pv type != DBR_STRING
|
||||
pvCount = x.readInt();
|
||||
logger.fine("MDA - pv count:: "+pvCount);
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
pvUnit = x.readString();
|
||||
logger.fine("MDA - pv unit:: "+ pvUnit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(pvType == 0){ // pvType == DBR_STRING
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String pvValue = x.readString();
|
||||
logger.fine("MDA - pv value:: "+pvValue);
|
||||
}
|
||||
}
|
||||
else if(pvType == 32){ // pvType == DBR_CTRL_CHAR
|
||||
for(int u=0;u<pvCount; u++){
|
||||
char pvValue = x.readChar();
|
||||
logger.fine("MDA - pv value:: "+pvValue);
|
||||
}
|
||||
}
|
||||
else if(pvType == 29){ // pvType == DBR_CTRL_SHORT
|
||||
for(int u=0;u<pvCount; u++){
|
||||
int pvValue = x.readInt();
|
||||
logger.fine("MDA - pv value:: "+pvValue);
|
||||
}
|
||||
}
|
||||
else if(pvType == 33){ // pvType == DBR_CTRL_LONG
|
||||
for(int u=0;u<pvCount; u++){
|
||||
int pvValue = x.readInt();
|
||||
logger.fine("MDA - pv value:: "+pvValue);
|
||||
}
|
||||
}
|
||||
else if(pvType == 30){ // pvType == DBR_CTRL_FLOAT
|
||||
for(int u=0;u<pvCount; u++){
|
||||
float pvValue = x.readFloat();
|
||||
logger.fine("MDA - pv value:: "+pvValue);
|
||||
}
|
||||
}
|
||||
else if(pvType == 34){ // pvType == DBR_CTRL_DOUBLE
|
||||
for(int u=0;u<pvCount; u++){
|
||||
double pvValue = x.readDouble();
|
||||
logger.fine("MDA - pv value:: "+pvValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
logger.fine("Reading and conversion done ...");
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
|
||||
private RecursiveReturnContainer readData(XDRInputStream x) throws IOException {
|
||||
|
||||
int length;
|
||||
|
||||
logger.fine("Read scan");
|
||||
|
||||
/**
|
||||
* Read scan header
|
||||
*/
|
||||
int scanRank = x.readInt();
|
||||
logger.fine("MDA - scan rank (this):: " + scanRank);
|
||||
int npts = x.readInt();
|
||||
logger.fine("MDA - number of requested points (npts):: " + npts);
|
||||
int currentPoint = x.readInt();
|
||||
logger.fine("MDA - current point:: " + currentPoint);
|
||||
|
||||
// Read pointers to lower scans
|
||||
if(scanRank > 1){
|
||||
// For 1D scans this block is never reached
|
||||
for(int i=0;i<npts;i++){
|
||||
int pointerLowerScans = x.readInt(); // pointer to lower scans
|
||||
logger.fine("MDA - pointer lower scans:: "+pointerLowerScans);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read scan info
|
||||
*/
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String scanName = x.readString();
|
||||
logger.fine("MDA - scanName:: "+scanName);
|
||||
}
|
||||
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String scanTime = x.readString(); // timestamp
|
||||
logger.fine("MDA - scanTime:: "+ scanTime);
|
||||
}
|
||||
|
||||
|
||||
int numberOfPositioners = x.readInt();
|
||||
logger.fine("MDA - number of positioners:: "+numberOfPositioners);
|
||||
int numberOfDetectors = x.readInt();
|
||||
logger.fine("MDA - number of detectors:: "+ numberOfDetectors);
|
||||
int numberOfTriggers = x.readInt();
|
||||
logger.fine("MDA - number of triggers:: "+ numberOfTriggers);
|
||||
|
||||
|
||||
List<Metadata> componentMetadataList = new ArrayList<>();
|
||||
/**
|
||||
* Read positioners metadata
|
||||
*/
|
||||
for(int i = 0; i<numberOfPositioners; i++){
|
||||
|
||||
logger.fine("Read positioner metadata");
|
||||
|
||||
int positionerNumber = x.readInt();
|
||||
logger.fine("MDA - positioner number:: "+positionerNumber);
|
||||
|
||||
length = x.readInt();
|
||||
if(length>0){
|
||||
String positionerName = x.readString();
|
||||
logger.fine("MDA - positioner name:: "+positionerName);
|
||||
// MDA starts at dimension number 1 we start at 0
|
||||
componentMetadataList.add(new Metadata(positionerName,scanRank-1));
|
||||
}
|
||||
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String positionerDescription = x.readString();
|
||||
logger.fine("MDA - positioner description:: "+positionerDescription);
|
||||
}
|
||||
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String positionerStepMode = x.readString();
|
||||
logger.fine("MDA - positioner step mode:: "+positionerStepMode);
|
||||
}
|
||||
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String positionerUnit = x.readString();
|
||||
logger.fine("MDA - positioner unit:: "+positionerUnit);
|
||||
}
|
||||
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String readbackName = x.readString();
|
||||
logger.fine("MDA - readback name:: "+readbackName);
|
||||
}
|
||||
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String readbackDescription = x.readString();
|
||||
logger.fine("MDA - readback description:: "+readbackDescription);
|
||||
}
|
||||
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String readbackUnit = x.readString();
|
||||
logger.fine("MDA - readback unit:: "+readbackUnit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read detector metadata
|
||||
*/
|
||||
for(int i=0; i<numberOfDetectors; i++){
|
||||
logger.fine("Read detector metadata");
|
||||
|
||||
int detectorNumber = x.readInt();
|
||||
logger.fine("MDA - detector number:: "+ detectorNumber);
|
||||
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String detectorName = x.readString();
|
||||
logger.fine("MDA - detector name:: "+detectorName);
|
||||
// MDA starts at dimension number 1 we start at 0
|
||||
componentMetadataList.add(new Metadata(detectorName, scanRank-1));
|
||||
}
|
||||
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String detectorDescription = x.readString();
|
||||
logger.fine("MDA - detector description:: "+detectorDescription);
|
||||
}
|
||||
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String detectorUnit = x.readString();
|
||||
logger.fine("MDA - detector unit:: "+detectorUnit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read trigger metadata
|
||||
*/
|
||||
for(int i=0; i<numberOfTriggers; i++){
|
||||
logger.fine("Read trigger metadata");
|
||||
|
||||
int triggerNumber = x.readInt();
|
||||
logger.fine("MDA - trigger number:: "+triggerNumber);
|
||||
|
||||
length = x.readInt();
|
||||
if(length > 0){
|
||||
String triggerName = x.readString();
|
||||
logger.fine("MDA - trigger name:: "+triggerName);
|
||||
}
|
||||
|
||||
float triggerCommand = x.readFloat();
|
||||
logger.fine("MDA - trigger command:: "+triggerCommand);
|
||||
}
|
||||
|
||||
|
||||
ArrayList<Double[]> data = new ArrayList<Double[]>();
|
||||
|
||||
/**
|
||||
* Read positioner data (readback)
|
||||
*/
|
||||
for(int i = 0; i<numberOfPositioners; i++){
|
||||
|
||||
logger.fine("Read positioner data");
|
||||
|
||||
Double[] pdata = new Double[npts];
|
||||
|
||||
StringBuffer b = new StringBuffer();
|
||||
b.append("[ ");
|
||||
for(int t=0; t<npts; t++){
|
||||
pdata[t]=x.readDouble();
|
||||
b.append(pdata[t]+" ");
|
||||
}
|
||||
b.append("]");
|
||||
logger.fine("MDA - positioner "+b.toString());
|
||||
|
||||
data.add(pdata);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read detector data
|
||||
*/
|
||||
for(int i=0; i<numberOfDetectors; i++){
|
||||
logger.fine("Read detector data");
|
||||
Double[] pdata = new Double[npts];
|
||||
|
||||
StringBuffer b = new StringBuffer();
|
||||
b.append("[ ");
|
||||
for(int t=0; t<npts; t++){
|
||||
pdata[t] = new Double(x.readFloat());
|
||||
b.append(pdata[t]+" ");
|
||||
}
|
||||
b.append("]");
|
||||
logger.fine("MDA - detector "+b.toString());
|
||||
|
||||
data.add(pdata);
|
||||
}
|
||||
|
||||
logger.fine("Read scan done ...");
|
||||
|
||||
|
||||
RecursiveReturnContainer cont = new RecursiveReturnContainer();
|
||||
// Update component metadata
|
||||
cont.getMetadata().addAll(componentMetadataList);
|
||||
|
||||
if(scanRank > 1){
|
||||
/**
|
||||
* Conversion logic if scan rank is > 1
|
||||
*/
|
||||
|
||||
/**
|
||||
* Read all scans recursively
|
||||
*/
|
||||
for(int i=0;i<npts;i++){
|
||||
|
||||
// Recursive call
|
||||
RecursiveReturnContainer container = readData(x);
|
||||
|
||||
if(i==0){
|
||||
// For the first scan of each dimension component data is read and stored
|
||||
cont.getMetadata().addAll(container.getMetadata());
|
||||
}
|
||||
|
||||
logger.fine("Convert data structure [rank="+scanRank+"] ...");
|
||||
for(Message m: container.getMessage()){
|
||||
if(m instanceof DataMessage){
|
||||
// Add own data to message and pass it to container
|
||||
DataMessage mm = new DataMessage(new ArrayList<Metadata>()); // Workaround
|
||||
for(Double[] d: data){
|
||||
mm.getData().add(d[i]);
|
||||
}
|
||||
mm.getData().addAll(((DataMessage) m).getData());
|
||||
cont.getMessage().add(mm);
|
||||
}
|
||||
else if(m instanceof StreamDelimiterMessage){
|
||||
// Just pass message to own container
|
||||
cont.getMessage().add(m);
|
||||
}
|
||||
}
|
||||
|
||||
logger.fine("Conversion done [rank="+scanRank+"]");
|
||||
}
|
||||
|
||||
// Add dimension delimiter message
|
||||
StreamDelimiterMessage m = new StreamDelimiterMessage(scanRank);
|
||||
cont.getMessage().add(m);
|
||||
}
|
||||
else{
|
||||
/**
|
||||
* Conversion logic if scan rank is 1
|
||||
*/
|
||||
|
||||
logger.fine("Convert data structure [rank="+scanRank+"]...");
|
||||
|
||||
for(int t = 0; t<npts ; t++){
|
||||
DataMessage m = new DataMessage(new ArrayList<Metadata>()); // workaround
|
||||
for(Double[] d: data){
|
||||
m.getData().add(d[t]);
|
||||
}
|
||||
cont.getMessage().add(m);
|
||||
}
|
||||
|
||||
// Add dimension delimiter message
|
||||
StreamDelimiterMessage m = new StreamDelimiterMessage(scanRank);
|
||||
cont.getMessage().add(m);
|
||||
|
||||
|
||||
logger.fine("Conversion done [rank="+scanRank+"]");
|
||||
}
|
||||
|
||||
return(cont);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read() {
|
||||
// Add data to queue
|
||||
for(Message m: c.getMessage()){
|
||||
if(m instanceof DataMessage){
|
||||
DataMessage dm = (DataMessage)m;
|
||||
dm.getMetadata().addAll(c.getMetadata()); // WORKAROUND !!!! ideally the reference to metadata is set while creating the
|
||||
// data message. Then there would be only one list with one reference. In this case we now have multiple lists!
|
||||
}
|
||||
bus.post(m);
|
||||
}
|
||||
bus.post(new EndOfStreamMessage());
|
||||
}
|
||||
}
|
||||
|
||||
class RecursiveReturnContainer{
|
||||
private List<Message> message = new ArrayList<Message>();
|
||||
private List<Metadata> metadata = new ArrayList<>();
|
||||
|
||||
public List<Message> getMessage() {
|
||||
return message;
|
||||
}
|
||||
public List<Metadata> getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* http://www.aps.anl.gov/bcda/synApps/sscan/saveData_fileFormat.txt
|
||||
*
|
||||
* scan file format
|
||||
|
||||
* FILE HEADER
|
||||
* xdr_float: VERSION (1.3)
|
||||
* xdr_long: scan number
|
||||
* xdr_short data's rank
|
||||
* xdr_vector(rank, xdr_int) dims;
|
||||
* xdr_int isRegular (true=1, false=0)
|
||||
* xdr_long: pointer to the extra pvs
|
||||
*
|
||||
*
|
||||
* SCAN
|
||||
* HEADER:
|
||||
* xdr_short: this scan's rank
|
||||
* xdr_long: number of requested points (NPTS)
|
||||
* xdr_long: current point (CPT)
|
||||
* if the scan rank is > 1
|
||||
* xdr_vector(NPTS, xdr_long) pointer to the lower scans
|
||||
*
|
||||
* INFO:
|
||||
* xdr_counted_string: scan name
|
||||
* xdr_counted_string: time stamp
|
||||
*
|
||||
*
|
||||
* xdr_int: number of positioners
|
||||
* xdr_int: number of detectors
|
||||
* xdr_int: number of triggers
|
||||
*
|
||||
* for each positioner
|
||||
* xdr_int: positioner number
|
||||
* xdr_counted_string: positioner name
|
||||
* xdr_counted_string: positioner desc
|
||||
* xdr_counted_string: positioner step mode
|
||||
* xdr_counted_string: positioner unit
|
||||
* xdr_counted_string: readback name
|
||||
* xdr_counted_string: readback description
|
||||
* xdr_counted_string: readback unit
|
||||
*
|
||||
* for each detector
|
||||
* xdr_int: detector number
|
||||
* xdr_counted_string: detector name
|
||||
* xdr_counted_string: detector desc
|
||||
* xdr_counted_string: detector unit
|
||||
*
|
||||
* for each trigger
|
||||
* xdr_int: trigger number
|
||||
* xdr_counted_string: trigger name
|
||||
* xdr_float: trigger command
|
||||
*
|
||||
* DATA:
|
||||
* for each positioner
|
||||
* xdr_vector(NPTS, xdr_double): readback array
|
||||
*
|
||||
* for each detector
|
||||
* xdr_vector(NPTS, xdr_float): detector array
|
||||
*
|
||||
* [SCAN]
|
||||
* ...
|
||||
* ...
|
||||
* ...
|
||||
* [SCAN]
|
||||
*
|
||||
* EXTRA PVs
|
||||
* xdr_int: number of extra pvs
|
||||
*
|
||||
* for each pv
|
||||
* xdr_counted_string: name
|
||||
* xdr_counted_string: desc
|
||||
* xdr_int: type
|
||||
* if type != DBR_STRING
|
||||
* xdr_long: count
|
||||
* xdr_counted_string: unit
|
||||
*
|
||||
* depending on the type:
|
||||
* DBR_STRING:
|
||||
* xdr_counted_string: value
|
||||
* DBR_CTRL_CHAR:
|
||||
* xdr_vector(count, xdr_char): value
|
||||
* DBR_CTRL_SHORT:
|
||||
* xdr_vector(count, xdr_short): value
|
||||
* DBR_CTRL_LONG:
|
||||
* xdr_vector(count, xdr_long): value
|
||||
* DBR_CTRL_FLOAT:
|
||||
* xdr_vector(count, xdr_float): value
|
||||
* DBR_CTRL_DOUBLE:
|
||||
* xdr_vector(count, xdr_double): value
|
||||
* -----------------------------------------------------------------------
|
||||
*
|
||||
* A 1D scan looks like this:
|
||||
*
|
||||
* header
|
||||
* extra PV's
|
||||
*
|
||||
* A 2D scan looks like this
|
||||
*
|
||||
* header
|
||||
* scan2
|
||||
* scan1
|
||||
* scan1
|
||||
* ...
|
||||
* extra PV's
|
||||
*
|
||||
* A 3D scan looks like this
|
||||
*
|
||||
* header
|
||||
* scan3
|
||||
* scan2
|
||||
* scan1
|
||||
* scan1
|
||||
* ...
|
||||
* scan2
|
||||
* scan1
|
||||
* scan1
|
||||
* ...
|
||||
* ...
|
||||
* extra PV's
|
||||
*
|
||||
*/
|
||||
205
src/main/java/ch/psi/fda/deserializer/DataDeserializerTXT.java
Normal file
@@ -0,0 +1,205 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.deserializer;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.messages.Metadata;
|
||||
import ch.psi.fda.messages.StreamDelimiterMessage;
|
||||
|
||||
/**
|
||||
* Deserializer for text files
|
||||
*/
|
||||
public class DataDeserializerTXT implements DataDeserializer {
|
||||
|
||||
private static Logger logger = Logger.getLogger(DataDeserializerTXT.class.getName());
|
||||
|
||||
private EventBus bus;
|
||||
private List<Metadata> metadata;
|
||||
private File file;
|
||||
|
||||
private List<Integer> dindex;
|
||||
private List<Integer> iindex;
|
||||
|
||||
public DataDeserializerTXT(EventBus b, File file){
|
||||
this.bus = b;
|
||||
this.file = file;
|
||||
this.dindex = new ArrayList<Integer>();
|
||||
this.iindex = new ArrayList<Integer>();
|
||||
|
||||
|
||||
this.metadata = new ArrayList<>();
|
||||
try{
|
||||
// Read metadata
|
||||
// Open file
|
||||
BufferedReader reader = new BufferedReader(new FileReader(file));
|
||||
|
||||
// Read file
|
||||
String line;
|
||||
|
||||
// First line is id
|
||||
line = reader.readLine();
|
||||
line = line.replaceAll("^ *# *", "");
|
||||
String[] ids = line.split("\t");
|
||||
|
||||
// Second line dimension
|
||||
line = reader.readLine();
|
||||
line = line.replaceAll("^ *# *", "");
|
||||
String[] dimensions = line.split("\t");
|
||||
|
||||
// Create data message metadata
|
||||
Integer d = -1;
|
||||
for(int i=0;i<ids.length;i++){
|
||||
Integer dimension = Integer.parseInt(dimensions[i]);
|
||||
metadata.add(new Metadata(ids[i], dimension));
|
||||
|
||||
// Store the first index of the first component
|
||||
// in each dimension ...
|
||||
if(!d.equals(dimension)){
|
||||
logger.finest("Add component index: "+i);
|
||||
dindex.add(dimension);
|
||||
iindex.add(i);
|
||||
d=dimension;
|
||||
}
|
||||
}
|
||||
|
||||
// Close file
|
||||
reader.close();
|
||||
}
|
||||
catch(Exception e){
|
||||
throw new RuntimeException("Unable to read file metadata and initialize data queue",e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read() {
|
||||
try{
|
||||
|
||||
List<Double> checklist = new ArrayList<Double>(dindex.size());
|
||||
for(int i=0;i<dindex.size();i++){
|
||||
checklist.add(null);
|
||||
}
|
||||
|
||||
// Open file
|
||||
BufferedReader reader = new BufferedReader(new FileReader(file));
|
||||
|
||||
// Read file
|
||||
String line;
|
||||
while((line=reader.readLine())!=null){
|
||||
|
||||
// Ignore empty lines
|
||||
if(line.matches("^ *$")){
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore comment lines
|
||||
if(line.matches("^ *# *.*")){
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create and populate new data message
|
||||
String[] data = line.split("\t");
|
||||
DataMessage message = new DataMessage(metadata);
|
||||
for (String d : data) {
|
||||
// Remove spaces at the end and beginning of the value
|
||||
d = d.trim();
|
||||
|
||||
// If the String does not contains spaces we assume that it is a double
|
||||
if (! d.contains(" ")) {
|
||||
// Scalar value
|
||||
|
||||
Object value;
|
||||
try {
|
||||
value = new Double(d);
|
||||
} catch (NumberFormatException e) {
|
||||
// We treat it as a String
|
||||
// TODO Need to find a way to treat other data formats
|
||||
value = d;
|
||||
}
|
||||
|
||||
// Add data to message
|
||||
message.getData().add(value);
|
||||
} else {
|
||||
try {
|
||||
// If the string contains spaces we treat it as an array
|
||||
String[] values = d.split(" ");
|
||||
double[] dv = new double[values.length];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
dv[i] = new Double(values[i]);
|
||||
}
|
||||
// Add data to message
|
||||
message.getData().add(dv);
|
||||
} catch (NumberFormatException e) {
|
||||
// Workaround
|
||||
// TODO Need to find a way to treat the array if it is not a double array
|
||||
message.getData().add(new Object());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Check whether to issue a end of dimension control message
|
||||
for(int t=0;t<iindex.size();t++){
|
||||
Integer i = iindex.get(t);
|
||||
if(dindex.get(t)>0){
|
||||
Double d = (Double) message.getData().get(i);
|
||||
if(checklist.get(i)!=null &&!checklist.get(i).equals(d)){
|
||||
// If value changes issue a dimension delimiter message
|
||||
bus.post(new StreamDelimiterMessage(dindex.get(t)-1));
|
||||
}
|
||||
checklist.set(i, d);
|
||||
}
|
||||
}
|
||||
|
||||
// Put message to queue
|
||||
bus.post(message);
|
||||
|
||||
// TODO Need to detect dimension boundaries
|
||||
|
||||
}
|
||||
|
||||
// Add delimiter for all the dimensions
|
||||
for(int i=dindex.size()-1;i>=0;i--){
|
||||
bus.post(new StreamDelimiterMessage(dindex.get(i)));
|
||||
}
|
||||
|
||||
// Place end of stream message
|
||||
bus.post(new EndOfStreamMessage());
|
||||
|
||||
// Close file
|
||||
reader.close();
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Data deserializer had a problem reading the specified datafile",e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
75
src/main/java/ch/psi/fda/gui/ProgressPanel.java
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ScanProgressPanel.java
|
||||
*
|
||||
* Created on Dec 1, 2009, 2:20:26 PM
|
||||
*/
|
||||
|
||||
package ch.psi.fda.gui;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public class ProgressPanel extends javax.swing.JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private javax.swing.JButton abortButton;
|
||||
private javax.swing.JProgressBar progressBar;
|
||||
|
||||
/** Creates new form ScanProgressPanel */
|
||||
public ProgressPanel() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
*/
|
||||
private void initComponents() {
|
||||
|
||||
progressBar = new javax.swing.JProgressBar();
|
||||
abortButton = new javax.swing.JButton();
|
||||
|
||||
progressBar.setIndeterminate(true);
|
||||
progressBar.setPreferredSize(new java.awt.Dimension(100, 24));
|
||||
|
||||
abortButton.setText("Abort");
|
||||
abortButton.setFocusable(false);
|
||||
abortButton.setPreferredSize(new java.awt.Dimension(70, 25));
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 152, Short.MAX_VALUE)
|
||||
.addComponent(abortButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(abortButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
}
|
||||
|
||||
public void addActionListener(ActionListener l){
|
||||
abortButton.addActionListener(l);
|
||||
}
|
||||
|
||||
public void done(){
|
||||
progressBar.setIndeterminate(false);
|
||||
progressBar.setValue(100);
|
||||
abortButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
64
src/main/java/ch/psi/fda/gui/ScrollableFlowPanel.java
Normal file
@@ -0,0 +1,64 @@
|
||||
package ch.psi.fda.gui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.Scrollable;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
public class ScrollableFlowPanel extends JPanel implements Scrollable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public void setBounds(int x, int y, int width, int height) {
|
||||
super.setBounds(x, y, getParent().getWidth(), height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(getWidth(), getPreferredHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredScrollableViewportSize() {
|
||||
return super.getPreferredSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
|
||||
int hundredth = (orientation == SwingConstants.VERTICAL ? getParent().getHeight() : getParent().getWidth()) / 100;
|
||||
return (hundredth == 0 ? 1 : hundredth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
|
||||
return orientation == SwingConstants.VERTICAL ? getParent().getHeight() : getParent().getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getScrollableTracksViewportWidth() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getScrollableTracksViewportHeight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private int getPreferredHeight() {
|
||||
int rv = 0;
|
||||
for (int k = 0, count = getComponentCount(); k < count; k++) {
|
||||
Component comp = getComponent(k);
|
||||
Rectangle r = comp.getBounds();
|
||||
int height = r.y + r.height;
|
||||
if (height > rv)
|
||||
rv = height;
|
||||
}
|
||||
rv += ((FlowLayout) getLayout()).getVgap();
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
152
src/main/java/ch/psi/fda/rest/ExecutionEngine.java
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2013 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but without any
|
||||
* warranty; without even the implied warranty of merchantability or fitness for
|
||||
* a particular purpose. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package ch.psi.fda.rest;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
|
||||
import ch.psi.fda.edescriptor.EDescriptor;
|
||||
import ch.psi.jcae.ChannelService;
|
||||
|
||||
/**
|
||||
* Main engine for data acquisition.
|
||||
*/
|
||||
public class ExecutionEngine {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ExecutionEngine.class.getName());
|
||||
|
||||
private final ChannelService cService;
|
||||
private final ZMQDataService zmqService;
|
||||
|
||||
private final ExecutorService eservice = Executors.newSingleThreadExecutor();
|
||||
private final Map<String, JobEntry> erequests = new HashMap<>();
|
||||
|
||||
@Inject
|
||||
public ExecutionEngine(ChannelService cService, ZMQDataService zmqService) {
|
||||
this.zmqService = zmqService;
|
||||
this.cService = cService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit a scan to be executed. This will generate an execution request which is
|
||||
* enqueued in the execution queue.
|
||||
*
|
||||
* @param trackingId Tracking id
|
||||
* @param edescriptor Edescriptor
|
||||
*/
|
||||
public void submit(String trackingId, EDescriptor edescriptor){
|
||||
|
||||
logger.info("Submitting job with trackingId ----" + trackingId);
|
||||
if(erequests.keySet().contains(trackingId) && !erequests.get(trackingId).getFuture().isDone()){ // Allow finished tracking ids to be reused for new tasks
|
||||
throw new IllegalArgumentException("A request with tracking ID "+trackingId+" is already submitted");
|
||||
}
|
||||
|
||||
ExecutionJob job = new ExecutionJob(cService, zmqService, trackingId, edescriptor);
|
||||
Future<?> future = eservice.submit(job);
|
||||
erequests.put(trackingId, new JobEntry(future, job));
|
||||
}
|
||||
|
||||
|
||||
public void terminateAll() {
|
||||
logger.info("Terminate all jobs");
|
||||
Set<String> keys = new HashSet<String>();
|
||||
keys.addAll(erequests.keySet());
|
||||
for(String trackingId: keys){
|
||||
try{
|
||||
terminate(trackingId);
|
||||
}
|
||||
catch(Exception e){
|
||||
logger.log(Level.WARNING, "", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate the request which is identified by its tracking id. If the request
|
||||
* is still in the execution queue it gets removed there.
|
||||
*
|
||||
* @param trackingId Tracking ID
|
||||
*/
|
||||
public void terminate(String trackingId){
|
||||
logger.info("Terminate TrackingId: "+trackingId);
|
||||
|
||||
if(!erequests.containsKey(trackingId)){
|
||||
throw new WebApplicationException("There is no request for tracking id "+trackingId, 404);
|
||||
}
|
||||
|
||||
final JobEntry f = erequests.get(trackingId);
|
||||
f.getFuture().cancel(true);
|
||||
f.getJob().stop();
|
||||
|
||||
|
||||
try{
|
||||
f.getFuture().get(10, TimeUnit.SECONDS);
|
||||
}
|
||||
catch(CancellationException | InterruptedException | ExecutionException | TimeoutException e){
|
||||
// Nothing to be done here
|
||||
throw new WebApplicationException("Unable to terminate job");
|
||||
}
|
||||
|
||||
erequests.remove(trackingId);
|
||||
}
|
||||
|
||||
public boolean isActive(String trackingId) {
|
||||
logger.info("Checking whether trackingId "+trackingId+" is active.");
|
||||
if(!erequests.containsKey(trackingId)){
|
||||
throw new IllegalArgumentException("There is no request for tracking id "+trackingId);
|
||||
}
|
||||
|
||||
Future<?> f = erequests.get(trackingId).getFuture();
|
||||
return !f.isDone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for the termination of the scan request
|
||||
* @param trackingId Tracking ID
|
||||
* @throws ExecutionException -
|
||||
* @throws InterruptedException -
|
||||
*/
|
||||
public void wait(String trackingId) throws InterruptedException, ExecutionException{
|
||||
logger.info("Waiting for termination for trackingId "+trackingId);
|
||||
if(!erequests.containsKey(trackingId)){
|
||||
throw new IllegalArgumentException("There is no request for tracking id "+trackingId);
|
||||
}
|
||||
|
||||
Future<?> f = erequests.get(trackingId).getFuture();
|
||||
if(f==null){
|
||||
throw new IllegalArgumentException("There is no request for tracking id "+trackingId);
|
||||
}
|
||||
f.get();
|
||||
logger.info("TrackingId "+trackingId+" terminated");
|
||||
}
|
||||
}
|
||||
106
src/main/java/ch/psi/fda/rest/ExecutionJob.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2014 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but without any
|
||||
* warranty; without even the implied warranty of merchantability or fitness for
|
||||
* a particular purpose. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package ch.psi.fda.rest;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import ch.psi.fda.EContainer;
|
||||
import ch.psi.fda.EContainerFactory;
|
||||
import ch.psi.fda.edescriptor.EDescriptor;
|
||||
import ch.psi.jcae.ChannelService;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* "Wrapper" around the execution container. Depending on the edescriptor this class takes care of loading the
|
||||
* correct execution container. It also takes care of all common stuff described in the edescriptor like
|
||||
* streaming for plotting, etc.
|
||||
*/
|
||||
public class ExecutionJob implements Runnable {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ExecutionJob.class.getName());
|
||||
|
||||
private final ChannelService cService;
|
||||
private final ZMQDataService zmqService;
|
||||
|
||||
private final String trackingId;
|
||||
private final EDescriptor edescriptor;
|
||||
|
||||
private EventBus ebus;
|
||||
|
||||
private EContainer econtainer = null;
|
||||
|
||||
public ExecutionJob(ChannelService cService, ZMQDataService zmqService, String trackingId, EDescriptor edescriptor) {
|
||||
this.zmqService = zmqService;
|
||||
this.cService = cService;
|
||||
this.trackingId = trackingId;
|
||||
this.edescriptor = edescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
|
||||
try {
|
||||
|
||||
logger.info("Execute ----" + trackingId);
|
||||
|
||||
ebus = new EventBus();
|
||||
|
||||
// Configure ZMQ streaming service and attach it to event bus
|
||||
zmqService.setTrackingId(trackingId);
|
||||
// TODO e.g. set some filters on what is streamed
|
||||
// TODO stream a metadata message on what is streamed via the zmq service
|
||||
ebus.register(zmqService);
|
||||
|
||||
|
||||
Injector injector = Guice.createInjector(new InjectionModule(cService));
|
||||
|
||||
ServiceLoader<EContainerFactory> factories = ServiceLoader.load(EContainerFactory.class);
|
||||
for (EContainerFactory factory : factories) {
|
||||
if(factory.supportsEDescriptor(edescriptor)){
|
||||
injector.injectMembers(factory);
|
||||
econtainer = factory.getEContainer(edescriptor, ebus);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
econtainer.initialize();
|
||||
econtainer.execute();
|
||||
|
||||
logger.info("Done ----" + trackingId);
|
||||
|
||||
} finally {
|
||||
ebus.unregister(zmqService);
|
||||
if(econtainer!=null){
|
||||
econtainer.destroy();
|
||||
}
|
||||
econtainer=null;
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(){
|
||||
if(econtainer!=null){
|
||||
econtainer.abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
112
src/main/java/ch/psi/fda/rest/FdaServer.java
Normal file
@@ -0,0 +1,112 @@
|
||||
package ch.psi.fda.rest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.GnuParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
|
||||
import org.glassfish.jersey.jackson.JacksonFeature;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.grizzly.http.server.HttpServer;
|
||||
import org.glassfish.grizzly.http.server.StaticHttpHandler;
|
||||
|
||||
import ch.psi.fda.ui.ApplicationConfigurator;
|
||||
import sun.misc.Signal;
|
||||
import sun.misc.SignalHandler;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class FdaServer {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(FdaServer.class.getName());
|
||||
|
||||
public static void main(String[] args) throws IOException, ParseException {
|
||||
|
||||
int port = 8080;
|
||||
String hostname = InetAddress.getLocalHost().getHostName();
|
||||
|
||||
Options options = new Options();
|
||||
options.addOption("h", false, "Help");
|
||||
options.addOption("p", true, "Server port (default: "+port+")");
|
||||
options.addOption("s", true, "Server address (default: "+hostname+")");
|
||||
|
||||
GnuParser parser = new GnuParser();
|
||||
CommandLine line = parser.parse(options, args);
|
||||
|
||||
if (line.hasOption("p")) {
|
||||
port = Integer.parseInt(line.getOptionValue("p"));
|
||||
}
|
||||
if (line.hasOption("s")) {
|
||||
hostname = line.getOptionValue("s");
|
||||
}
|
||||
if (line.hasOption("h")) {
|
||||
HelpFormatter f = new HelpFormatter();
|
||||
f.printHelp("fda", options);
|
||||
return;
|
||||
}
|
||||
|
||||
// set the correct environment variable based on ch.psi.fda.home variable
|
||||
ApplicationConfigurator ac = new ApplicationConfigurator();
|
||||
ac.initializeApplication();
|
||||
|
||||
URI baseUri = UriBuilder.fromUri("http://" + hostname + "/").port(port).build();
|
||||
|
||||
ResourceBinder binder = new ResourceBinder();
|
||||
|
||||
ResourceConfig resourceConfig = new ResourceConfig();
|
||||
resourceConfig.packages(FdaServer.class.getPackage().getName()+".services"); // Services are located in services package
|
||||
resourceConfig.register(binder);
|
||||
|
||||
resourceConfig.register(JacksonFeature.class);
|
||||
|
||||
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(baseUri, resourceConfig);
|
||||
|
||||
// Static content
|
||||
String home = System.getenv("FDA_BASE");
|
||||
if (home == null) {
|
||||
home = "src/main/assembly";
|
||||
}
|
||||
home = home + "/www";
|
||||
server.getServerConfiguration().addHttpHandler(new StaticHttpHandler(home), "/static");
|
||||
logger.info(String.format("Management interface available at %sstatic/", baseUri));
|
||||
|
||||
|
||||
logger.info("Server started");
|
||||
logger.info("Use ctrl+c to stop ...");
|
||||
|
||||
// Signal handling
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Signal.handle(new Signal("INT"), new SignalHandler() {
|
||||
public void handle(Signal sig) {
|
||||
if(latch.getCount()==0){
|
||||
logger.info("Terminate broker by System.exit()");
|
||||
System.exit(1); // Terminate program after 2 ctrl+c
|
||||
}
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for termination, i.e. wait for ctrl+c
|
||||
try {
|
||||
latch.await();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
|
||||
server.shutdownNow();
|
||||
logger.info("Server terminated");
|
||||
|
||||
// Destroy global resources
|
||||
binder.destroy();
|
||||
|
||||
// Using System.exit() to ensure that JVM is going down
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
21
src/main/java/ch/psi/fda/rest/InjectionModule.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package ch.psi.fda.rest;
|
||||
|
||||
import ch.psi.jcae.ChannelService;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
|
||||
public class InjectionModule extends AbstractModule{
|
||||
|
||||
private ChannelService cservice;
|
||||
public InjectionModule(ChannelService cservice){
|
||||
this.cservice = cservice;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ChannelService.class).toInstance(cservice);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
21
src/main/java/ch/psi/fda/rest/JobEntry.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package ch.psi.fda.rest;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class JobEntry {
|
||||
|
||||
private final Future<?> future;
|
||||
private final ExecutionJob job;
|
||||
|
||||
public JobEntry(Future<?> future, ExecutionJob job){
|
||||
this.future=future;
|
||||
this.job=job;
|
||||
}
|
||||
|
||||
public Future<?> getFuture() {
|
||||
return future;
|
||||
}
|
||||
public ExecutionJob getJob() {
|
||||
return job;
|
||||
}
|
||||
}
|
||||
34
src/main/java/ch/psi/fda/rest/ResourceBinder.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package ch.psi.fda.rest;
|
||||
|
||||
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.glassfish.hk2.utilities.binding.AbstractBinder;
|
||||
|
||||
import ch.psi.jcae.ChannelService;
|
||||
import ch.psi.jcae.impl.DefaultChannelService;
|
||||
|
||||
public class ResourceBinder extends AbstractBinder {
|
||||
|
||||
private ChannelService channelService = new DefaultChannelService();
|
||||
private ZMQDataService zmqService = new ZMQDataService(10000);
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(channelService).to(ChannelService.class);
|
||||
bind(ExecutionEngine.class).to(ExecutionEngine.class).in(Singleton.class);
|
||||
bind(zmqService).to(ZMQDataService.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the allocated global resource.
|
||||
* Resources destroyed are:
|
||||
* - ChannelService
|
||||
* - ZMQDataService
|
||||
*/
|
||||
public void destroy(){
|
||||
channelService.destroy();
|
||||
zmqService.terminate();
|
||||
}
|
||||
}
|
||||
101
src/main/java/ch/psi/fda/rest/ZMQDataService.java
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2013 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but without any
|
||||
* warranty; without even the implied warranty of merchantability or fitness for
|
||||
* a particular purpose. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package ch.psi.fda.rest;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.zeromq.ZMQ;
|
||||
|
||||
import ch.psi.fda.messages.Message;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
/**
|
||||
* Service to stream out messages via ZMQ
|
||||
*/
|
||||
public class ZMQDataService {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ZMQDataService.class.getName());
|
||||
|
||||
private final int bufferSize = 5;
|
||||
private final int port;
|
||||
|
||||
private ZMQ.Context context;
|
||||
private ZMQ.Socket socket;
|
||||
|
||||
private String trackingId;
|
||||
|
||||
public ZMQDataService(int port){
|
||||
this.port = port;
|
||||
initialize();
|
||||
}
|
||||
|
||||
public void initialize(){
|
||||
context = ZMQ.context(1);
|
||||
// zmq.ZError.clear(); // Clear error code
|
||||
socket = context.socket(ZMQ.PUB);
|
||||
socket.setHWM(bufferSize);
|
||||
socket.bind("tcp://*:"+port);
|
||||
}
|
||||
|
||||
public void terminate(){
|
||||
socket.close();
|
||||
context.term();
|
||||
// zmq.ZError.clear(); // Clear error code
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMessage(Message m) {
|
||||
// logger.fine(m.toString());
|
||||
socket.sendMore("{\"htype\": [\"fda-2.1\"], \"trackingId\":\"" + trackingId + "\"}");
|
||||
try (
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
ObjectOutputStream o = new ObjectOutputStream(b);
|
||||
) {
|
||||
o.writeObject(m);
|
||||
socket.send(b.toByteArray());
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.WARNING, "Unable to serialize message", e);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Need to revive this
|
||||
// @Subscribe
|
||||
// public void onMessage(List<Visualization> vis){
|
||||
// logger.fine("Sending plotting filters");
|
||||
// socket.sendMore("{\"htype\": [\"fda-plot-2.1\"], \"trackingId\":\"" + trackingId + "\"}");
|
||||
// try (
|
||||
// ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
// ObjectOutputStream o = new ObjectOutputStream(b);
|
||||
// ) {
|
||||
// o.writeObject(vis);
|
||||
// socket.send(b.toByteArray());
|
||||
// } catch (IOException e) {
|
||||
// logger.log(Level.WARNING, "Unable to serialize message", e);
|
||||
// }
|
||||
// }
|
||||
|
||||
public void setTrackingId(String id){
|
||||
trackingId = id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package ch.psi.fda.rest.services;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.ws.rs.ext.ContextResolver;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
||||
import ch.psi.fda.DescriptorProvider;
|
||||
import ch.psi.fda.edescriptor.EDescriptor;
|
||||
|
||||
/**
|
||||
* JAXB Context Provider for the EDescriptor class
|
||||
* This class registers all implementations of the EDescriptor interfaces to the context
|
||||
*/
|
||||
@Provider
|
||||
public class EDescriptorJAXBContextProvider implements ContextResolver<JAXBContext> {
|
||||
private static final Logger logger = Logger.getLogger(EDescriptorJAXBContextProvider.class.getName());
|
||||
|
||||
List<Class<?>> classes = new ArrayList<>();
|
||||
|
||||
public EDescriptorJAXBContextProvider(){
|
||||
classes.add(EDescriptor.class);
|
||||
ServiceLoader<DescriptorProvider> providers = ServiceLoader.load(DescriptorProvider.class);
|
||||
for (DescriptorProvider provider : providers) {
|
||||
classes.add(provider.getEDescriptorClass());
|
||||
}
|
||||
}
|
||||
|
||||
private JAXBContext context = null;
|
||||
|
||||
public JAXBContext getContext(Class<?> type) {
|
||||
if(type != EDescriptor.class){
|
||||
return null; // No support for other classes than EDescriptor
|
||||
}
|
||||
|
||||
if(context == null) {
|
||||
try {
|
||||
context = JAXBContext.newInstance(classes.toArray(new Class[]{}));
|
||||
} catch (JAXBException e) {
|
||||
|
||||
logger.log(Level.WARNING, "Unable to create JAXB Context", e);
|
||||
}
|
||||
}
|
||||
return context;
|
||||
}
|
||||
}
|
||||
80
src/main/java/ch/psi/fda/rest/services/ExecutionService.java
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2013 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but without any
|
||||
* warranty; without even the implied warranty of merchantability or fitness for
|
||||
* a particular purpose. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.rest.services;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import ch.psi.fda.edescriptor.EDescriptor;
|
||||
import ch.psi.fda.rest.ExecutionEngine;
|
||||
|
||||
@Path("fda")
|
||||
public class ExecutionService {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ExecutionService.class.getName());
|
||||
|
||||
@Inject
|
||||
private ExecutionEngine aengine;
|
||||
|
||||
@PUT
|
||||
@Path("{trackingId}")
|
||||
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
|
||||
public void execute(@PathParam("trackingId") String trackingId, EDescriptor edescriptor) throws InterruptedException{
|
||||
logger.info("Submitting job with tracking id "+trackingId);
|
||||
aengine.submit(trackingId, edescriptor);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{trackingId}")
|
||||
public void stop(@PathParam("trackingId") String trackingId){
|
||||
logger.info("Stopping job with tracking id "+trackingId);
|
||||
aengine.terminate(trackingId);
|
||||
}
|
||||
|
||||
@DELETE
|
||||
public void terminateAll(){
|
||||
logger.info("Terminate all jobs");
|
||||
aengine.terminateAll();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{trackingId}/running")
|
||||
public boolean isActive(@PathParam("trackingId") String trackingId){
|
||||
logger.info("Check whether job with tracking id "+trackingId+" is running");
|
||||
return aengine.isActive(trackingId);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("{trackingId}/done")
|
||||
public void wait(@PathParam("trackingId") String trackingId) throws InterruptedException, ExecutionException{
|
||||
logger.info("Wait for job with tracking id "+trackingId+" to be finished");
|
||||
aengine.wait(trackingId);
|
||||
}
|
||||
|
||||
}
|
||||
163
src/main/java/ch/psi/fda/serializer/SerializerMAT.java
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.serializer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.jmatio.io.MatFileWriter;
|
||||
import com.jmatio.types.MLArray;
|
||||
import com.jmatio.types.MLDouble;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.messages.Message;
|
||||
import ch.psi.fda.messages.Metadata;
|
||||
|
||||
/**
|
||||
* Serialize data received by a DataQueue into a Matlab file
|
||||
*/
|
||||
public class SerializerMAT {
|
||||
|
||||
private File file;
|
||||
|
||||
private boolean appendSuffix = false;
|
||||
private boolean first = true;
|
||||
|
||||
/**
|
||||
* Construtor
|
||||
* @param file Name of the Matlab file to serialize the data to
|
||||
*/
|
||||
public SerializerMAT(File file){
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
File outfile;
|
||||
List<List<Object>> dlist;
|
||||
List<Class<?>> clist;
|
||||
|
||||
private List<Metadata> metadata;
|
||||
@Subscribe
|
||||
public void onMessage(Message message) {
|
||||
try {
|
||||
|
||||
|
||||
|
||||
if (message instanceof DataMessage) {
|
||||
DataMessage m = (DataMessage) message;
|
||||
|
||||
// Initialize list
|
||||
if (first) {
|
||||
first = false;
|
||||
|
||||
this.metadata = m.getMetadata();
|
||||
|
||||
// WORKAROUND BEGIN
|
||||
if (appendSuffix) {
|
||||
// Append a count suffix to the file. If there is already a
|
||||
// file with
|
||||
// this suffix increase the counter for the suffix
|
||||
int cnt = 0;
|
||||
String fname = this.file.getAbsolutePath(); // Determine
|
||||
// file name
|
||||
String extension = fname.replaceAll("^.*\\.", ""); // Determine
|
||||
// extension
|
||||
fname = fname.replaceAll("\\." + extension + "$", "");
|
||||
|
||||
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
|
||||
|
||||
while (outfile.exists()) {
|
||||
cnt++;
|
||||
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
|
||||
}
|
||||
} else {
|
||||
outfile = this.file;
|
||||
}
|
||||
// WORKAROUND END
|
||||
|
||||
// Transposed data list
|
||||
dlist = new ArrayList<List<Object>>();
|
||||
clist = new ArrayList<Class<?>>();
|
||||
|
||||
for (Object o : m.getData()) {
|
||||
dlist.add(new ArrayList<Object>());
|
||||
clist.add(o.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
// Put data into data list
|
||||
for (int i = 0; i < m.getData().size(); i++) {
|
||||
Object object = m.getData().get(i);
|
||||
dlist.get(i).add(object);
|
||||
}
|
||||
} else if (message instanceof EndOfStreamMessage) {
|
||||
|
||||
// Create Matlab vectors
|
||||
ArrayList<MLArray> matlablist = new ArrayList<MLArray>();
|
||||
for (int t = 0; t < dlist.size(); t++) {
|
||||
// Get component metadata
|
||||
Metadata c = metadata.get(t);
|
||||
c.getId();
|
||||
|
||||
List<Object> list = dlist.get(t);
|
||||
|
||||
if (clist.get(t).isArray()) {
|
||||
// Array Handling
|
||||
} else if (clist.get(t).equals(Double.class)) {
|
||||
// Data is of type Double
|
||||
MLDouble darray = new MLDouble(escapeString(c.getId()), (Double[]) list.toArray(new Double[list.size()]), 1);
|
||||
matlablist.add(darray);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Write Matlab file
|
||||
MatFileWriter writerr = new MatFileWriter();
|
||||
writerr.write(outfile, matlablist);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Data serializer had a problem writing to the specified file", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape string to be Matlab key conform
|
||||
* @param value
|
||||
* @return Escaped string value
|
||||
*/
|
||||
private String escapeString(String value){
|
||||
|
||||
String evalue = value.replaceAll("-", "_");
|
||||
evalue = evalue.replaceAll(":", "_");
|
||||
evalue = evalue.replaceAll("\\.", "_");
|
||||
evalue = evalue.replaceAll(" ", "_");
|
||||
evalue = evalue.replaceAll("\\(", "_");
|
||||
evalue = evalue.replaceAll("\\)", "_");
|
||||
evalue = evalue.replaceAll("\\[", "_");
|
||||
evalue = evalue.replaceAll("\\]", "_");
|
||||
|
||||
return(evalue);
|
||||
}
|
||||
|
||||
}
|
||||
246
src/main/java/ch/psi/fda/serializer/SerializerMAT2D.java
Normal file
@@ -0,0 +1,246 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.serializer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.jmatio.io.MatFileWriter;
|
||||
import com.jmatio.types.MLArray;
|
||||
import com.jmatio.types.MLDouble;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.messages.Message;
|
||||
import ch.psi.fda.messages.Metadata;
|
||||
import ch.psi.fda.messages.StreamDelimiterMessage;
|
||||
|
||||
/**
|
||||
* Serialize data received by a DataQueue into a Matlab file
|
||||
*/
|
||||
public class SerializerMAT2D {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(SerializerMAT2D.class.getName());
|
||||
|
||||
private File file;
|
||||
private boolean appendSuffix = false;
|
||||
|
||||
private boolean first = true;
|
||||
|
||||
private List<List<List<Object>>> dlist;
|
||||
private List<Class<?>> clist;
|
||||
private int dsize;
|
||||
private int dcount;
|
||||
private Integer mindsize;
|
||||
private File outfile;
|
||||
|
||||
private List<Metadata> metadata;
|
||||
|
||||
/**
|
||||
* @param file Name of the Matlab file to serialize the data to
|
||||
*/
|
||||
public SerializerMAT2D(File file){
|
||||
this.file = file;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMessage(Message message) {
|
||||
try{
|
||||
if(message instanceof DataMessage){
|
||||
DataMessage m = (DataMessage) message;
|
||||
|
||||
// Initialize list
|
||||
if(first){
|
||||
first=false;
|
||||
|
||||
this.metadata = m.getMetadata();
|
||||
|
||||
// Check if input queue does only hold 2D data
|
||||
int maxdim=0;
|
||||
for(Metadata me: metadata){
|
||||
if(me.getDimension()>maxdim){
|
||||
maxdim=me.getDimension();
|
||||
}
|
||||
|
||||
if(me.getDimension()>1){
|
||||
throw new RuntimeException("Serializer does only support 2D data (XD data found)");
|
||||
}
|
||||
}
|
||||
|
||||
if(maxdim<1){
|
||||
throw new RuntimeException("Serializer does only support 2D data ("+maxdim+"D data found)");
|
||||
}
|
||||
|
||||
|
||||
// WORKAROUND BEGIN
|
||||
if(appendSuffix){
|
||||
// Append a count suffix to the file. If there is already a file with
|
||||
// this suffix increase the counter for the suffix
|
||||
int cnt = 0;
|
||||
String fname = this.file.getAbsolutePath(); // Determine file name
|
||||
String extension = fname.replaceAll("^.*\\.", ""); // Determine extension
|
||||
fname = fname.replaceAll("\\."+extension+"$", "");
|
||||
|
||||
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
|
||||
|
||||
while(outfile.exists()){
|
||||
cnt++;
|
||||
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
|
||||
}
|
||||
}
|
||||
else{
|
||||
outfile = this.file;
|
||||
}
|
||||
// WORKAROUND END
|
||||
|
||||
|
||||
// Transposed data list
|
||||
dlist = new ArrayList<List<List<Object>>>();
|
||||
clist = new ArrayList<Class<?>>();
|
||||
dsize = 0; // Size of the dimension
|
||||
dcount = 0;
|
||||
mindsize = null;
|
||||
|
||||
for(Object o: m.getData()){
|
||||
// TODO Create list of lists (for each line one list - to
|
||||
// be able to fill up empty data points if there are some)
|
||||
List<List<Object>> l = new ArrayList<List<Object>>();
|
||||
l.add(new ArrayList<Object>());
|
||||
dlist.add(l);
|
||||
|
||||
clist.add(o.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
// Put data into data list
|
||||
for(int i=0;i< m.getData().size();i++){
|
||||
Object object = m.getData().get(i);
|
||||
List<List<Object>> lo = dlist.get(i);
|
||||
lo.get(lo.size()-1).add(object); // add data to latest list
|
||||
}
|
||||
|
||||
dcount++;
|
||||
}
|
||||
else if(message instanceof StreamDelimiterMessage){
|
||||
StreamDelimiterMessage m = (StreamDelimiterMessage) message;
|
||||
if(m.getNumber()==0){
|
||||
// Determine minimum dimension size
|
||||
if(dsize<dcount){
|
||||
dsize=dcount;
|
||||
}
|
||||
|
||||
// Determine maximum dimension size
|
||||
if(mindsize == null){
|
||||
mindsize=dcount;
|
||||
}
|
||||
if(mindsize>dcount){
|
||||
mindsize=dcount;
|
||||
}
|
||||
|
||||
// Add a new list for all component to the dlist
|
||||
for(List<List<Object>> lo:dlist){
|
||||
lo.add(new ArrayList<Object>());
|
||||
}
|
||||
|
||||
dcount=0;
|
||||
}
|
||||
}
|
||||
|
||||
else if(message instanceof EndOfStreamMessage){
|
||||
logger.info("dsize: "+dsize + " mindsize:"+mindsize);
|
||||
|
||||
// Create Matlab vectors
|
||||
ArrayList<MLArray> matlablist = new ArrayList<MLArray>();
|
||||
logger.info("dlist size: "+dlist.size());
|
||||
for(int t=0; t<dlist.size(); t++ ){
|
||||
|
||||
// Get component metadata
|
||||
Metadata c = metadata.get(t);
|
||||
|
||||
// Combine all lists to one big list (pad if there are data points missing)
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
List<List<Object>> ol = dlist.get(t);
|
||||
|
||||
// Remove last array list as it is empty
|
||||
ol.remove(ol.size()-1);
|
||||
|
||||
for(List<Object> li: ol){
|
||||
list.addAll(li);
|
||||
// Pad list if there are missing data points for some lines
|
||||
for(int i=li.size();i<dsize;i++){
|
||||
logger.info("Pad data point: "+i);
|
||||
list.add(Double.NaN);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// List<Object> list = dlist.get(t);
|
||||
logger.info("List: "+list.size());
|
||||
|
||||
|
||||
if(clist.get(t).isArray()){
|
||||
// Array Handling
|
||||
}
|
||||
else if(clist.get(t).equals(Double.class)){
|
||||
// Data is of type Double
|
||||
MLDouble darray = new MLDouble(escapeString(c.getId()),(Double[])list.toArray(new Double[list.size()]), dsize);
|
||||
matlablist.add(darray);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Write Matlab file
|
||||
MatFileWriter writerr = new MatFileWriter();
|
||||
writerr.write(outfile, matlablist);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Data serializer had a problem writing to the specified file",e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape string to be Matlab key conform
|
||||
* @param value
|
||||
* @return Escaped string value
|
||||
*/
|
||||
private String escapeString(String value){
|
||||
|
||||
String evalue = value.replaceAll("-", "_");
|
||||
evalue = evalue.replaceAll(":", "_");
|
||||
evalue = evalue.replaceAll("\\.", "_");
|
||||
evalue = evalue.replaceAll(" ", "_");
|
||||
evalue = evalue.replaceAll("\\(", "_");
|
||||
evalue = evalue.replaceAll("\\)", "_");
|
||||
evalue = evalue.replaceAll("\\[", "_");
|
||||
evalue = evalue.replaceAll("\\]", "_");
|
||||
|
||||
return(evalue);
|
||||
}
|
||||
|
||||
}
|
||||
241
src/main/java/ch/psi/fda/serializer/SerializerMAT2DZigZag.java
Normal file
@@ -0,0 +1,241 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.serializer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.jmatio.io.MatFileWriter;
|
||||
import com.jmatio.types.MLArray;
|
||||
import com.jmatio.types.MLDouble;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.messages.Message;
|
||||
import ch.psi.fda.messages.Metadata;
|
||||
import ch.psi.fda.messages.StreamDelimiterMessage;
|
||||
|
||||
/**
|
||||
* Serialize data received by a DataQueue into a Matlab file
|
||||
*/
|
||||
public class SerializerMAT2DZigZag {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(SerializerMAT2DZigZag.class.getName());
|
||||
|
||||
private List<Metadata> metadata;
|
||||
private File file;
|
||||
private boolean appendSuffix = false;
|
||||
private boolean first = true;
|
||||
|
||||
private File outfile;
|
||||
private List<List<Object>> dlist;
|
||||
private List<List<Object>> dlistTmp;
|
||||
private List<Class<?>> clist;
|
||||
private int dsize; // Size of the dimension
|
||||
private int dcount;
|
||||
|
||||
private int delimiterCount;
|
||||
|
||||
private boolean firstF;
|
||||
private boolean firstC;
|
||||
|
||||
/**
|
||||
* Construtor
|
||||
* @param file Name of the Matlab file to serialize the data to
|
||||
*/
|
||||
public SerializerMAT2DZigZag(File file){
|
||||
this.file = file;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMessage(Message message) {
|
||||
try{
|
||||
|
||||
|
||||
|
||||
|
||||
if(message instanceof DataMessage){
|
||||
DataMessage m = (DataMessage) message;
|
||||
|
||||
if(first){
|
||||
first=false;
|
||||
|
||||
this.metadata = m.getMetadata();
|
||||
|
||||
// Check if input queue does only hold 2D data
|
||||
int maxdim=0;
|
||||
for(Metadata me: metadata){
|
||||
if(me.getDimension()>maxdim){
|
||||
maxdim=me.getDimension();
|
||||
}
|
||||
|
||||
if(me.getDimension()>1){
|
||||
throw new RuntimeException("Serializer does only support 2D data (XD data found)");
|
||||
}
|
||||
}
|
||||
|
||||
if(maxdim<1){
|
||||
throw new RuntimeException("Serializer does only support 2D data ("+maxdim+"D data found)");
|
||||
}
|
||||
|
||||
// WORKAROUND BEGIN
|
||||
if(appendSuffix){
|
||||
// Append a count suffix to the file. If there is already a file with
|
||||
// this suffix increase the counter for the suffix
|
||||
int cnt = 0;
|
||||
String fname = this.file.getAbsolutePath(); // Determine file name
|
||||
String extension = fname.replaceAll("^.*\\.", ""); // Determine extension
|
||||
fname = fname.replaceAll("\\."+extension+"$", "");
|
||||
|
||||
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
|
||||
|
||||
while(outfile.exists()){
|
||||
cnt++;
|
||||
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
|
||||
}
|
||||
}
|
||||
else{
|
||||
outfile = this.file;
|
||||
}
|
||||
// WORKAROUND END
|
||||
|
||||
|
||||
// Transposed data list
|
||||
dlist = new ArrayList<List<Object>>();
|
||||
dlistTmp = new ArrayList<List<Object>>();
|
||||
clist = new ArrayList<Class<?>>();
|
||||
dsize = 0; // Size of the dimension
|
||||
dcount = 0;
|
||||
|
||||
delimiterCount = 0;
|
||||
|
||||
firstF = true;
|
||||
firstC = true;
|
||||
}
|
||||
|
||||
|
||||
if(firstC){
|
||||
for(Object o: m.getData()){
|
||||
dlist.add(new ArrayList<Object>());
|
||||
clist.add(o.getClass());
|
||||
firstC=false;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize list
|
||||
if(firstF){
|
||||
for(int i=0;i<m.getData().size();i++){
|
||||
dlistTmp.add(new ArrayList<Object>());
|
||||
}
|
||||
firstF=false;
|
||||
}
|
||||
|
||||
// Put data into data list
|
||||
for(int i=0;i< m.getData().size();i++){
|
||||
Object object = m.getData().get(i);
|
||||
dlistTmp.get(i).add(object);
|
||||
}
|
||||
|
||||
dcount++;
|
||||
}
|
||||
else if(message instanceof StreamDelimiterMessage){
|
||||
StreamDelimiterMessage m = (StreamDelimiterMessage) message;
|
||||
if(m.getNumber()==0){
|
||||
if(dsize<dcount){
|
||||
dsize=dcount;
|
||||
}
|
||||
dcount=0;
|
||||
|
||||
// Add temporary list to final list
|
||||
for(int i=0;i<dlist.size();i++){
|
||||
if(delimiterCount%2==1){
|
||||
Collections.reverse(dlistTmp.get(i));
|
||||
}
|
||||
dlist.get(i).addAll(dlistTmp.get(i));
|
||||
}
|
||||
|
||||
dlistTmp.clear();
|
||||
|
||||
firstF=true;
|
||||
delimiterCount++;
|
||||
}
|
||||
}
|
||||
|
||||
else if(message instanceof EndOfStreamMessage){
|
||||
// Create Matlab vectors
|
||||
ArrayList<MLArray> matlablist = new ArrayList<MLArray>();
|
||||
logger.info("dlist size: "+dlist.size());
|
||||
for(int t=0; t<dlist.size(); t++ ){
|
||||
// Get component metadata
|
||||
Metadata c = metadata.get(t);
|
||||
|
||||
List<Object> list = dlist.get(t);
|
||||
|
||||
if(clist.get(t).isArray()){
|
||||
// Array Handling
|
||||
}
|
||||
else if(clist.get(t).equals(Double.class)){
|
||||
// Data is of type Double
|
||||
MLDouble darray = new MLDouble(escapeString(c.getId()),(Double[])list.toArray(new Double[list.size()]), dsize);
|
||||
matlablist.add(darray);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Write Matlab file
|
||||
MatFileWriter writerr = new MatFileWriter();
|
||||
writerr.write(outfile, matlablist);
|
||||
}
|
||||
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Data serializer had a problem writing to the specified file",e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape string to be Matlab key conform
|
||||
* @param value
|
||||
* @return Escaped string value
|
||||
*/
|
||||
private String escapeString(String value){
|
||||
|
||||
String evalue = value.replaceAll("-", "_");
|
||||
evalue = evalue.replaceAll(":", "_");
|
||||
evalue = evalue.replaceAll("\\.", "_");
|
||||
evalue = evalue.replaceAll(" ", "_");
|
||||
evalue = evalue.replaceAll("\\(", "_");
|
||||
evalue = evalue.replaceAll("\\)", "_");
|
||||
evalue = evalue.replaceAll("\\[", "_");
|
||||
evalue = evalue.replaceAll("\\]", "_");
|
||||
|
||||
return(evalue);
|
||||
}
|
||||
|
||||
}
|
||||
375
src/main/java/ch/psi/fda/serializer/SerializerMDA.java
Normal file
@@ -0,0 +1,375 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.serializer;
|
||||
|
||||
import hep.io.xdr.XDRRandomAccessFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.messages.Message;
|
||||
import ch.psi.fda.messages.Metadata;
|
||||
import ch.psi.fda.messages.StreamDelimiterMessage;
|
||||
|
||||
/**
|
||||
* Serialize data received by a DataQueue
|
||||
*
|
||||
* http://www.aps.anl.gov/bcda/synApps/sscan/saveData_fileFormat.txt
|
||||
*/
|
||||
public class SerializerMDA {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(SerializerMDA.class.getName());
|
||||
|
||||
private File file;
|
||||
|
||||
private boolean first = true;
|
||||
|
||||
private List<Boolean> firstL;
|
||||
private List<Boolean> takeData;
|
||||
private List<Integer> dcountL;
|
||||
private List<List<List<List<Double>>>> dimensionList;
|
||||
private HashMap<Integer,List<Integer>> dMap;
|
||||
private HashMap<Integer,List<String>> idMap;
|
||||
private int numberOfDimensions;
|
||||
|
||||
public SerializerMDA(File file){
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMessage(Message message) {
|
||||
|
||||
|
||||
// Write data
|
||||
// Read Message
|
||||
if(message instanceof DataMessage){
|
||||
DataMessage m = (DataMessage) message;
|
||||
|
||||
|
||||
if(first){
|
||||
first = false;
|
||||
// Analyze header
|
||||
|
||||
// Map holding all indexes for a given dimension
|
||||
dMap = new HashMap<Integer, List<Integer>>();
|
||||
// Map holding all ids for a given dimension
|
||||
idMap = new HashMap<Integer, List<String>>();
|
||||
|
||||
int index=0;
|
||||
for(Metadata me: m.getMetadata()){
|
||||
if(!dMap.containsKey(me.getDimension())){
|
||||
dMap.put(me.getDimension(), new ArrayList<Integer>());
|
||||
}
|
||||
if(!idMap.containsKey(me.getDimension())){
|
||||
idMap.put(me.getDimension(), new ArrayList<String>());
|
||||
}
|
||||
dMap.get(me.getDimension()).add(index);
|
||||
idMap.get(me.getDimension()).add(me.getId());
|
||||
index++;
|
||||
}
|
||||
|
||||
//dimensions/dimension/dimensioncomponents/component/componentvalue
|
||||
dimensionList = new ArrayList<List<List<List<Double>>>>();
|
||||
|
||||
numberOfDimensions = dMap.size();
|
||||
logger.info("Number of dimensions: "+numberOfDimensions);
|
||||
for(int i=0;i<numberOfDimensions; i++){
|
||||
// For each dimension add an list
|
||||
dimensionList.add(new ArrayList<List<List<Double>>>());
|
||||
}
|
||||
|
||||
firstL = new ArrayList<Boolean>();
|
||||
takeData = new ArrayList<Boolean>(); // Flag whether to take data for this dimension
|
||||
dcountL = new ArrayList<Integer>(); // How many times this dimension is there
|
||||
|
||||
for(int i=0;i<numberOfDimensions;i++){
|
||||
firstL.add(true);
|
||||
takeData.add(true);
|
||||
dcountL.add(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for(Integer dimensionNumberKey : dMap.keySet()){
|
||||
if(firstL.get(dimensionNumberKey)){
|
||||
List<List<Double>> l = new ArrayList<List<Double>>();
|
||||
dimensionList.get(dimensionNumberKey).add(l);
|
||||
|
||||
for(int y=0;y<dMap.get(dimensionNumberKey).size(); y++){
|
||||
l.add(new ArrayList<Double>());
|
||||
}
|
||||
|
||||
// Set first flag to false
|
||||
firstL.set(dimensionNumberKey, false);
|
||||
|
||||
}
|
||||
|
||||
// Read data from data message
|
||||
if(takeData.get(dimensionNumberKey) || dimensionNumberKey == 0){
|
||||
for(int y=0;y<dMap.get(dimensionNumberKey).size(); y++){
|
||||
int ind = dMap.get(dimensionNumberKey).get(y);
|
||||
|
||||
// Get data of component at index
|
||||
Object value = m.getData().get(ind);
|
||||
if(value instanceof Double){
|
||||
dimensionList.get(dimensionNumberKey).get(dcountL.get(dimensionNumberKey)).get(y).add((Double)value);
|
||||
}
|
||||
}
|
||||
|
||||
takeData.set(dimensionNumberKey,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(message instanceof StreamDelimiterMessage){
|
||||
StreamDelimiterMessage m = (StreamDelimiterMessage) message;
|
||||
logger.fine("----Delimiter "+m.getNumber()+"----");
|
||||
|
||||
// Increase dimension count
|
||||
dcountL.set(m.getNumber(), (dcountL.get(m.getNumber())+1));
|
||||
|
||||
// Set flag that next message in the stream will be the first again of the dimension
|
||||
firstL.set(m.getNumber(), true);
|
||||
|
||||
// Every time a delimiter comes set take data of the dimension above to true
|
||||
int c = m.getNumber()+1;
|
||||
if(c<takeData.size()){
|
||||
takeData.set(c, true);
|
||||
}
|
||||
}
|
||||
|
||||
else if(message instanceof EndOfStreamMessage){
|
||||
// Write MDA file
|
||||
logger.info("Write MDA data file");
|
||||
|
||||
try {
|
||||
if(file.exists()){
|
||||
file.delete();
|
||||
}
|
||||
// XDROutputStream x = new XDROutputStream(new FileOutputStream(file));
|
||||
XDRRandomAccessFile x = new XDRRandomAccessFile(file, "rw");
|
||||
|
||||
|
||||
/**
|
||||
* Read file header
|
||||
*/
|
||||
x.writeFloat(0f); // Version
|
||||
x.writeInt(0); // Scan number
|
||||
x.writeInt(numberOfDimensions); // Rank/Number of dimensions
|
||||
|
||||
for(int i=numberOfDimensions-1;i>=0; i--){
|
||||
int s = dimensionList.get(i).get(0).get(0).size();
|
||||
x.writeInt(s); // Dimension size
|
||||
logger.info("Size: "+i+" - "+s+" ");
|
||||
}
|
||||
|
||||
x.writeInt(1); // Is Regular (true=1, false=0)
|
||||
x.writeInt(0); // Number of extra pvs
|
||||
|
||||
// Write data
|
||||
HashMap<Integer,Integer> indexCount = new HashMap<Integer,Integer>();
|
||||
for(int i=0;i<dimensionList.size();i++){
|
||||
indexCount.put(i, 0);
|
||||
}
|
||||
|
||||
// The highest dimension only consist of one data list
|
||||
int dnum = dimensionList.size()-1;
|
||||
writeDimension(x, dimensionList, indexCount, idMap, dnum);
|
||||
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long writeDimension(XDRRandomAccessFile x, List<List<List<List<Double>>>> dimensionList, HashMap<Integer,Integer> icount, HashMap<Integer,List<String>> idMap, int dnum) throws IOException{
|
||||
|
||||
int ic = icount.get(dnum);
|
||||
List<List<Double>> l = dimensionList.get(dnum).get(ic);
|
||||
// Increment count for dimension
|
||||
icount.put(dnum,(ic+1));
|
||||
|
||||
logger.info("Write data: "+dnum+"["+ic+"]");
|
||||
|
||||
// Write data to file
|
||||
// Address of this dimension (block)
|
||||
long daddress = x.getFilePointer();
|
||||
List<Long> dpaddressL = writeData(x, l, idMap.get(dnum), dnum);
|
||||
|
||||
|
||||
if(dnum>0){
|
||||
for(int i=0;i<l.get(0).size();i++){
|
||||
// long caddress = x.getFilePointer();
|
||||
|
||||
// Write lower level dimensions to file
|
||||
long p = writeDimension(x, dimensionList, icount, idMap, dnum-1);
|
||||
|
||||
// Write pointer to pdaddress+i*long
|
||||
x.seek(dpaddressL.get(i));
|
||||
x.writeInt((int)p);
|
||||
|
||||
// Got to caddress again
|
||||
// x.seek(caddress);
|
||||
x.seek(x.length());
|
||||
}
|
||||
}
|
||||
|
||||
return daddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data of a dimension
|
||||
* @param x
|
||||
* @param list
|
||||
* @param dimension
|
||||
* @throws IOException
|
||||
*
|
||||
* @return Address where the pointers lower level dimensions are stored
|
||||
*/
|
||||
private List<Long> writeData(XDRRandomAccessFile x, List<List<Double>> list, List<String> ids, int dimension) throws IOException{
|
||||
int npoints = list.get(0).size();
|
||||
|
||||
logger.info("Dimension rank: "+(dimension+1));
|
||||
x.writeInt(dimension+1); // Scan rank
|
||||
x.writeInt(npoints); // Number of points
|
||||
x.writeInt(npoints); // Current Point
|
||||
|
||||
// Address of the place where the pointers to the lower level dimensions
|
||||
// are stored.
|
||||
List<Long> dpaddressList = new ArrayList<Long>();
|
||||
// long dpaddress = x.getFilePointer();
|
||||
// Read pointers to lower scans
|
||||
if(dimension > 0){
|
||||
// For 1D scans this block is never reached
|
||||
for(int i=0;i<npoints;i++){
|
||||
dpaddressList.add(x.getFilePointer());
|
||||
x.writeInt(0); // pointer to lower scans (data is not correct)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read scan info
|
||||
*/
|
||||
String sname = "dimension: "+dimension;
|
||||
x.writeInt(sname.length()); // Length
|
||||
x.writeString(sname); // Scan name
|
||||
|
||||
|
||||
Date d = new Date();
|
||||
// String tstamp = "Oct 04, 2008 19:17:43.633180";
|
||||
String tstamp = d.toString(); // Take current time as timestamp
|
||||
x.writeInt(tstamp.length()); // Length
|
||||
x.writeString(tstamp); // timestamp
|
||||
|
||||
|
||||
int nPosDet = list.size();
|
||||
|
||||
int nPositioner = 1; // Assume that first in list is always the positioner
|
||||
int nDetector = nPosDet-1; // Assume that the rest are detectors
|
||||
x.writeInt(nPositioner); // Number of positioners
|
||||
x.writeInt(nDetector); // Number of detectors
|
||||
x.writeInt(0); // Number of triggers
|
||||
|
||||
int cnt = 0;
|
||||
|
||||
// Positioners metadata
|
||||
for(int i = 0; i<nPositioner; i++){
|
||||
String pos = ids.get(cnt);
|
||||
cnt++;
|
||||
|
||||
x.writeInt(i); // Positioner number
|
||||
|
||||
x.writeInt(pos.length());
|
||||
x.writeString(pos); // Positioner name
|
||||
|
||||
x.writeInt(0);
|
||||
// x.writeString(); // Description
|
||||
|
||||
x.writeInt(0);
|
||||
// x.writeString(); // Step mode
|
||||
|
||||
x.writeInt(0);
|
||||
// x.writeString("mm"); // Unit
|
||||
|
||||
x.writeInt(pos.length());
|
||||
x.writeString(pos); // Readback name
|
||||
|
||||
x.writeInt(0);
|
||||
// x.writeString(); // Readback description
|
||||
|
||||
x.writeInt(0);
|
||||
// x.writeString(); // Readback unit
|
||||
}
|
||||
|
||||
// Detector metadata
|
||||
for(int i=0; i<nDetector; i++){
|
||||
String det = ids.get(cnt);
|
||||
cnt++;
|
||||
|
||||
x.writeInt(i); // Detector number
|
||||
|
||||
x.writeInt(det.length());
|
||||
x.writeString(det); // Detector name
|
||||
|
||||
x.writeInt(0);
|
||||
// x.writeString(); // Description
|
||||
|
||||
x.writeInt(0);
|
||||
// x.writeString(); // Unit
|
||||
}
|
||||
|
||||
// No trigger metadata (as there are no triggers)
|
||||
|
||||
|
||||
// Positioner data
|
||||
for(int i = 0; i<nPositioner; i++){
|
||||
for(int t=0; t<npoints; t++){
|
||||
x.writeDouble(list.get(i).get(t));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Detector data
|
||||
for(int i=0; i<nDetector; i++){
|
||||
for(int t=0; t<npoints; t++){
|
||||
x.writeFloat(list.get(i+nPositioner).get(t).floatValue());
|
||||
}
|
||||
}
|
||||
|
||||
return dpaddressList;
|
||||
}
|
||||
|
||||
}
|
||||
200
src/main/java/ch/psi/fda/serializer/SerializerTXT2D.java
Normal file
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.serializer;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.messages.Message;
|
||||
import ch.psi.fda.messages.Metadata;
|
||||
import ch.psi.fda.messages.StreamDelimiterMessage;
|
||||
|
||||
/**
|
||||
* Serialize data received by a DataQueue into a Matlab file
|
||||
*/
|
||||
public class SerializerTXT2D {
|
||||
|
||||
private File file;
|
||||
private boolean appendSuffix = false;
|
||||
|
||||
private boolean first = true;
|
||||
|
||||
File outfile;
|
||||
List<List<Object>> dlist;
|
||||
List<Class<?>> clist;
|
||||
int dsize;
|
||||
int dcount;
|
||||
|
||||
private List<Metadata> metadata;
|
||||
|
||||
/**
|
||||
* @param file Name of the Matlab file to serialize the data to
|
||||
*/
|
||||
public SerializerTXT2D(File file){
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMessage(Message message) {
|
||||
try{
|
||||
|
||||
|
||||
|
||||
|
||||
if(message instanceof DataMessage){
|
||||
DataMessage m = (DataMessage) message;
|
||||
|
||||
|
||||
if(first){
|
||||
first = false;
|
||||
|
||||
// Check if input queue does only hold 2D data
|
||||
int maxdim=0;
|
||||
metadata = m.getMetadata();
|
||||
for(Metadata me: m.getMetadata()){
|
||||
if(me.getDimension()>maxdim){
|
||||
maxdim=me.getDimension();
|
||||
}
|
||||
|
||||
if(me.getDimension()>1){
|
||||
throw new RuntimeException("Serializer does only support 2D data (XD data found)");
|
||||
}
|
||||
}
|
||||
|
||||
if(maxdim<1){
|
||||
throw new RuntimeException("Serializer does only support 2D data ("+maxdim+"D data found)");
|
||||
}
|
||||
|
||||
|
||||
// WORKAROUND BEGIN
|
||||
|
||||
if(appendSuffix){
|
||||
// Append a count suffix to the file. If there is already a file with
|
||||
// this suffix increase the counter for the suffix
|
||||
int cnt = 0;
|
||||
String fname = this.file.getAbsolutePath(); // Determine file name
|
||||
String extension = fname.replaceAll("^.*\\.", ""); // Determine extension
|
||||
// fname = fname.replaceAll("(_[0-9]+)?\\."+extension+"$", "");
|
||||
fname = fname.replaceAll("\\."+extension+"$", "");
|
||||
|
||||
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
|
||||
|
||||
while(outfile.exists()){
|
||||
cnt++;
|
||||
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
|
||||
}
|
||||
}
|
||||
else{
|
||||
outfile = this.file;
|
||||
}
|
||||
// WORKAROUND END
|
||||
|
||||
|
||||
// Transposed data list
|
||||
dlist = new ArrayList<List<Object>>();
|
||||
clist = new ArrayList<Class<?>>();
|
||||
dsize = 0; // Size of the dimension
|
||||
dcount = 0;
|
||||
|
||||
|
||||
for(Object o: m.getData()){
|
||||
dlist.add(new ArrayList<Object>());
|
||||
clist.add(o.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
// Put data into data list
|
||||
for(int i=0;i< m.getData().size();i++){
|
||||
Object object = m.getData().get(i);
|
||||
dlist.get(i).add(object);
|
||||
}
|
||||
|
||||
dcount++;
|
||||
}
|
||||
else if(message instanceof StreamDelimiterMessage){
|
||||
StreamDelimiterMessage m = (StreamDelimiterMessage) message;
|
||||
if(m.getNumber()==0){
|
||||
if(dsize<dcount){
|
||||
dsize=dcount;
|
||||
}
|
||||
dcount=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else if(message instanceof EndOfStreamMessage){
|
||||
// Open file
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(outfile));
|
||||
|
||||
// Create text images
|
||||
for(int t=0; t<dlist.size(); t++ ){
|
||||
// Get component metadata
|
||||
Metadata c = metadata.get(t);
|
||||
|
||||
writer.write(c.getId()+"\n");
|
||||
|
||||
List<Object> list = dlist.get(t);
|
||||
|
||||
|
||||
|
||||
if(clist.get(t).isArray()){
|
||||
// Array Handling
|
||||
}
|
||||
else if(clist.get(t).equals(Double.class)){
|
||||
// Data is of type Double
|
||||
|
||||
StringBuffer b = new StringBuffer();
|
||||
int counter = 0;
|
||||
for(Object o: list){
|
||||
b.append(o);
|
||||
counter++;
|
||||
if(counter==dsize){
|
||||
b.append("\n");
|
||||
counter=0;
|
||||
}
|
||||
else{
|
||||
b.append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
writer.write(b.toString());
|
||||
}
|
||||
|
||||
writer.write("\n");
|
||||
|
||||
}
|
||||
|
||||
// Close file
|
||||
writer.close();
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Data serializer had a problem writing to the specified file",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
195
src/main/java/ch/psi/fda/serializer/SerializerTXTSplit.java
Normal file
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but without any
|
||||
* warranty; without even the implied warranty of merchantability or fitness for
|
||||
* a particular purpose. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.serializer;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.Message;
|
||||
import ch.psi.fda.messages.Metadata;
|
||||
import ch.psi.fda.messages.StreamDelimiterMessage;
|
||||
|
||||
/**
|
||||
* Serialize data received by a DataQueue
|
||||
*/
|
||||
public class SerializerTXTSplit {
|
||||
|
||||
private File file;
|
||||
|
||||
private int maxdim = 0;
|
||||
|
||||
private boolean first = true;
|
||||
|
||||
private List<String> header;
|
||||
private List<String> data;
|
||||
|
||||
public SerializerTXTSplit(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMessage(Message message) {
|
||||
try {
|
||||
// Write data
|
||||
// Read Message
|
||||
|
||||
if (message instanceof DataMessage) {
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
|
||||
header = new ArrayList<String>();
|
||||
data = new ArrayList<String>();
|
||||
|
||||
// Write header
|
||||
StringBuffer b = new StringBuffer();
|
||||
StringBuffer b1 = new StringBuffer();
|
||||
b.append("#");
|
||||
b1.append("#");
|
||||
for (Metadata c : ((DataMessage) message).getMetadata()) {
|
||||
|
||||
b.append(c.getId());
|
||||
b.append("\t");
|
||||
|
||||
b1.append(c.getDimension());
|
||||
b1.append("\t");
|
||||
|
||||
if (c.getDimension() > maxdim) {
|
||||
maxdim = c.getDimension();
|
||||
}
|
||||
}
|
||||
b.setCharAt(b.length() - 1, '\n');
|
||||
b1.setCharAt(b1.length() - 1, '\n');
|
||||
header.add(b.toString());
|
||||
header.add(b1.toString());
|
||||
|
||||
if (maxdim < 1) {
|
||||
throw new RuntimeException("Split serializer only supports data > 1 dimension");
|
||||
}
|
||||
}
|
||||
|
||||
// Write message to file - each message will result in one line
|
||||
DataMessage m = (DataMessage) message;
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (Object o : m.getData()) {
|
||||
if (o.getClass().isArray()) {
|
||||
// If the array object is of type double[] display its
|
||||
// content
|
||||
if (o instanceof double[]) {
|
||||
double[] oa = (double[]) o;
|
||||
for (double o1 : oa) {
|
||||
buffer.append(o1);
|
||||
buffer.append(" "); // Use space instead of tab
|
||||
}
|
||||
buffer.replace(buffer.length() - 1, buffer.length() - 1, "\t"); // Replace
|
||||
// last
|
||||
// space
|
||||
// with
|
||||
// tab
|
||||
} else if (o instanceof Object[]) {
|
||||
// TODO need to be recursive ...
|
||||
Object[] oa = (Object[]) o;
|
||||
for (Object o1 : oa) {
|
||||
buffer.append(o1);
|
||||
buffer.append(" "); // Use space instead of tab
|
||||
}
|
||||
buffer.replace(buffer.length() - 1, buffer.length() - 1, "\t"); // Replace
|
||||
// last
|
||||
// space
|
||||
// with
|
||||
// tab
|
||||
} else {
|
||||
buffer.append("-"); // Not supported
|
||||
}
|
||||
} else {
|
||||
buffer.append(o);
|
||||
buffer.append("\t");
|
||||
}
|
||||
}
|
||||
|
||||
buffer.deleteCharAt(buffer.length() - 1); // Remove last
|
||||
// character (i.e.
|
||||
// \t)
|
||||
buffer.append("\n"); // Append newline
|
||||
data.add(buffer.toString());
|
||||
} else if (message instanceof StreamDelimiterMessage) {
|
||||
StreamDelimiterMessage m = (StreamDelimiterMessage) message;
|
||||
if (m.getNumber() == maxdim - 1) {
|
||||
writeData(header, data);
|
||||
// Clear data
|
||||
data.clear();
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Data serializer had a problem writing to the specified file", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void writeData(List<String> header, List<String> data) throws IOException {
|
||||
|
||||
// WORKAROUND BEGIN
|
||||
File outfile;
|
||||
// if(appendSuffix){
|
||||
// Append a count suffix to the file. If there is already a file with
|
||||
// this suffix increase the counter for the suffix
|
||||
int cnt = 0;
|
||||
String fname = this.file.getAbsolutePath(); // Determine file name
|
||||
String extension = fname.replaceAll("^.*\\.", ""); // Determine
|
||||
// extension
|
||||
fname = fname.replaceAll("\\." + extension + "$", "");
|
||||
|
||||
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
|
||||
|
||||
while (outfile.exists()) {
|
||||
cnt++;
|
||||
outfile = new File(String.format("%s_%04d.%s", fname, cnt, extension));
|
||||
}
|
||||
// }
|
||||
// else{
|
||||
// outfile = this.file;
|
||||
// }
|
||||
// WORKAROUND END
|
||||
|
||||
// Open file
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(outfile));
|
||||
|
||||
// Write header
|
||||
for (String s : header) {
|
||||
writer.write(s);
|
||||
}
|
||||
|
||||
// Write data
|
||||
for (String s : data) {
|
||||
writer.write(s);
|
||||
}
|
||||
|
||||
// Close file
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
376
src/main/java/ch/psi/fda/ui/AcquisitionMain.java
Normal file
@@ -0,0 +1,376 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.ScrollPaneLayout;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.GnuParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Option;
|
||||
import org.apache.commons.cli.OptionBuilder;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
|
||||
import com.google.common.eventbus.AsyncEventBus;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
import sun.misc.Signal;
|
||||
import sun.misc.SignalHandler;
|
||||
import ch.psi.fda.DescriptorProvider;
|
||||
import ch.psi.fda.EContainer;
|
||||
import ch.psi.fda.EContainerFactory;
|
||||
import ch.psi.fda.edescriptor.EDescriptor;
|
||||
import ch.psi.fda.gui.ProgressPanel;
|
||||
import ch.psi.fda.gui.ScrollableFlowPanel;
|
||||
import ch.psi.fda.rest.InjectionModule;
|
||||
import ch.psi.fda.ui.visualizer.Visualizer;
|
||||
import ch.psi.fda.vdescriptor.VDescriptor;
|
||||
import ch.psi.jcae.ChannelService;
|
||||
import ch.psi.jcae.impl.DefaultChannelService;
|
||||
|
||||
/**
|
||||
* Entry class for command line based data acquisition
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class AcquisitionMain {
|
||||
|
||||
private static Logger logger = Logger.getLogger(AcquisitionMain.class.getName());
|
||||
|
||||
/**
|
||||
* Main Program
|
||||
* Process exit code: -1 if wrong number of arguments are passed
|
||||
*
|
||||
* @param args Arguments of the program
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
String scriptname = "fda_scan";
|
||||
|
||||
Integer iterations = null;
|
||||
boolean autoclose = false;
|
||||
boolean nogui = false;
|
||||
String files[] = null;
|
||||
|
||||
// Iterations option
|
||||
OptionBuilder.hasArg();
|
||||
OptionBuilder.withArgName("iterations");
|
||||
OptionBuilder.withDescription("Number of iterations");
|
||||
OptionBuilder.withType(new Integer(1));
|
||||
Option o_iterations = OptionBuilder.create( "iterations");
|
||||
|
||||
Option o_autoclose = new Option( "autoclose", "Close down application after scan" );
|
||||
Option o_init = new Option( "initialize", "Initialize application directories and configuration files" );
|
||||
Option o_nogui = new Option( "nogui", "Do not show scan GUI" );
|
||||
|
||||
Options options = new Options();
|
||||
options.addOption(o_iterations);
|
||||
options.addOption(o_autoclose);
|
||||
options.addOption(o_init);
|
||||
options.addOption(o_nogui);
|
||||
|
||||
CommandLineParser parser = new GnuParser();
|
||||
// Parse the command line arguments
|
||||
try {
|
||||
CommandLine line = parser.parse( options, args );
|
||||
|
||||
// Initialize application
|
||||
if( line.hasOption(o_init.getOpt()) ){
|
||||
// Initialize application
|
||||
ApplicationConfigurator ac = new ApplicationConfigurator();
|
||||
ac.initializeApplication();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
if(line.getArgs().length<1){
|
||||
throw new ParseException("One argument is required");
|
||||
}
|
||||
|
||||
files=line.getArgs();
|
||||
|
||||
// Iterations option
|
||||
if( line.hasOption(o_iterations.getOpt()) ){
|
||||
iterations = Integer.parseInt(line.getOptionValue(o_iterations.getOpt()));
|
||||
}
|
||||
|
||||
// Autoclose option
|
||||
if( line.hasOption( o_autoclose.getOpt() ) ) {
|
||||
autoclose = true;
|
||||
}
|
||||
|
||||
// No GUI option
|
||||
if( line.hasOption( o_nogui.getOpt() ) ) {
|
||||
nogui = true;
|
||||
}
|
||||
|
||||
} catch (ParseException e) {
|
||||
System.err.println(e.getMessage());
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.printUsage(new PrintWriter(System.out, true), HelpFormatter.DEFAULT_WIDTH, scriptname, options);
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
// Run application
|
||||
try{
|
||||
for(String file: files){
|
||||
run(new File(file), iterations, autoclose, nogui);
|
||||
}
|
||||
|
||||
// Close application automatically if autoclose option is set (and visualizations are specified)
|
||||
if(nogui || autoclose ){
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
catch(Exception ee){
|
||||
System.out.println("Acquisition failed due to: "+ee.getMessage());
|
||||
logger.log(Level.SEVERE, "Acquisition failed due to: ", ee); // Do not print stack trace
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Run scan
|
||||
* @param file Scan file
|
||||
* @param iterations Number of iterations
|
||||
* @param autoclose Flag whether to close the application automatically after the scan
|
||||
* @param nogui Flag whether to run the scan with a GUI
|
||||
*/
|
||||
public static void run(final File file, Integer iterations, boolean autoclose, boolean nogui){
|
||||
|
||||
// Initialize application
|
||||
new ApplicationConfigurator().initializeApplication();
|
||||
|
||||
// Basic services
|
||||
final ChannelService cservice = new DefaultChannelService();
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
EventBus b = new AsyncEventBus(executor);
|
||||
Injector injector = Guice.createInjector(new InjectionModule(cservice));
|
||||
|
||||
|
||||
EDescriptor edescriptor = null;
|
||||
VDescriptor vdescriptor = null;
|
||||
ServiceLoader<DescriptorProvider> providers = ServiceLoader.load(DescriptorProvider.class);
|
||||
for (DescriptorProvider provider : providers) {
|
||||
try{
|
||||
provider.load(file);
|
||||
edescriptor = provider.getEDescriptor();
|
||||
vdescriptor = provider.getVDescriptor();
|
||||
break;
|
||||
}
|
||||
catch(Exception e){
|
||||
logger.log(Level.INFO, provider.getClass().getName()+ " is not able to read provided descriptor files", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EContainer ec = null;
|
||||
ServiceLoader<EContainerFactory> factories = ServiceLoader.load(EContainerFactory.class);
|
||||
for (EContainerFactory factory : factories) {
|
||||
if(factory.supportsEDescriptor(edescriptor)){
|
||||
injector.injectMembers(factory);
|
||||
ec = factory.getEContainer(edescriptor, b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
final EContainer econtainer = ec;
|
||||
|
||||
|
||||
econtainer.initialize();
|
||||
|
||||
Visualizer visualizer = null;
|
||||
|
||||
|
||||
// Only register data visualization task/processor if there are visualizations
|
||||
if(vdescriptor.getPlots().size()>0 && !nogui){
|
||||
visualizer = new Visualizer(vdescriptor);
|
||||
b.register(visualizer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// GUI GUI GUI GUI GUI GUI GUI
|
||||
ProgressPanel progressPanel = null;
|
||||
if(visualizer != null){ // Only bring up GUI if there are some plots ...
|
||||
// Visualizations
|
||||
JPanel opanel = new ScrollableFlowPanel();
|
||||
opanel.setLayout(new FlowLayout());
|
||||
|
||||
JScrollPane spane = new JScrollPane(opanel, ScrollPaneLayout.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneLayout.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
JTabbedPane tpane = new JTabbedPane();
|
||||
tpane.addTab("Overview", spane);
|
||||
|
||||
for(JPanel p: visualizer.getPlotPanels()){
|
||||
opanel.add(p);
|
||||
}
|
||||
|
||||
final JFrame frame = new JFrame("FDA: "+file.getName());
|
||||
frame.setSize(1200,800);
|
||||
|
||||
// Create progress panel
|
||||
progressPanel = new ProgressPanel();
|
||||
progressPanel.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
econtainer.abort();
|
||||
} catch (Exception e1) {
|
||||
logger.log(Level.SEVERE, "Exception occured while aborting scan", e1);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
JSplitPane splitPane = new JSplitPane();
|
||||
splitPane.setLeftComponent(progressPanel);
|
||||
splitPane.setRightComponent(tpane);
|
||||
|
||||
frame.add(splitPane);
|
||||
frame.addWindowListener(new WindowAdapter(){
|
||||
@Override
|
||||
public void windowClosing(WindowEvent we){
|
||||
if(econtainer.isActive()){
|
||||
// Abort acquisition
|
||||
econtainer.abort();
|
||||
}
|
||||
|
||||
// Wait until acquisition is aborted. Maximum wait 10*100milliseconds before forcefully
|
||||
// terminate application
|
||||
int count=0;
|
||||
while(econtainer.isActive()){
|
||||
if(count == 10){
|
||||
break;
|
||||
}
|
||||
|
||||
// Sleep 100 milliseconds
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
// Terminate program
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//.DO_NOTHING_ON_CLOSE);
|
||||
// frame.setVisible(true);
|
||||
|
||||
java.awt.EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
frame.setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
// GUI GUI GUI GUI GUI GUI GUI
|
||||
|
||||
// CLI CLI CLI CLI
|
||||
// Register the scan engine as Signal Handler
|
||||
Signal.handle(new Signal("INT"), new SignalHandler() {
|
||||
/**
|
||||
* Thread save signal counter
|
||||
*/
|
||||
private AtomicInteger signalCount= new AtomicInteger(0);
|
||||
|
||||
/**
|
||||
* Testing signal handler (in Eclipse) use this after starting scan:
|
||||
*
|
||||
* SL5: A=`ps -ef | tail -10 | grep jav[a] | awk '{printf $2}'`;kill -2 $A
|
||||
* MacOS X: A=`ps -ef | grep AcquisitionMai[n] | awk '{printf $2}'`;kill -2 $A
|
||||
*
|
||||
* on the command line use CTRL-C
|
||||
*/
|
||||
@Override
|
||||
public void handle(Signal signal) {
|
||||
|
||||
logger.finest("Received signal: "+signal);
|
||||
|
||||
int count = signalCount.incrementAndGet();
|
||||
|
||||
// If signal is received more than 1 time forcefully abort application
|
||||
if(count>1){
|
||||
logger.info("Terminate application");
|
||||
System.exit(2);
|
||||
}
|
||||
|
||||
// Abort acquisition engine
|
||||
if(econtainer.isActive()){
|
||||
// Abort acquisition
|
||||
econtainer.abort();
|
||||
}
|
||||
}
|
||||
});
|
||||
// CLI CLI CLI CLI
|
||||
|
||||
|
||||
// Run acquisition engine
|
||||
// try {
|
||||
if(visualizer != null){
|
||||
// Start visualization
|
||||
visualizer.configure();
|
||||
}
|
||||
|
||||
econtainer.execute();
|
||||
econtainer.destroy();
|
||||
|
||||
cservice.destroy();
|
||||
executor.shutdownNow();
|
||||
|
||||
// GUI GUI GUI GUI GUI GUI GUI
|
||||
// Set progress panel to done
|
||||
if(progressPanel != null){
|
||||
// Can this be done via a Listener?
|
||||
progressPanel.done();
|
||||
}
|
||||
// GUI GUI GUI GUI GUI GUI GUI
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
324
src/main/java/ch/psi/fda/ui/ApplicationConfigurator.java
Normal file
@@ -0,0 +1,324 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InterfaceAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class ApplicationConfigurator {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ApplicationConfigurator.class.getName());
|
||||
|
||||
public final static String FDA_HOME_ARGUMENT = "ch.psi.fda.home";
|
||||
|
||||
private final File home;
|
||||
private final File configdir;
|
||||
private final File datadir;
|
||||
private final File logdir;
|
||||
private final File scandir;
|
||||
|
||||
private final File jcaeProperties;
|
||||
private final File fdaProperties;
|
||||
private final File loggingProperties;
|
||||
|
||||
/**
|
||||
* Constructor: The constructor will determine the home directory based on the
|
||||
* System property fda.home passed via the VM option -Dfda.home=dir or, if not present,
|
||||
* via the source code (jar) location (this will fail if the source code is not loaded from a file source).
|
||||
*/
|
||||
public ApplicationConfigurator(){
|
||||
this.home = determineHome();
|
||||
this.configdir = new File(home, "config");
|
||||
this.datadir = new File(home, "data");
|
||||
this.logdir = new File(home, "logs");
|
||||
this.scandir = new File(home, "scans");
|
||||
|
||||
this.jcaeProperties = new File(configdir, "jcae.properties");
|
||||
this.fdaProperties = new File(configdir, "fda.properties");
|
||||
this.loggingProperties = new File(configdir, "logging.properties");
|
||||
}
|
||||
|
||||
|
||||
public void initializeApplication(){
|
||||
|
||||
// Overwrite system property
|
||||
System.setProperty(FDA_HOME_ARGUMENT, this.home.getAbsolutePath());
|
||||
|
||||
createApplicationHome();
|
||||
createDefaultConfigurationFiles();
|
||||
|
||||
// Set FDA configuration argument -Dch.psi.fda.config.file=...
|
||||
|
||||
final String configFile = "ch.psi.fda.xscan.config.file";
|
||||
String property = System.getProperty(configFile);
|
||||
if(property==null){
|
||||
System.setProperty(configFile, fdaProperties.getAbsolutePath());
|
||||
}
|
||||
|
||||
// Set jcae.properties file
|
||||
property = System.getProperty("ch.psi.jcae.config.file");
|
||||
if(property==null){
|
||||
System.setProperty("ch.psi.jcae.config.file", jcaeProperties.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to determine home directory. This function assumes that the application directories are
|
||||
* ordered as follows:
|
||||
* HOME
|
||||
* |-version
|
||||
* | |-lib
|
||||
* | | |-jars
|
||||
* | |-bin
|
||||
* |-config
|
||||
* |-logs
|
||||
* |-data
|
||||
* |-scans
|
||||
* | |-templates
|
||||
* | |-users
|
||||
* @return file
|
||||
*/
|
||||
public File determineHome(){
|
||||
File home = null;
|
||||
|
||||
// Check whether fda.home System property is set
|
||||
String s = System.getProperty(FDA_HOME_ARGUMENT);
|
||||
if(s!=null){
|
||||
// A system property is specified
|
||||
home = new File(s);
|
||||
}
|
||||
else{
|
||||
// No system property is specified
|
||||
|
||||
// Try to determine home location based on the location of the sourcecode
|
||||
try {
|
||||
// Note: Obviously, this will do odd things if you class was loaded from a non-file location.
|
||||
// http://stackoverflow.com/questions/320542/how-to-get-the-path-of-a-running-jar-file
|
||||
// Get path where the jar is located
|
||||
File f = new File(ApplicationConfigurator.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
|
||||
|
||||
// Check whether class was loaded from a jar file
|
||||
if(f.isDirectory()){
|
||||
// Loaded from a directory
|
||||
home = f.getParentFile().getParentFile();
|
||||
}
|
||||
else{
|
||||
// Jar file
|
||||
// Assume that the jar file is located in a <version>/lib directory
|
||||
home = f.getParentFile().getParentFile().getParentFile();
|
||||
}
|
||||
} catch (URISyntaxException e) {;
|
||||
}
|
||||
}
|
||||
return(home);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize fda home directory
|
||||
* Will create the home directory directory structure
|
||||
*/
|
||||
public void createApplicationHome(){
|
||||
|
||||
// Create directories
|
||||
if(!home.exists()){
|
||||
logger.info("Create home directory: "+home.getAbsolutePath());
|
||||
home.mkdirs();
|
||||
}
|
||||
|
||||
// Configuration directory
|
||||
if(!configdir.exists()){
|
||||
logger.info("Create configuration directory: "+configdir.getAbsolutePath());
|
||||
configdir.mkdir();
|
||||
}
|
||||
|
||||
// Data directory
|
||||
if(!datadir.exists()){
|
||||
logger.info("Create data directory: "+datadir.getAbsolutePath());
|
||||
datadir.mkdir();
|
||||
}
|
||||
|
||||
// Log directory
|
||||
if(!logdir.exists()){
|
||||
logger.info("Create log directory: "+logdir.getAbsolutePath());
|
||||
logdir.mkdir();
|
||||
}
|
||||
|
||||
// Scan directories
|
||||
if(!scandir.exists()){
|
||||
logger.info("Create scan directory: "+scandir.getAbsolutePath());
|
||||
scandir.mkdir();
|
||||
}
|
||||
File sdir = new File(scandir, "templates");
|
||||
if(!sdir.exists()){
|
||||
logger.info("Create template scan directory: "+sdir.getAbsolutePath());
|
||||
sdir.mkdir();
|
||||
}
|
||||
sdir = new File(scandir, "users");
|
||||
if(!sdir.exists()){
|
||||
logger.info("Create user scan directory: "+sdir.getAbsolutePath());
|
||||
sdir.mkdir();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create required configuration files
|
||||
*/
|
||||
public void createDefaultConfigurationFiles() {
|
||||
try{
|
||||
|
||||
if(!jcaeProperties.exists()){
|
||||
logger.info("Create jcae.properties file: "+jcaeProperties.getAbsolutePath());
|
||||
// jca.properties
|
||||
String addresses = getLocalBroadcastAddresses();
|
||||
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(jcaeProperties));
|
||||
PrintWriter w = new PrintWriter(writer);
|
||||
// Set address list
|
||||
w.println("ch.psi.jcae.ContextFactory.addressList="+addresses);
|
||||
// Timeout for creating channels
|
||||
w.println("ch.psi.jcae.ChannelFactory.timeout=2000");
|
||||
w.println("ch.psi.jcae.ChannelFactory.retries=4");
|
||||
// Get/set timeout of a ChannelBean
|
||||
w.println("ch.psi.jcae.ChannelBeanFactory.timeout=10000");
|
||||
// Set default wait time for wait operations of a ChannelBean (30 minutes)
|
||||
w.println("ch.psi.jcae.ChannelBeanFactory.waitTimeout=1800000");
|
||||
// Set wait retry period for wait operations of a ChannelBean (1 minutes)
|
||||
w.println("ch.psi.jcae.ChannelBeanFactory.waitRetryPeriod=60000");
|
||||
// Set retries for operations on a ChannelBean
|
||||
w.println("ch.psi.jcae.ChannelBeanFactory.retries=4");
|
||||
writer.close();
|
||||
}
|
||||
|
||||
if(!fdaProperties.exists()){
|
||||
logger.info("Create fda.properties file: "+fdaProperties.getAbsolutePath());
|
||||
// fda.properties
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(fdaProperties));
|
||||
PrintWriter w = new PrintWriter(writer);
|
||||
|
||||
w.println("ch.psi.fda.aq.data.dir=../data");
|
||||
w.println("ch.psi.fda.aq.data.filePrefix=${yyyy_MM}/${yyyyMMdd}/${yyyyMMddHHmmss}_${name}/${yyyyMMddHHmm}_");
|
||||
|
||||
w.println();
|
||||
w.println("# Global Error Notification (uncomment if needed)");
|
||||
w.println("#ch.psi.fda.aq.notification.recipients=mail.address@psi.ch smsnumber");
|
||||
|
||||
w.println();
|
||||
w.println("# OTFSCAN Configuration (uncomment if needed)");
|
||||
w.println("#ch.psi.fda.aq.otf.channelPrefix=X-X-OTFX");
|
||||
w.println("#ch.psi.fda.aq.otf.nfsServer=beamlineFileServer.psi.ch");
|
||||
w.println("#ch.psi.fda.aq.otf.nfsShare=/usr/local/nfsshare");
|
||||
w.println("#ch.psi.fda.aq.otf.smbShare=smb://:@beamlineFileServer.psi.ch/otftemp/");
|
||||
|
||||
writer.close();
|
||||
}
|
||||
|
||||
if(!loggingProperties.exists()){
|
||||
logger.info("Create logging.properties file: "+loggingProperties.getAbsolutePath());
|
||||
// logging.properties
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(loggingProperties));
|
||||
PrintWriter w = new PrintWriter(writer);
|
||||
|
||||
w.println("# Specify the handlers to create in the root logger");
|
||||
w.println("handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler");
|
||||
w.println("");
|
||||
w.println("# Set the default logging level for the root logger");
|
||||
w.println(".level=INFO");
|
||||
w.println("");
|
||||
w.println("# Set the default logging level for new ConsoleHandler instances");
|
||||
w.println("java.util.logging.ConsoleHandler.level=ALL");
|
||||
w.println("");
|
||||
w.println("# Set the default formatter for new ConsoleHandler instances");
|
||||
w.println("java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter");
|
||||
w.println("");
|
||||
w.println("# Set the default logging level for new FileHandler instances");
|
||||
w.println("java.util.logging.FileHandler.level=ALL");
|
||||
w.println("");
|
||||
w.println("# Set the default formatter for new ConsoleHandler instances");
|
||||
w.println("java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter");
|
||||
w.println("");
|
||||
w.println("# Naming of the output file:");
|
||||
w.println("java.util.logging.FileHandler.pattern="+logdir.getAbsolutePath()+"/fda-%u.%g.log");
|
||||
w.println("");
|
||||
w.println("# Limiting size of output file in bytes (10000kb):");
|
||||
w.println("java.util.logging.FileHandler.limit=10000000");
|
||||
w.println("");
|
||||
w.println("# Number of output files to cycle through, by appending an");
|
||||
w.println("# integer to the base file name:");
|
||||
w.println("java.util.logging.FileHandler.count=10");
|
||||
w.println("");
|
||||
w.println("# Set the default logging level for the logger named com.mycompany");
|
||||
w.println("ch.psi.fda.level=ALL");
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
catch(IOException e){
|
||||
throw new RuntimeException("Cannot create default configuration files",e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine local broadcast addresses of the available network interfaces
|
||||
* @return
|
||||
*/
|
||||
private String getLocalBroadcastAddresses(){
|
||||
StringBuffer bAddressList = new StringBuffer();
|
||||
|
||||
// Loop host interfaces
|
||||
Enumeration<NetworkInterface> networkInterfaces;
|
||||
try {
|
||||
networkInterfaces = NetworkInterface.getNetworkInterfaces();
|
||||
} catch (SocketException e) {
|
||||
// Something went wrong while determining the network interfaces of the current machine.
|
||||
// As there is nothing a user can do, turn this exception into a unchecked RuntimeException.
|
||||
throw new RuntimeException("Unable to determine network interfaces of the machine", e);
|
||||
}
|
||||
while (networkInterfaces.hasMoreElements()) {
|
||||
NetworkInterface networkInterface = networkInterfaces.nextElement();
|
||||
|
||||
// Loop IP addresses of interface
|
||||
List<InterfaceAddress> interfaceAddresses = networkInterface.getInterfaceAddresses();
|
||||
|
||||
for(InterfaceAddress interfaceAddress: interfaceAddresses){
|
||||
InetAddress broadcastAddress = interfaceAddress.getBroadcast();
|
||||
if (broadcastAddress != null) {
|
||||
if(bAddressList.length()>0){
|
||||
bAddressList.append(" ");
|
||||
}
|
||||
// Use of .substring(1) to remove leading "/" character
|
||||
bAddressList.append(broadcastAddress.toString().substring(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
return(bAddressList.toString());
|
||||
}
|
||||
}
|
||||
237
src/main/java/ch/psi/fda/ui/ConversionMain.java
Normal file
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.GnuParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Option;
|
||||
import org.apache.commons.cli.OptionBuilder;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import ch.psi.fda.deserializer.DataDeserializer;
|
||||
import ch.psi.fda.deserializer.DataDeserializerMDA;
|
||||
import ch.psi.fda.deserializer.DataDeserializerTXT;
|
||||
import ch.psi.fda.serializer.SerializerMAT;
|
||||
import ch.psi.fda.serializer.SerializerMAT2D;
|
||||
import ch.psi.fda.serializer.SerializerMAT2DZigZag;
|
||||
import ch.psi.fda.serializer.SerializerMDA;
|
||||
import ch.psi.fda.serializer.SerializerTXT;
|
||||
import ch.psi.fda.serializer.SerializerTXT2D;
|
||||
import ch.psi.fda.serializer.SerializerTXTSplit;
|
||||
|
||||
/**
|
||||
* Converter to convert the format of datafiles
|
||||
*/
|
||||
public class ConversionMain {
|
||||
|
||||
private static Logger logger = Logger.getLogger(ConversionMain.class.getName());
|
||||
|
||||
public enum Writer {TXT, TXT_2D, TXT_SPLIT, MAT, MAT_2D, MDA, MAT_2D_Z};
|
||||
public enum Reader {TXT, MDA};
|
||||
|
||||
|
||||
public void convert(File input, File output, Reader reader, Writer writer) throws InterruptedException{
|
||||
|
||||
// Check existence input file
|
||||
if(input==null){
|
||||
throw new IllegalArgumentException("Input file not specified (is null)");
|
||||
}
|
||||
else if(!input.exists()){
|
||||
throw new IllegalArgumentException("Input file ["+input.getAbsolutePath()+"] does not exist");
|
||||
}
|
||||
|
||||
// Check existence output file
|
||||
if(output==null){
|
||||
throw new IllegalArgumentException("Output file not specified (is null)");
|
||||
}
|
||||
else if(output.exists()){
|
||||
throw new IllegalArgumentException("Output file ["+output.getAbsolutePath()+"] already exists");
|
||||
}
|
||||
|
||||
|
||||
EventBus bus = new EventBus();
|
||||
|
||||
// Create deserializer
|
||||
DataDeserializer deserializer;
|
||||
if(reader.equals(Reader.TXT)){
|
||||
deserializer = new DataDeserializerTXT(bus, input);
|
||||
}
|
||||
else if(reader.equals(Reader.MDA)){
|
||||
deserializer = new DataDeserializerMDA(bus, input);
|
||||
}
|
||||
else{
|
||||
throw new IllegalArgumentException("Reader of type "+reader+" not supported.");
|
||||
}
|
||||
|
||||
if(writer.equals(Writer.MAT)){
|
||||
bus.register(new SerializerMAT(output));
|
||||
}
|
||||
else if(writer.equals(Writer.MAT_2D)){
|
||||
bus.register(new SerializerMAT2D(output));
|
||||
}
|
||||
else if(writer.equals(Writer.TXT)){
|
||||
bus.register(new SerializerTXT(output, false));
|
||||
}
|
||||
else if(writer.equals(Writer.TXT_2D)){
|
||||
bus.register(new SerializerTXT2D(output));
|
||||
}
|
||||
else if(writer.equals(Writer.TXT_SPLIT)){
|
||||
bus.register(new SerializerTXTSplit(output));
|
||||
}
|
||||
else if(writer.equals(Writer.MDA)){
|
||||
bus.register(new SerializerMDA(output));
|
||||
}
|
||||
else if(writer.equals(Writer.MAT_2D_Z)){
|
||||
bus.register(new SerializerMAT2DZigZag(output));
|
||||
}
|
||||
else{
|
||||
throw new IllegalArgumentException("Writer of type "+writer+" not supported.");
|
||||
}
|
||||
|
||||
// Start conversion
|
||||
deserializer.read();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method accepts a data file and an option (-file) specifying the scan configuration file
|
||||
* used for creating the data file. If no option is specified the configuration file is derived by the
|
||||
* data file name.
|
||||
*
|
||||
* @param args Command line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
String scriptname = "fda_convert";
|
||||
|
||||
File outfile = null;
|
||||
File infile = null;
|
||||
Reader reader = Reader.TXT;
|
||||
Writer writer = Writer.TXT;
|
||||
|
||||
|
||||
OptionBuilder.hasArg();
|
||||
OptionBuilder.withArgName("writer");
|
||||
OptionBuilder.withDescription("Output format");
|
||||
OptionBuilder.withType(new String());
|
||||
Option o_writer = OptionBuilder.create( "writer");
|
||||
|
||||
OptionBuilder.hasArg();
|
||||
OptionBuilder.withArgName("reader");
|
||||
OptionBuilder.withDescription("Input format");
|
||||
OptionBuilder.withType(new String());
|
||||
Option o_reader = OptionBuilder.create( "reader");
|
||||
|
||||
Options options = new Options();
|
||||
options.addOption(o_writer);
|
||||
options.addOption(o_reader);
|
||||
|
||||
CommandLineParser parser = new GnuParser();
|
||||
// Parse the command line arguments
|
||||
try {
|
||||
CommandLine line = parser.parse( options, args );
|
||||
|
||||
// Check whether exactly one file is specified
|
||||
if(line.getArgs().length != 2){
|
||||
throw new ParseException("Two arguments required");
|
||||
}
|
||||
|
||||
infile = new File(line.getArgs()[0]);
|
||||
outfile= new File(line.getArgs()[1]);
|
||||
|
||||
if( line.hasOption(o_reader.getOpt() )){
|
||||
String wr = line.getOptionValue(o_reader.getOpt());
|
||||
try{
|
||||
Reader r = Reader.valueOf(wr.toUpperCase());
|
||||
reader = r;
|
||||
}
|
||||
catch(IllegalArgumentException e){
|
||||
throw new ParseException("Data type "+ wr + " not supported");
|
||||
}
|
||||
}
|
||||
else{
|
||||
String suffix = infile.getName().replaceAll("^.*\\.", "");
|
||||
try{
|
||||
Reader r = Reader.valueOf(suffix.toUpperCase());
|
||||
reader = r;
|
||||
}
|
||||
catch(IllegalArgumentException e){
|
||||
throw new ParseException("Data type "+ suffix + " not supported");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( line.hasOption(o_writer.getOpt() )){
|
||||
String wr = line.getOptionValue(o_writer.getOpt());
|
||||
try{
|
||||
Writer v = Writer.valueOf(wr.toUpperCase());
|
||||
writer = v;
|
||||
}
|
||||
catch(IllegalArgumentException e){
|
||||
throw new ParseException("Data type "+ wr + " not supported");
|
||||
}
|
||||
}
|
||||
else{
|
||||
String suffix = outfile.getName().replaceAll("^.*\\.", "");
|
||||
try{
|
||||
Writer v = Writer.valueOf(suffix.toUpperCase());
|
||||
writer = v;
|
||||
}
|
||||
catch(IllegalArgumentException e){
|
||||
throw new ParseException("Data type "+ suffix + " not supported");
|
||||
}
|
||||
}
|
||||
|
||||
// Debug output
|
||||
logger.finest("Using writer: "+writer);
|
||||
|
||||
} catch (ParseException e) {
|
||||
System.err.println(e.getMessage());
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.printUsage(new PrintWriter(System.out, true), HelpFormatter.DEFAULT_WIDTH, scriptname, options);
|
||||
StringBuffer b = new StringBuffer();
|
||||
for(Writer w: Writer.values()){
|
||||
b.append(" ");
|
||||
b.append(w.toString().toLowerCase());
|
||||
}
|
||||
System.out.println("Supported writer(s):"+ b);
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
ConversionMain e = new ConversionMain();
|
||||
try{
|
||||
e.convert(infile, outfile, reader, writer);
|
||||
}
|
||||
catch(Exception ee){
|
||||
System.out.println("Conversion failed due to: "+ee.getMessage());
|
||||
logger.log(Level.WARNING, "Conversion failed due to Exception:", ee);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
293
src/main/java/ch/psi/fda/ui/RemoteAcquisitionMain.java
Normal file
@@ -0,0 +1,293 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but without any
|
||||
* warranty; without even the implied warranty of merchantability or fitness for
|
||||
* a particular purpose. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.ScrollPaneLayout;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.GnuParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Option;
|
||||
import org.apache.commons.cli.OptionBuilder;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
|
||||
import com.google.common.eventbus.AsyncEventBus;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import sun.misc.Signal;
|
||||
import sun.misc.SignalHandler;
|
||||
import ch.psi.fda.DescriptorProvider;
|
||||
import ch.psi.fda.edescriptor.EDescriptor;
|
||||
import ch.psi.fda.gui.ProgressPanel;
|
||||
import ch.psi.fda.gui.ScrollableFlowPanel;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.ui.visualizer.Visualizer;
|
||||
import ch.psi.fda.vdescriptor.VDescriptor;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class RemoteAcquisitionMain {
|
||||
|
||||
private static Logger logger = Logger.getLogger(RemoteAcquisitionMain.class.getName());
|
||||
|
||||
StreamClient streamClient = null;
|
||||
private String trackingId;
|
||||
|
||||
/**
|
||||
* Main Program Process exit code: -1 if wrong number of arguments are
|
||||
* passed Process exit code: 3 if aborted via Ctrl+C
|
||||
*
|
||||
* @param args
|
||||
* Arguments of the program
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
String scriptname = "scan";
|
||||
|
||||
String server = null;
|
||||
boolean nogui = false;
|
||||
List<File> files = new ArrayList<>();
|
||||
|
||||
OptionBuilder.hasArg();
|
||||
OptionBuilder.isRequired();
|
||||
OptionBuilder.withArgName("hostname");
|
||||
OptionBuilder.withDescription("Hostname server");
|
||||
OptionBuilder.withType(new String());
|
||||
Option o_server = OptionBuilder.create("server");
|
||||
|
||||
Option o_nogui = new Option("nogui", "Do not show scan GUI");
|
||||
|
||||
Options options = new Options();
|
||||
options.addOption(o_server);
|
||||
options.addOption(o_nogui);
|
||||
|
||||
CommandLineParser parser = new GnuParser();
|
||||
try {
|
||||
CommandLine line = parser.parse(options, args);
|
||||
|
||||
if (line.getArgs().length < 1) {
|
||||
throw new ParseException("One argument is required");
|
||||
}
|
||||
|
||||
if (line.hasOption(o_server.getOpt())) {
|
||||
server = line.getOptionValue(o_server.getOpt());
|
||||
}
|
||||
|
||||
if (line.hasOption(o_nogui.getOpt())) {
|
||||
nogui = true;
|
||||
}
|
||||
|
||||
for (String f : line.getArgs()) {
|
||||
File file = new File(f);
|
||||
if (!file.exists()) {
|
||||
throw new RuntimeException("File " + file.getAbsolutePath() + " does not exist");
|
||||
}
|
||||
files.add(file);
|
||||
}
|
||||
|
||||
} catch (ParseException e) {
|
||||
System.err.println(e.getMessage());
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.printUsage(new PrintWriter(System.out, true), HelpFormatter.DEFAULT_WIDTH, scriptname, options);
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
try {
|
||||
for (File file : files) {
|
||||
RemoteAcquisitionMain m = new RemoteAcquisitionMain();
|
||||
m.execute(server, file, nogui);
|
||||
}
|
||||
} catch (Exception ee) {
|
||||
logger.log(Level.SEVERE, "Acquisition failed due to: ", ee);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void execute(final String server, File file, boolean nogui) {
|
||||
|
||||
trackingId = UUID.randomUUID().toString();
|
||||
logger.info("TrackingID of job: " + trackingId);
|
||||
|
||||
|
||||
EDescriptor edescriptor = null;
|
||||
VDescriptor vdescriptor = null;
|
||||
ServiceLoader<DescriptorProvider> providers = ServiceLoader.load(DescriptorProvider.class);
|
||||
for (DescriptorProvider provider : providers) {
|
||||
try{
|
||||
provider.load(file);
|
||||
edescriptor = provider.getEDescriptor();
|
||||
vdescriptor = provider.getVDescriptor();
|
||||
break;
|
||||
}
|
||||
catch(Exception e){
|
||||
logger.log(Level.INFO, provider.getClass().getName()+ " is not able to read provided descriptor files", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EventBus b = new AsyncEventBus(Executors.newSingleThreadExecutor());
|
||||
final RestClient client = new RestClient(server, 8080); // TODO hardcoded server port
|
||||
|
||||
|
||||
|
||||
if (!nogui && vdescriptor.getPlots().size() > 0) {
|
||||
|
||||
streamClient = new StreamClient(b);
|
||||
|
||||
Visualizer visualizer = new Visualizer(vdescriptor);
|
||||
visualizer.configure();
|
||||
b.register(visualizer);
|
||||
|
||||
JPanel opanel = new ScrollableFlowPanel();
|
||||
opanel.setLayout(new FlowLayout());
|
||||
|
||||
JScrollPane spane = new JScrollPane(opanel, ScrollPaneLayout.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneLayout.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
JTabbedPane tpane = new JTabbedPane();
|
||||
tpane.addTab("Overview", spane);
|
||||
|
||||
for (JPanel p : visualizer.getPlotPanels()) {
|
||||
opanel.add(p);
|
||||
}
|
||||
|
||||
final JFrame frame = new JFrame("FDA: " + file);
|
||||
frame.setSize(1200, 800);
|
||||
|
||||
final ProgressPanel progressPanel = new ProgressPanel();
|
||||
progressPanel.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
client.terminate(trackingId);
|
||||
} catch (Exception e1) {
|
||||
logger.log(Level.SEVERE, "Exception occured while aborting scan", e1);
|
||||
} finally {
|
||||
progressPanel.done();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
b.register(new Object(){
|
||||
@Subscribe
|
||||
public void onMessage(EndOfStreamMessage m){
|
||||
progressPanel.done();
|
||||
}
|
||||
});
|
||||
|
||||
JSplitPane splitPane = new JSplitPane();
|
||||
splitPane.setLeftComponent(progressPanel);
|
||||
splitPane.setRightComponent(tpane);
|
||||
|
||||
frame.add(splitPane);
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent we) {
|
||||
client.terminate(trackingId);
|
||||
|
||||
int count = 0;
|
||||
while (client.isActive(trackingId)) {
|
||||
if (count == 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // .DO_NOTHING_ON_CLOSE);
|
||||
|
||||
java.awt.EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
frame.setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
Signal.handle(new Signal("INT"), new SignalHandler() {
|
||||
|
||||
private AtomicInteger signalCount = new AtomicInteger(0);
|
||||
|
||||
@Override
|
||||
public void handle(Signal signal) {
|
||||
|
||||
logger.finest("Received signal: " + signal);
|
||||
|
||||
try{
|
||||
client.terminate(trackingId);
|
||||
}
|
||||
catch(Exception e){
|
||||
logger.log(Level.WARNING, "Stopping scan failed with exception", e);
|
||||
}
|
||||
|
||||
if (signalCount.incrementAndGet() > 1) {
|
||||
logger.info("Terminate application");
|
||||
System.exit(2);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
if(streamClient!=null){
|
||||
streamClient.filterTrackingId(trackingId);
|
||||
Executors.newSingleThreadExecutor().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
streamClient.listen("tcp://"+server+":10000");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
client.acquire(trackingId, edescriptor);
|
||||
}
|
||||
}
|
||||
56
src/main/java/ch/psi/fda/ui/RestClient.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2013 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but without any
|
||||
* warranty; without even the implied warranty of merchantability or fitness for
|
||||
* a particular purpose. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package ch.psi.fda.ui;
|
||||
|
||||
import javax.ws.rs.client.Client;
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.glassfish.jersey.jackson.JacksonFeature;
|
||||
|
||||
import ch.psi.fda.edescriptor.EDescriptor;
|
||||
|
||||
public class RestClient {
|
||||
|
||||
private final Client client;
|
||||
private final WebTarget target;
|
||||
|
||||
public RestClient(String servername, int port){
|
||||
client = ClientBuilder.newClient().register(JacksonFeature.class);
|
||||
target = client.target("http://"+servername+":"+port).path("fda");
|
||||
}
|
||||
|
||||
public String acquire(String trackingId, EDescriptor edescriptor){
|
||||
return target.path(trackingId).request().put(Entity.entity(edescriptor, MediaType.APPLICATION_XML), String.class);
|
||||
}
|
||||
|
||||
public void terminate(String trackingId){
|
||||
target.path(trackingId).request().delete();
|
||||
}
|
||||
|
||||
public void terminateAll(){
|
||||
target.request().delete();
|
||||
}
|
||||
|
||||
public boolean isActive(String trackingId){
|
||||
return target.path(trackingId).path("running").request().get(Boolean.class);
|
||||
}
|
||||
}
|
||||
98
src/main/java/ch/psi/fda/ui/StreamClient.java
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2013 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but without any
|
||||
* warranty; without even the implied warranty of merchantability or fitness for
|
||||
* a particular purpose. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package ch.psi.fda.ui;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.codehaus.jackson.JsonFactory;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.codehaus.jackson.type.TypeReference;
|
||||
import org.zeromq.ZMQ;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
public class StreamClient {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(StreamClient.class.getName());
|
||||
private ObjectMapper mapper = new ObjectMapper(new JsonFactory());
|
||||
|
||||
|
||||
private final EventBus bus;
|
||||
private String trackingIdFilter = null;
|
||||
|
||||
public StreamClient(EventBus bus) {
|
||||
this.bus = bus;
|
||||
}
|
||||
|
||||
public void listen(String endpoint) {
|
||||
ZMQ.Context context = ZMQ.context(1);
|
||||
// zmq.ZError.clear(); // Clear error code
|
||||
ZMQ.Socket socket = context.socket(ZMQ.SUB);
|
||||
socket.connect(endpoint);
|
||||
socket.subscribe("".getBytes()); // SUBSCRIBE !
|
||||
|
||||
while (true) {
|
||||
String tid = null;
|
||||
|
||||
byte[] content = null;
|
||||
byte[] header = socket.recv(); // header
|
||||
if(trackingIdFilter!=null){
|
||||
try {
|
||||
Map<String,Object> m = mapper.readValue(header, new TypeReference<HashMap<String,Object>>(){});
|
||||
tid = (String) m.get("trackingId");
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
while (socket.hasReceiveMore()) {
|
||||
content = socket.recv();
|
||||
}
|
||||
if (content == null) { // we lost something discard read messages
|
||||
logger.warning("Lost some message - discard and continue");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(tid!=null && !tid.matches(trackingIdFilter)){
|
||||
continue;
|
||||
}
|
||||
|
||||
try (ByteArrayInputStream bis = new ByteArrayInputStream(content); ObjectInput in = new ObjectInputStream(bis);) {
|
||||
Object o = in.readObject();
|
||||
bus.post(o);
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
logger.log(Level.WARNING, "Unable to deserialize message", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public String getTrackingIdFilter() {
|
||||
return trackingIdFilter;
|
||||
}
|
||||
|
||||
public void filterTrackingId(String trackingId) {
|
||||
this.trackingIdFilter = trackingId;
|
||||
}
|
||||
}
|
||||
221
src/main/java/ch/psi/fda/ui/VisualizationMain.java
Normal file
@@ -0,0 +1,221 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.ScrollPaneLayout;
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.GnuParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Option;
|
||||
import org.apache.commons.cli.OptionBuilder;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.google.common.eventbus.AsyncEventBus;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import ch.psi.fda.DescriptorProvider;
|
||||
import ch.psi.fda.deserializer.DataDeserializer;
|
||||
import ch.psi.fda.deserializer.DataDeserializerTXT;
|
||||
import ch.psi.fda.gui.ScrollableFlowPanel;
|
||||
import ch.psi.fda.ui.visualizer.Visualizer;
|
||||
import ch.psi.fda.vdescriptor.VDescriptor;
|
||||
|
||||
/**
|
||||
* Visualize data according to the scan description
|
||||
*/
|
||||
public class VisualizationMain {
|
||||
|
||||
private static Logger logger = Logger.getLogger(VisualizationMain.class.getName());
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public VisualizationMain(){
|
||||
}
|
||||
|
||||
// Visualize data based on the configuration file
|
||||
public void visualize(File configuration, File data) throws InterruptedException{
|
||||
|
||||
if(configuration==null){
|
||||
throw new IllegalArgumentException("Configuration file is null");
|
||||
}
|
||||
else if(!configuration.exists()){
|
||||
throw new IllegalArgumentException("Configuration file ["+configuration.getAbsolutePath()+"] does not exist");
|
||||
}
|
||||
|
||||
VDescriptor vdescriptor = null;
|
||||
ServiceLoader<DescriptorProvider> providers = ServiceLoader.load(DescriptorProvider.class);
|
||||
for (DescriptorProvider provider : providers) {
|
||||
try{
|
||||
provider.load(configuration);
|
||||
vdescriptor = provider.getVDescriptor();
|
||||
break;
|
||||
}
|
||||
catch(Exception e){
|
||||
logger.log(Level.INFO, provider.getClass().getName()+ " is not able to read provided descriptor files", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Visualize data
|
||||
visualize(vdescriptor, data);
|
||||
}
|
||||
|
||||
public void visualize(VDescriptor vdescriptor, File data) throws InterruptedException{
|
||||
|
||||
if(data==null){
|
||||
throw new IllegalArgumentException("Data file is null");
|
||||
}
|
||||
else if(!data.exists()){
|
||||
throw new IllegalArgumentException("Data file ["+data.getAbsolutePath()+"] does not exist");
|
||||
}
|
||||
|
||||
EventBus bus = new AsyncEventBus(Executors.newCachedThreadPool());
|
||||
// Create deserializer
|
||||
DataDeserializer deserializer = new DataDeserializerTXT(bus, data);
|
||||
|
||||
// Create Visualizer
|
||||
Visualizer visualizer = new Visualizer(vdescriptor);
|
||||
|
||||
// visualizer.setTerminateAtEOS(true);
|
||||
// Adapt default visualizer behavior to optimize performance for visualization
|
||||
visualizer.setUpdateAtStreamElement(false);
|
||||
visualizer.setUpdateAtStreamDelimiter(false);
|
||||
visualizer.setUpdateAtEndOfStream(true);
|
||||
|
||||
JPanel opanel = new ScrollableFlowPanel();
|
||||
opanel.setLayout(new FlowLayout());
|
||||
|
||||
JScrollPane spane = new JScrollPane(opanel, ScrollPaneLayout.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneLayout.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
JTabbedPane tpane = new JTabbedPane();
|
||||
tpane.addTab("Overview", spane);
|
||||
|
||||
for (JPanel p : visualizer.getPlotPanels()) {
|
||||
opanel.add(p);
|
||||
}
|
||||
|
||||
final JFrame frame = new JFrame();
|
||||
frame.setSize(1200,800);
|
||||
frame.add(tpane);
|
||||
// frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
frame.addWindowListener(new WindowAdapter(){
|
||||
@Override
|
||||
public void windowClosing(WindowEvent we){
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//.DO_NOTHING_ON_CLOSE);
|
||||
|
||||
java.awt.EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
frame.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
// Start deserializer and visualizer
|
||||
|
||||
bus.register(visualizer);
|
||||
visualizer.configure();
|
||||
deserializer.read();
|
||||
|
||||
logger.info("Deserializer finished");
|
||||
// visualizer.stopVisualization();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method accepts a data file and an option (-file) specifying the scan configuration file
|
||||
* used for creating the data file. If no option is specified the configuration file is derived by the
|
||||
* data file name.
|
||||
*
|
||||
* @param args Command line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
String scriptname = "fda_vis";
|
||||
File dfile = null;
|
||||
File cfile = null;
|
||||
|
||||
OptionBuilder.hasArg();
|
||||
OptionBuilder.withArgName("file");
|
||||
OptionBuilder.withDescription("Scan configuration file");
|
||||
OptionBuilder.withType(new String());
|
||||
Option o_cfile = OptionBuilder.create( "file");
|
||||
|
||||
Options options = new Options();
|
||||
options.addOption(o_cfile);
|
||||
|
||||
CommandLineParser parser = new GnuParser();
|
||||
// Parse the command line arguments
|
||||
try {
|
||||
CommandLine line = parser.parse( options, args );
|
||||
|
||||
// Check whether exactly one file is specified
|
||||
if(line.getArgs().length!=1){
|
||||
throw new ParseException("Only up to one argument is supported");
|
||||
}
|
||||
dfile= new File(line.getArgs()[0]);
|
||||
|
||||
if( line.hasOption(o_cfile.getOpt() )){
|
||||
cfile = new File(line.getOptionValue(o_cfile.getOpt()));
|
||||
}
|
||||
else{
|
||||
// Try to determine configuration file from data file name
|
||||
File dir = dfile.getParentFile();
|
||||
String name = dfile.getName();
|
||||
name = name.replaceAll("_[0-9]*.txt$", "");
|
||||
cfile = new File(dir, name+".xml");
|
||||
}
|
||||
|
||||
} catch (ParseException e) {
|
||||
System.err.println(e.getMessage());
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.printUsage(new PrintWriter(System.out, true), HelpFormatter.DEFAULT_WIDTH, scriptname, options);
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
VisualizationMain e = new VisualizationMain();
|
||||
try{
|
||||
e.visualize(cfile, dfile);
|
||||
}
|
||||
catch(Exception ee){
|
||||
System.out.println("Visualization failed due to: "+ee.getMessage());
|
||||
logger.log(Level.WARNING, "Visualization failed due to Exception:", ee);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
179
src/main/java/ch/psi/fda/ui/VisualizationZMQMain.java
Normal file
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Label;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.ScrollPaneLayout;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.GnuParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import ch.psi.fda.gui.ScrollableFlowPanel;
|
||||
import ch.psi.fda.ui.visualizer.Visualizer;
|
||||
import ch.psi.fda.vdescriptor.VDescriptor;
|
||||
|
||||
/**
|
||||
* Visualize data according to the descriptor streamed via ZMQ
|
||||
*/
|
||||
public class VisualizationZMQMain {
|
||||
|
||||
private static Logger logger = Logger.getLogger(VisualizationZMQMain.class.getName());
|
||||
|
||||
private Visualizer visualizer;
|
||||
private String source;;
|
||||
|
||||
public VisualizationZMQMain(String source){
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
|
||||
public void visualize() throws InterruptedException{
|
||||
|
||||
final JPanel opanel = new ScrollableFlowPanel();
|
||||
opanel.setLayout(new FlowLayout());
|
||||
|
||||
opanel.add(new Label());
|
||||
|
||||
JScrollPane spane = new JScrollPane(opanel, ScrollPaneLayout.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneLayout.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
JTabbedPane tpane = new JTabbedPane();
|
||||
tpane.addTab("Overview", spane);
|
||||
|
||||
|
||||
|
||||
final JFrame frame = new JFrame();
|
||||
frame.setSize(1200,800);
|
||||
frame.add(tpane);
|
||||
frame.addWindowListener(new WindowAdapter(){
|
||||
@Override
|
||||
public void windowClosing(WindowEvent we){
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//.DO_NOTHING_ON_CLOSE);
|
||||
|
||||
java.awt.EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
frame.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
// Start receiving messages
|
||||
final EventBus bus = new EventBus();
|
||||
|
||||
bus.register(new Object(){
|
||||
@Subscribe
|
||||
public void onMessage(VDescriptor vdescriptor){
|
||||
|
||||
logger.info("Build up new visualization");
|
||||
|
||||
// De-register old visualizer
|
||||
if(visualizer!=null){
|
||||
bus.unregister(visualizer);
|
||||
}
|
||||
|
||||
visualizer = new Visualizer(vdescriptor);
|
||||
visualizer.setUpdateAtStreamElement(true);
|
||||
visualizer.setUpdateAtStreamDelimiter(true);
|
||||
visualizer.setUpdateAtEndOfStream(true);
|
||||
|
||||
|
||||
opanel.removeAll();
|
||||
for (JPanel p : visualizer.getPlotPanels()) {
|
||||
opanel.add(p);
|
||||
}
|
||||
frame.repaint();
|
||||
|
||||
bus.register(visualizer);
|
||||
visualizer.configure();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
new StreamClient(bus).listen(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method accepts a data file and an option (-file) specifying the scan configuration file
|
||||
* used for creating the data file. If no option is specified the configuration file is derived by the
|
||||
* data file name.
|
||||
*
|
||||
* @param args Command line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
int port = 10000;
|
||||
String hostname = "localhost";
|
||||
Options options = new Options();
|
||||
options.addOption("h", false, "Help");
|
||||
options.addOption("p", true, "Server port (default: "+port+")");
|
||||
options.addOption("s", true, "Server address (default: "+hostname+")");
|
||||
|
||||
GnuParser parser = new GnuParser();
|
||||
|
||||
try {
|
||||
CommandLine line = parser.parse(options, args);
|
||||
|
||||
if (line.hasOption("p")) {
|
||||
port = Integer.parseInt(line.getOptionValue("p"));
|
||||
}
|
||||
if (line.hasOption("s")) {
|
||||
hostname = line.getOptionValue("s");
|
||||
}
|
||||
if (line.hasOption("h")) {
|
||||
HelpFormatter f = new HelpFormatter();
|
||||
f.printHelp("viewer", options);
|
||||
return;
|
||||
}
|
||||
} catch (ParseException e1) {
|
||||
System.err.println("Wrong arguments: "+ e1.getMessage());
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
try{
|
||||
VisualizationZMQMain e = new VisualizationZMQMain("tcp://"+hostname+":"+port);
|
||||
e.visualize();
|
||||
}
|
||||
catch(Exception ee){
|
||||
System.out.println("Visualization failed due to: "+ee.getMessage());
|
||||
logger.log(Level.WARNING, "Visualization failed due to Exception:", ee);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ch.psi.plot.Plot;
|
||||
|
||||
public class DataVisualization {
|
||||
|
||||
private final Plot plot;
|
||||
private final List<XYSeriesDataFilter> series;
|
||||
|
||||
public DataVisualization(Plot plot){
|
||||
this.plot = plot;
|
||||
this.series = new ArrayList<XYSeriesDataFilter>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the plot
|
||||
*/
|
||||
public Plot getPlot() {
|
||||
return plot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the series
|
||||
*/
|
||||
public List<XYSeriesDataFilter> getSeries() {
|
||||
return series;
|
||||
}
|
||||
|
||||
}
|
||||
32
src/main/java/ch/psi/fda/ui/visualizer/SeriesDataFilter.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import ch.psi.plot.Plot;
|
||||
import ch.psi.plot.PlotSeries;
|
||||
|
||||
public interface SeriesDataFilter {
|
||||
/**
|
||||
* Get the plot for the filter
|
||||
* @return Plot
|
||||
*/
|
||||
public Plot getPlot();
|
||||
public PlotSeries getSeries();
|
||||
}
|
||||
415
src/main/java/ch/psi/fda/ui/visualizer/Visualizer.java
Normal file
@@ -0,0 +1,415 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.messages.StreamDelimiterMessage;
|
||||
import ch.psi.fda.vdescriptor.Series;
|
||||
import ch.psi.fda.vdescriptor.VDescriptor;
|
||||
import ch.psi.fda.vdescriptor.XYSeries;
|
||||
import ch.psi.fda.vdescriptor.XYZSeries;
|
||||
import ch.psi.fda.vdescriptor.YSeries;
|
||||
import ch.psi.fda.vdescriptor.YZSeries;
|
||||
import ch.psi.plot.LinePlot;
|
||||
import ch.psi.plot.LinePlotBase;
|
||||
import ch.psi.plot.LinePlotSeries;
|
||||
import ch.psi.plot.MatrixPlot;
|
||||
import ch.psi.plot.MatrixPlotBase;
|
||||
import ch.psi.plot.MatrixPlotSeries;
|
||||
import ch.psi.plot.Plot;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import java.awt.Font;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
* Visualizer for visualizing data
|
||||
*/
|
||||
public class Visualizer {
|
||||
|
||||
private static Logger logger = Logger.getLogger(Visualizer.class.getName());
|
||||
|
||||
private boolean updateAtStreamElement = true;
|
||||
private boolean updateAtStreamDelimiter = true;
|
||||
private boolean updateAtEndOfStream = false;
|
||||
|
||||
private int ecount;
|
||||
private boolean clearPlot;
|
||||
private List<SeriesDataFilter> filters;
|
||||
|
||||
int subsampling;
|
||||
int subsamplingCounter=0;
|
||||
|
||||
public static final Font TITLE_FONT = new Font("Tahoma", Font.BOLD, 18);
|
||||
|
||||
private boolean first = true;
|
||||
public Visualizer(VDescriptor vdescriptor){
|
||||
this(vdescriptor,null);
|
||||
}
|
||||
public Visualizer(VDescriptor vdescriptor, String linePlotImpl){
|
||||
if (linePlotImpl==null){
|
||||
linePlotImpl="jfree";
|
||||
}
|
||||
String matrixPlotImpl="jfree";
|
||||
|
||||
filters = new ArrayList<SeriesDataFilter>();
|
||||
|
||||
try{
|
||||
for(ch.psi.fda.vdescriptor.Plot vplot: vdescriptor.getPlots()){
|
||||
if(vplot instanceof ch.psi.fda.vdescriptor.LinePlot){
|
||||
ch.psi.fda.vdescriptor.LinePlot lp = (ch.psi.fda.vdescriptor.LinePlot) vplot;
|
||||
|
||||
// Create plot for visualization
|
||||
LinePlot plot = LinePlotBase.newPlot(linePlotImpl);
|
||||
plot.setTitle(lp.getTitle());
|
||||
plot.getAxis(Plot.AxisId.X).setLabel(null);
|
||||
plot.getAxis(Plot.AxisId.Y).setLabel(null);
|
||||
plot.setTitleFont(TITLE_FONT);
|
||||
|
||||
for(Series s: lp.getData()){
|
||||
if(s instanceof XYSeries){
|
||||
XYSeries sxy = (XYSeries)s;
|
||||
XYSeriesDataFilter filter = new XYSeriesDataFilter(sxy.getX(), sxy.getY(), plot);
|
||||
filter.setSeriesName(sxy.getY());
|
||||
if (sxy.getMaxItemCount()>=0)
|
||||
filter.setMaxNumberOfPoints(sxy.getMaxItemCount());
|
||||
filters.add(filter);
|
||||
}
|
||||
else if(s instanceof YSeries){
|
||||
YSeries sy = (YSeries)s;
|
||||
|
||||
XYSeriesArrayDataFilter filter = new XYSeriesArrayDataFilter(sy.getY(), plot);
|
||||
// filter.setMaxSeries(lp.getMaxSeries()*lp.getY().size()); // Workaround - keep for each array max series
|
||||
// filter.setOffset(lp.getOffset());
|
||||
// filter.setSize(lp.getSize());
|
||||
filter.setMaxSeries(lp.getMaxSeries());
|
||||
filter.setOffset(lp.getMinX().intValue());
|
||||
filter.setSize(Double.valueOf(lp.getMaxX()-lp.getMinX()).intValue());
|
||||
filter.setSeriesName(sy.getY());
|
||||
filters.add(filter);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if(vplot instanceof ch.psi.fda.vdescriptor.MatrixPlot){
|
||||
|
||||
// MatrixPlot does currently not support RegionPositioners because of the
|
||||
// plotting problems this would cause. If regions of the positioner have different
|
||||
// step sizes it is not easily possible (without (specialized) rasterization) to plot the data.
|
||||
|
||||
ch.psi.fda.vdescriptor.MatrixPlot lp = (ch.psi.fda.vdescriptor.MatrixPlot) vplot;
|
||||
MatrixPlotSeries data = new MatrixPlotSeries("", lp.getMinX(), lp.getMaxX(), lp.getnX(), lp.getMinY(), lp.getMaxY(), lp.getnY());
|
||||
if ("3D".equals(lp.getType()))
|
||||
matrixPlotImpl="jzy3d";
|
||||
MatrixPlot plot = MatrixPlotBase.newPlot(matrixPlotImpl);
|
||||
plot.setTitle(lp.getTitle());
|
||||
plot.setTitleFont(TITLE_FONT);
|
||||
plot.addSeries(data);
|
||||
|
||||
for(Series s: lp.getData()){
|
||||
if(s instanceof XYZSeries){
|
||||
XYZSeries sxyz = (XYZSeries) s;
|
||||
XYZSeriesDataFilter filter=new XYZSeriesDataFilter(sxyz.getX(), sxyz.getY(), sxyz.getZ(), plot);
|
||||
filter.setSeries(data);
|
||||
filters.add(filter);
|
||||
|
||||
}
|
||||
else if(s instanceof YZSeries){
|
||||
YZSeries syz = (YZSeries) s;
|
||||
XYZSeriesArrayDataFilter filter = new XYZSeriesArrayDataFilter(syz.getY(), syz.getZ(), 0, 0, plot);
|
||||
filter.setSeries(data);
|
||||
filters.add(filter);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Ignore if something goes wrong while adding a datapoint
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onDataMessage(final DataMessage message){
|
||||
|
||||
if(first){
|
||||
first=false;
|
||||
// filters = VisMapper.mapVisualizations(visualizations);
|
||||
// TODO somehow handle dimension / clear
|
||||
}
|
||||
|
||||
// Clear is here as the plot should not be cleared after the last point is plotted
|
||||
// but just before the first point of the next plot (cycle)
|
||||
if (clearPlot) {
|
||||
for (SeriesDataFilter f: filters) {
|
||||
Plot plot = f.getPlot();
|
||||
if(plot instanceof MatrixPlot){
|
||||
f.getSeries().clear();
|
||||
}
|
||||
}
|
||||
clearPlot = false;
|
||||
}
|
||||
|
||||
if (subsampling>1){
|
||||
if ((subsamplingCounter++) > subsampling) {
|
||||
subsamplingCounter=0;
|
||||
}
|
||||
else{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for(SeriesDataFilter filter: filters){
|
||||
if(filter instanceof XYSeriesDataFilter){
|
||||
XYSeriesDataFilter xyfilter = (XYSeriesDataFilter) filter;
|
||||
|
||||
if(xyfilter.getSeries()==null || xyfilter.isNewseries()){
|
||||
// First series that is filled by this filter!
|
||||
LinePlotSeries s = new LinePlotSeries(xyfilter.getSeriesName() + " " + ecount + "-" + xyfilter.getCount());
|
||||
if (xyfilter.getMaxNumberOfPoints()>=0)
|
||||
s.setMaxItemCount(xyfilter.getMaxNumberOfPoints());
|
||||
((LinePlot)xyfilter.getPlot()).addSeries(s);
|
||||
xyfilter.setSeries(s);
|
||||
xyfilter.setNewseries(false);
|
||||
}
|
||||
|
||||
LinePlotSeries series = xyfilter.getSeries(); // TODO Does not work with multiple series filter per plot !!!!
|
||||
|
||||
// There might be other values than double in the data, therefore we have to check for it
|
||||
Object dX = message.getData(xyfilter.getIdX());
|
||||
Object dY = message.getData(xyfilter.getIdY());
|
||||
Double dataX = getDoubleValue (dX);
|
||||
Double dataY = getDoubleValue (dY);
|
||||
|
||||
// Add Data to the series
|
||||
((LinePlot)xyfilter.getPlot()).setUpdatesEnabled(updateAtStreamElement);
|
||||
series.appendData(dataX , dataY);
|
||||
((LinePlot)xyfilter.getPlot()).setUpdatesEnabled(true);
|
||||
}
|
||||
if(filter instanceof XYSeriesArrayDataFilter){
|
||||
final XYSeriesArrayDataFilter xyfilter = (XYSeriesArrayDataFilter) filter;
|
||||
|
||||
// Ensure that there is no concurrent modification exception or synchronization problems with the
|
||||
// Swing update task
|
||||
SwingUtilities.invokeLater(new Runnable(){
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LinePlotSeries series = new LinePlotSeries(xyfilter.getSeriesName() + "-" + xyfilter.getCount()); // Series name must be unique
|
||||
xyfilter.incrementCount();
|
||||
|
||||
// ((LinePlot)xyfilter.getPlot()).getData().removeAllSeries(); // Remove all series from the data
|
||||
// If we can agree only to display one series at a time also a clear() on the actual series is better
|
||||
((LinePlot)xyfilter.getPlot()).addSeries(series);
|
||||
xyfilter.setSeries(series);
|
||||
|
||||
// Remove outdated series
|
||||
if(((LinePlot)xyfilter.getPlot()).getNumberOfSeries()>xyfilter.getMaxSeries()){
|
||||
// Remove oldest series
|
||||
LinePlotSeries s = ((LinePlot)xyfilter.getPlot()).getSeries(0);
|
||||
((LinePlot)xyfilter.getPlot()).removeSeries(s);
|
||||
}
|
||||
|
||||
double[] data = message.getData(xyfilter.getIdY());
|
||||
|
||||
|
||||
// Copy data starting from offset to size
|
||||
int size = data.length;
|
||||
int offset = xyfilter.getOffset();
|
||||
if(xyfilter.getSize()>0 && offset+xyfilter.getSize()<data.length){
|
||||
size = offset + xyfilter.getSize();
|
||||
}
|
||||
|
||||
((LinePlot)xyfilter.getPlot()).setUpdatesEnabled(updateAtStreamElement);
|
||||
for(int i=offset;i<size;i++){
|
||||
//series.add(i,data[i], false); // Do not fire change event - this would degrade performance drastically
|
||||
series.appendData(i,data[i]);
|
||||
}
|
||||
((LinePlot)xyfilter.getPlot()).setUpdatesEnabled(true);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
else if(filter instanceof XYZSeriesDataFilter){
|
||||
XYZSeriesDataFilter xyzfilter = (XYZSeriesDataFilter) filter;
|
||||
try{
|
||||
xyzfilter.getPlot().setUpdatesEnabled(updateAtStreamElement);
|
||||
xyzfilter.getSeries().appendData((Double) message.getData(xyzfilter.getIdX()),(Double) message.getData(xyzfilter.getIdY()), (Double) message.getData(xyzfilter.getIdZ()));
|
||||
xyzfilter.getPlot().setUpdatesEnabled(true);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Ignore if something goes wrong while adding a datapoint
|
||||
logger.log(Level.WARNING, "Unable to plot datapoint in matrix plot", e);
|
||||
}
|
||||
}
|
||||
else if(filter instanceof XYZSeriesArrayDataFilter){
|
||||
XYZSeriesArrayDataFilter xyzfilter = (XYZSeriesArrayDataFilter) filter;
|
||||
try{
|
||||
double[] data = (double[]) message.getData(xyzfilter.getIdZ());
|
||||
double y = (Double) message.getData(xyzfilter.getIdY());
|
||||
// int offset = xyzfilter.getOffset();
|
||||
// int size = xyzfilter.getSize();
|
||||
// for(int i=offset;i<offset+size; i++){
|
||||
xyzfilter.getPlot().setUpdatesEnabled(updateAtStreamElement);
|
||||
for(int i=0;i<data.length; i++){
|
||||
((MatrixPlot)xyzfilter.getPlot()).getSeries("").appendData(i, y, data[i]);
|
||||
}
|
||||
xyzfilter.getPlot().setUpdatesEnabled(true);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Ignore if something goes wrong while adding a datapoint
|
||||
logger.log(Level.WARNING, "Unable to plot datapoint in matrix plot", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Double getDoubleValue(Object value){
|
||||
if(value instanceof Double){
|
||||
return (Double) value;
|
||||
}
|
||||
if(value instanceof Integer){
|
||||
return (double)((Integer) value);
|
||||
}
|
||||
else if(value instanceof Short){
|
||||
return (double)((Short) value);
|
||||
}
|
||||
else if(value instanceof Long){
|
||||
return (double)((Long) value);
|
||||
}
|
||||
else if(value instanceof Float){
|
||||
return (double)((Float) value);
|
||||
}
|
||||
else if(value instanceof Boolean){
|
||||
return ((Boolean) value)?1.0:0.0;
|
||||
}
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStreamDelimiterMessage(StreamDelimiterMessage message){
|
||||
for(SeriesDataFilter filter: filters){
|
||||
if(filter instanceof XYSeriesDataFilter){
|
||||
// Create new series
|
||||
XYSeriesDataFilter xyfilter = (XYSeriesDataFilter) filter;
|
||||
// if (message.getNumber() == xyfilter.getDimensionX()) {
|
||||
if (message.getNumber() == 0) { // TODO need to check this - here we assume that always at the lowest level we create a new series
|
||||
// Indicate to create new series at the next message
|
||||
xyfilter.setCount(xyfilter.getCount()+1); // Increment count of the filter
|
||||
xyfilter.setNewseries(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update matrix plot at the end of each line
|
||||
if(updateAtStreamDelimiter){
|
||||
for (Plot plot:getPlots()) {
|
||||
plot.update(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear matrix plot if iflag is encountered
|
||||
// TODO: One need to check whether the iflag belongs to a delimiter
|
||||
// of a higher dimension than the highest dimension (axis) that
|
||||
// is involved in the plot
|
||||
if (message.isIflag()) {
|
||||
clearPlot = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEndOfStreamMessage(EndOfStreamMessage message){
|
||||
ecount++;
|
||||
|
||||
// Update plots if updateAtEndOfStream flag is set
|
||||
if(updateAtEndOfStream){
|
||||
// Update matrix plots
|
||||
for (Plot plot:getPlots()) {
|
||||
plot.update(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void configure(){
|
||||
ecount = 0;
|
||||
clearPlot = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plot panels for the visualizations
|
||||
* @return List of configured JPanels
|
||||
*/
|
||||
public List<JPanel> getPlotPanels(){
|
||||
List<JPanel> panels = new ArrayList<JPanel>();
|
||||
for(SeriesDataFilter f: filters){
|
||||
JPanel panel=(JPanel) f.getPlot();
|
||||
if ((panel!=null) &&(!panels.contains(panel)))
|
||||
panels.add(panel);
|
||||
}
|
||||
|
||||
return panels;
|
||||
}
|
||||
|
||||
public List<Plot> getPlots(){
|
||||
List<Plot> plots = new ArrayList<Plot>();
|
||||
for(SeriesDataFilter f: filters){
|
||||
Plot plot=f.getPlot();
|
||||
if ((plot!=null) &&(!plots.contains(plot)))
|
||||
plots.add(plot);
|
||||
}
|
||||
return plots;
|
||||
}
|
||||
|
||||
public boolean isUpdateAtStreamElement() {
|
||||
return updateAtStreamElement;
|
||||
}
|
||||
public void setUpdateAtStreamElement(boolean updateAtStreamElement) {
|
||||
this.updateAtStreamElement = updateAtStreamElement;
|
||||
}
|
||||
public boolean isUpdateAtStreamDelimiter() {
|
||||
return updateAtStreamDelimiter;
|
||||
}
|
||||
public void setUpdateAtStreamDelimiter(boolean updateAtStreamDelimiter) {
|
||||
this.updateAtStreamDelimiter = updateAtStreamDelimiter;
|
||||
}
|
||||
public boolean isUpdateAtEndOfStream() {
|
||||
return updateAtEndOfStream;
|
||||
}
|
||||
public void setUpdateAtEndOfStream(boolean updateAtEndOfStream) {
|
||||
this.updateAtEndOfStream = updateAtEndOfStream;
|
||||
}
|
||||
|
||||
public int getSubsampling() {
|
||||
return subsampling;
|
||||
}
|
||||
public void setSubsampling(int factor) {
|
||||
this.subsampling = factor;
|
||||
subsamplingCounter=subsampling;//To plot first point
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import ch.psi.plot.LinePlotSeries;
|
||||
import ch.psi.plot.Plot;
|
||||
|
||||
/**
|
||||
* Metadata of a group of XYSeries.
|
||||
* This metadata holds the information needed by the DataVisualizer
|
||||
* to plot series.
|
||||
*/
|
||||
public class XYSeriesArrayDataFilter implements SeriesDataFilter {
|
||||
|
||||
private final String idY;
|
||||
|
||||
// Name of the series generated by this filter
|
||||
private String seriesName = "";
|
||||
|
||||
// Number of series generated for this filter
|
||||
private int count = 0;
|
||||
|
||||
private int maxSeries = 10;
|
||||
|
||||
// Offset of the array to plot
|
||||
private int offset = 0;
|
||||
// Size of the array to plot - size 0 means the complete array
|
||||
private int size = 0;
|
||||
|
||||
// Plot the data of this filter goes to
|
||||
private final Plot plot;
|
||||
|
||||
public XYSeriesArrayDataFilter(String idY, Plot plot){
|
||||
this.idY = idY;
|
||||
this.plot = plot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the yId
|
||||
*/
|
||||
public String getIdY() {
|
||||
return idY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the seriesName
|
||||
*/
|
||||
public String getSeriesName() {
|
||||
return seriesName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param seriesName the seriesName to set
|
||||
*/
|
||||
public void setSeriesName(String seriesName) {
|
||||
this.seriesName = seriesName;
|
||||
}
|
||||
|
||||
private LinePlotSeries series = null;
|
||||
|
||||
@Override
|
||||
public LinePlotSeries getSeries(){
|
||||
return series;
|
||||
}
|
||||
|
||||
public void setSeries(LinePlotSeries series){
|
||||
this.series=series;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the count
|
||||
*/
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param count the count to set
|
||||
*/
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the plot
|
||||
*/
|
||||
public Plot getPlot() {
|
||||
return plot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment series count
|
||||
*/
|
||||
public void incrementCount(){
|
||||
count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param maxSeries the maxSeries to set
|
||||
*/
|
||||
public void setMaxSeries(int maxSeries) {
|
||||
this.maxSeries = maxSeries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maxSeries
|
||||
*/
|
||||
public int getMaxSeries() {
|
||||
return maxSeries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the offset
|
||||
*/
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param offset the offset to set
|
||||
*/
|
||||
public void setOffset(int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the size
|
||||
*/
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param size the size to set
|
||||
*/
|
||||
public void setSize(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import ch.psi.plot.LinePlot;
|
||||
import ch.psi.plot.LinePlotSeries;
|
||||
import ch.psi.plot.PlotSeries;
|
||||
|
||||
/**
|
||||
* Metadata of a group of XYSeries.
|
||||
* This metadata holds the information needed by the DataVisualizer
|
||||
* to plot series.
|
||||
*/
|
||||
public class XYSeriesDataFilter implements SeriesDataFilter{
|
||||
|
||||
private final String idX;
|
||||
private final String idY;
|
||||
|
||||
// Name of the series generated by this filter
|
||||
private String seriesName = "";
|
||||
|
||||
// Number of series generated for this filter
|
||||
private int count = 0;
|
||||
|
||||
// Max number of points per series (additional appends make oldest value to be )
|
||||
private int maxNumberOfPoints=-1;
|
||||
|
||||
// Plot the data of this filter goes to
|
||||
private final LinePlot plot;
|
||||
|
||||
private boolean newseries = false;
|
||||
|
||||
private LinePlotSeries series = null;
|
||||
@Override
|
||||
public LinePlotSeries getSeries(){
|
||||
return series;
|
||||
}
|
||||
public void setSeries(LinePlotSeries series){
|
||||
this.series=series;
|
||||
}
|
||||
|
||||
public XYSeriesDataFilter(String idX, String idY, LinePlot plot){
|
||||
this.idX = idX;
|
||||
this.idY = idY;
|
||||
this.plot = plot;
|
||||
}
|
||||
|
||||
public String getIdX() {
|
||||
return idX;
|
||||
}
|
||||
public String getIdY() {
|
||||
return idY;
|
||||
}
|
||||
public String getSeriesName() {
|
||||
return seriesName;
|
||||
}
|
||||
public void setSeriesName(String seriesName) {
|
||||
this.seriesName = seriesName;
|
||||
}
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
public LinePlot getPlot() {
|
||||
return plot;
|
||||
}
|
||||
public boolean isNewseries() {
|
||||
return newseries;
|
||||
}
|
||||
public void setNewseries(boolean newseries) {
|
||||
this.newseries = newseries;
|
||||
}
|
||||
public int getMaxNumberOfPoints() {
|
||||
return maxNumberOfPoints;
|
||||
}
|
||||
public void setMaxNumberOfPoints(int count) {
|
||||
this.maxNumberOfPoints = count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import ch.psi.plot.MatrixPlotSeries;
|
||||
import ch.psi.plot.Plot;
|
||||
|
||||
public class XYZSeriesArrayDataFilter implements SeriesDataFilter {
|
||||
|
||||
private final String idY;
|
||||
private final String idZ;
|
||||
|
||||
// Name of the series generated by this filter
|
||||
private String seriesName = "";
|
||||
|
||||
// Number of series generated for this filter
|
||||
private int count = 0;
|
||||
|
||||
// Plot the data of this filter goes to
|
||||
private final Plot plot;
|
||||
|
||||
private boolean newseries = false;
|
||||
|
||||
private final int size;
|
||||
private final int offset;
|
||||
|
||||
public XYZSeriesArrayDataFilter(String idY, String idZ, int offset, int size, Plot plot){
|
||||
this.idY = idY;
|
||||
this.idZ = idZ;
|
||||
this.offset = offset;
|
||||
this.size = size;
|
||||
this.plot = plot;
|
||||
}
|
||||
|
||||
public String getIdZ() {
|
||||
return idZ;
|
||||
}
|
||||
public String getSeriesName() {
|
||||
return seriesName;
|
||||
}
|
||||
public void setSeriesName(String seriesName) {
|
||||
this.seriesName = seriesName;
|
||||
}
|
||||
private MatrixPlotSeries series = null;
|
||||
|
||||
@Override
|
||||
public MatrixPlotSeries getSeries(){
|
||||
return series;
|
||||
}
|
||||
|
||||
public void setSeries(MatrixPlotSeries series){
|
||||
this.series=series;
|
||||
}
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
public boolean isNewseries() {
|
||||
return newseries;
|
||||
}
|
||||
public void setNewseries(boolean newseries) {
|
||||
this.newseries = newseries;
|
||||
}
|
||||
public String getIdY() {
|
||||
return idY;
|
||||
}
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
public Plot getPlot() {
|
||||
return plot;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import ch.psi.plot.MatrixPlotSeries;
|
||||
import ch.psi.plot.Plot;
|
||||
|
||||
public class XYZSeriesDataFilter implements SeriesDataFilter {
|
||||
|
||||
private final String idX;
|
||||
private final String idY;
|
||||
private final String idZ;
|
||||
|
||||
// Name of the series generated by this filter
|
||||
private String seriesName = "";
|
||||
|
||||
// Number of series generated for this filter
|
||||
private int count = 0;
|
||||
|
||||
// Plot the data of this filter goes to
|
||||
private final Plot plot;
|
||||
|
||||
private boolean newseries = false;
|
||||
|
||||
|
||||
public XYZSeriesDataFilter(String idX, String idY, String idZ, Plot plot){
|
||||
this.idX = idX;
|
||||
this.idY = idY;
|
||||
this.idZ = idZ;
|
||||
this.plot = plot;
|
||||
}
|
||||
|
||||
public String getIdZ() {
|
||||
return idZ;
|
||||
}
|
||||
public String getSeriesName() {
|
||||
return seriesName;
|
||||
}
|
||||
public void setSeriesName(String seriesName) {
|
||||
this.seriesName = seriesName;
|
||||
}
|
||||
|
||||
private MatrixPlotSeries series = null;
|
||||
|
||||
@Override
|
||||
public MatrixPlotSeries getSeries(){
|
||||
return series;
|
||||
}
|
||||
public void setSeries(MatrixPlotSeries series){
|
||||
this.series=series;
|
||||
}
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
public boolean isNewseries() {
|
||||
return newseries;
|
||||
}
|
||||
public void setNewseries(boolean newseries) {
|
||||
this.newseries = newseries;
|
||||
}
|
||||
public String getIdX() {
|
||||
return idX;
|
||||
}
|
||||
public String getIdY() {
|
||||
return idY;
|
||||
}
|
||||
public Plot getPlot() {
|
||||
return plot;
|
||||
}
|
||||
|
||||
}
|
||||
0
src/main/resources/.gitignore
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.deserializer;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import ch.psi.fda.messages.ControlMessage;
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.Message;
|
||||
import ch.psi.fda.messages.Metadata;
|
||||
|
||||
/**
|
||||
* For testing whether the created MDA file is correct use following
|
||||
* program on a SLS SL5 beamline console (or slslc05/06)
|
||||
*/
|
||||
public class DataDeserializerMDATest {
|
||||
|
||||
private static Logger logger = Logger.getLogger(DataDeserializerMDATest.class.getName());
|
||||
|
||||
private EventBus bus;
|
||||
private DataDeserializerMDA deserializer;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
bus = new EventBus();
|
||||
URL url = this.getClass().getClassLoader().getResource("testdata/mda/mdadata7.mda");
|
||||
deserializer = new DataDeserializerMDA(bus, new File(new URI(url.toString())));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRead() throws InterruptedException {
|
||||
|
||||
|
||||
|
||||
|
||||
// Do "read" data
|
||||
bus.register(new Object(){
|
||||
boolean first = true;
|
||||
|
||||
@Subscribe
|
||||
public void onMessage(Message m){
|
||||
if(m instanceof DataMessage){
|
||||
DataMessage x = (DataMessage) m;
|
||||
|
||||
if(first){
|
||||
first=false;
|
||||
// Visualize metadata
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("[");
|
||||
StringBuilder b1 = new StringBuilder();
|
||||
b1.append("[");
|
||||
for(Metadata cm : x.getMetadata()){
|
||||
b.append(" ");
|
||||
b.append(cm.getId());
|
||||
b1.append(" ");
|
||||
b1.append(cm.getDimension());
|
||||
}
|
||||
b.append(" ]");
|
||||
b1.append(" ]");
|
||||
|
||||
logger.info("Metadata "+b.toString());
|
||||
logger.info("Metadata "+b1.toString());
|
||||
}
|
||||
|
||||
|
||||
logger.info( x.toString() );
|
||||
}
|
||||
else if(m instanceof ControlMessage){
|
||||
logger.info("---- "+m.toString()+" ----");
|
||||
}
|
||||
}
|
||||
});
|
||||
deserializer.read();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.deserializer;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import ch.psi.fda.deserializer.DataDeserializer;
|
||||
import ch.psi.fda.deserializer.DataDeserializerTXT;
|
||||
import ch.psi.fda.messages.ControlMessage;
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.Message;
|
||||
|
||||
public class DataDeserializerTest {
|
||||
|
||||
private static Logger logger = Logger.getLogger(DataDeserializerTest.class.getName());
|
||||
|
||||
private DataDeserializer deserializer;
|
||||
private EventBus bus;
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
bus = new EventBus();
|
||||
URL url = this.getClass().getClassLoader().getResource("testdata/text/textdata2.txt");
|
||||
deserializer = new DataDeserializerTXT(bus, new File(new URI(url.toString())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.deserializer.DataDeserializerTXT#run()}.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Test
|
||||
public void testRun() throws InterruptedException {
|
||||
|
||||
bus.register(new Object(){
|
||||
@Subscribe
|
||||
public void onMessage(Message m){
|
||||
if(m instanceof DataMessage){
|
||||
DataMessage x = (DataMessage) m;
|
||||
logger.info( x.toString() );
|
||||
}
|
||||
else if(m instanceof ControlMessage){
|
||||
logger.info("---- "+m.toString()+" ----");
|
||||
}
|
||||
}
|
||||
});
|
||||
deserializer.read();
|
||||
}
|
||||
}
|
||||
225
src/test/java/ch/psi/fda/serializer/SerializerTest.java
Normal file
@@ -0,0 +1,225 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.serializer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.messages.Metadata;
|
||||
import ch.psi.fda.messages.StreamDelimiterMessage;
|
||||
import ch.psi.fda.serializer.SerializerMAT;
|
||||
import ch.psi.fda.serializer.SerializerMAT2D;
|
||||
import ch.psi.fda.serializer.SerializerTXT;
|
||||
import ch.psi.fda.serializer.SerializerTXT2D;
|
||||
import ch.psi.fda.serializer.SerializerTXTSplit;
|
||||
|
||||
|
||||
public class SerializerTest {
|
||||
|
||||
private static final String tmpDirectory = "target/tmp";
|
||||
|
||||
private EventBus bus;
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
new File(tmpDirectory).mkdirs();
|
||||
bus = new EventBus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate 1D data
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private void generate1DData() throws InterruptedException{
|
||||
List<Metadata> metadata = new ArrayList<>();
|
||||
metadata.add(new Metadata("id0", 0));
|
||||
metadata.add(new Metadata("id1", 0));
|
||||
metadata.add(new Metadata("id2", 0));
|
||||
|
||||
// Dimension
|
||||
DataMessage m = new DataMessage(metadata);
|
||||
m.getData().add(0.000000000000000001);
|
||||
m.getData().add(0.1);
|
||||
m.getData().add(1d); // have this value as double
|
||||
bus.post(m);
|
||||
|
||||
m = new DataMessage(metadata);
|
||||
m.getData().add(0.02);
|
||||
m.getData().add(0.2);
|
||||
m.getData().add(2d); // have this value as double
|
||||
bus.post(m);
|
||||
bus.post(new EndOfStreamMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate 2D test data
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private void generate2DData() throws InterruptedException{
|
||||
List<Metadata> metadata = new ArrayList<>();
|
||||
metadata.add(new Metadata("id0", 1));
|
||||
metadata.add(new Metadata("id1", 0));
|
||||
metadata.add(new Metadata("id2", 0));
|
||||
|
||||
for(double i=0;i<5;i++){
|
||||
for(double t=0.1; t<10; t=t+0.1){
|
||||
// Dimension
|
||||
DataMessage m = new DataMessage(metadata);
|
||||
m.getData().add(i);
|
||||
m.getData().add(t);
|
||||
m.getData().add(Math.log(t)); // have this value as double
|
||||
bus.post(m);
|
||||
}
|
||||
bus.post(new StreamDelimiterMessage(0));
|
||||
}
|
||||
bus.post(new StreamDelimiterMessage(1));
|
||||
|
||||
|
||||
bus.post(new EndOfStreamMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate 3d test data
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private void generate3DData() throws InterruptedException{
|
||||
List<Metadata> metadata = new ArrayList<>();
|
||||
metadata.add(new Metadata("id0", 2));
|
||||
metadata.add(new Metadata("id1", 1));
|
||||
metadata.add(new Metadata("id2", 0));
|
||||
metadata.add(new Metadata("id3", 0));
|
||||
|
||||
for(double z=30;z<36;z++){
|
||||
for(double i=0;i<6;i++){
|
||||
for(double t=0.1; t<1.1; t=t+0.1){
|
||||
// Dimension
|
||||
DataMessage m = new DataMessage(metadata);
|
||||
m.getData().add(z);
|
||||
m.getData().add(i);
|
||||
m.getData().add(t);
|
||||
m.getData().add(Math.log(t)); // have this value as double
|
||||
bus.post(m);
|
||||
}
|
||||
bus.post(new StreamDelimiterMessage(0));
|
||||
}
|
||||
bus.post(new StreamDelimiterMessage(1));
|
||||
}
|
||||
bus.post(new StreamDelimiterMessage(2));
|
||||
|
||||
bus.post(new EndOfStreamMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.serializer.SerializerTXT#run()}.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Test
|
||||
public void testRunTXT() throws InterruptedException {
|
||||
SerializerTXT serializer = new SerializerTXT(new File(tmpDirectory+"/test.txt"), true);
|
||||
bus.register(serializer);
|
||||
generate1DData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.serializer.SerializerTXT#run()}.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Test
|
||||
public void testRunMAT() throws InterruptedException {
|
||||
|
||||
SerializerMAT serializer = new SerializerMAT(new File(tmpDirectory+"/test.mat"));
|
||||
bus.register(serializer);
|
||||
generate1DData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.serializer.SerializerTXT#run()}.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Test
|
||||
public void testRunMAT2D() throws InterruptedException {
|
||||
SerializerMAT2D serializer = new SerializerMAT2D(new File(tmpDirectory+"/test-2d.mat"));
|
||||
bus.register(serializer);
|
||||
generate2DData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.serializer.SerializerTXT#run()}.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Test
|
||||
public void testRunTXT2D() throws InterruptedException {
|
||||
SerializerTXT2D serializer = new SerializerTXT2D(new File(tmpDirectory+"/test-2d.txt"));
|
||||
bus.register(serializer);
|
||||
generate2DData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.serializer.SerializerTXT#run()}.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Test
|
||||
public void testRunSplitTXT() throws InterruptedException {
|
||||
SerializerTXTSplit serializer = new SerializerTXTSplit(new File(tmpDirectory+"/test-2d-split.txt"));
|
||||
bus.register(serializer);
|
||||
generate2DData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.serializer.SerializerMDA#run()}.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Test
|
||||
public void testRun2D() throws InterruptedException {
|
||||
SerializerMDA serializer = new SerializerMDA(new File(tmpDirectory+"/test-2d.mda"));
|
||||
bus.register(serializer);
|
||||
generate2DData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.serializer.SerializerMDA#run()}.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Test
|
||||
public void testRun3D() throws InterruptedException {
|
||||
SerializerMDA serializer = new SerializerMDA(new File(tmpDirectory+"/test-3d.mda"));
|
||||
bus.register(serializer);
|
||||
generate3DData();
|
||||
}
|
||||
}
|
||||
38
src/test/java/ch/psi/fda/ui/AcquisitionMainTest.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2011 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but without any
|
||||
* warranty; without even the implied warranty of merchantability or fitness for
|
||||
* a particular purpose. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package ch.psi.fda.ui;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import ch.psi.fda.ui.AcquisitionMain;
|
||||
|
||||
public class AcquisitionMainTest {
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.ui.AcquisitionMain#main(java.lang.String[])}.
|
||||
*/
|
||||
@Ignore
|
||||
@Test
|
||||
public void testMain() {
|
||||
System.setProperty("ch.psi.fda.home","src/test/resources/home");
|
||||
AcquisitionMain.main(new String[]{"src/test/resources/home/scans/templates/scan1d-waitError.xml"});
|
||||
}
|
||||
|
||||
}
|
||||
41
src/test/java/ch/psi/fda/ui/ApplicationConfiguratorTest.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import ch.psi.fda.ui.ApplicationConfigurator;
|
||||
|
||||
public class ApplicationConfiguratorTest {
|
||||
|
||||
private ApplicationConfigurator configurator;
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testInitializeApplication() throws IOException{
|
||||
System.setProperty(ApplicationConfigurator.FDA_HOME_ARGUMENT, "target/tmp/home");
|
||||
configurator = new ApplicationConfigurator();
|
||||
configurator.initializeApplication();
|
||||
}
|
||||
|
||||
}
|
||||
122
src/test/java/ch/psi/fda/ui/VisualizationMainTest.java
Normal file
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import ch.psi.fda.ui.VisualizationMain;
|
||||
|
||||
/**
|
||||
* Testcase for visualization engine
|
||||
*/
|
||||
public class VisualizationMainTest {
|
||||
|
||||
private VisualizationMain engine;
|
||||
private String configurationFile;
|
||||
private String dataFile;
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
URL url = this.getClass().getClassLoader().getResource("testdata/scan/scan1d.xml");
|
||||
configurationFile = new File(new URI(url.toString())).getAbsolutePath();
|
||||
|
||||
url = this.getClass().getClassLoader().getResource("testdata/scan/scan1d_0000.txt");
|
||||
dataFile = new File(new URI(url.toString())).getAbsolutePath();
|
||||
|
||||
engine = new VisualizationMain();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.ui.VisualizationMain#visualize(java.io.File, java.io.File)}.
|
||||
* Test whether a null data parameter is handled correctly
|
||||
* @throws InterruptedException
|
||||
* @throws SAXException
|
||||
* @throws JAXBException
|
||||
*/
|
||||
@Test(expected=RuntimeException.class)
|
||||
public void testVisualizeFileFileDataNull() throws InterruptedException {
|
||||
engine.visualize(new File(configurationFile), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.ui.VisualizationMain#visualize(java.io.File, java.io.File)}.
|
||||
* Test whether a non existing data file is handled correctly
|
||||
* @throws InterruptedException
|
||||
* @throws SAXException
|
||||
* @throws JAXBException
|
||||
*/
|
||||
@Test(expected=RuntimeException.class)
|
||||
public void testVisualizeFileFileDataNoExist() throws InterruptedException {
|
||||
engine.visualize(new File(configurationFile), new File(""));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.ui.VisualizationMain#visualize(java.io.File, java.io.File)}.
|
||||
* Check whether null configuration file is handled correctly
|
||||
* @throws InterruptedException
|
||||
* @throws SAXException
|
||||
* @throws JAXBException
|
||||
*/
|
||||
@Test(expected=RuntimeException.class)
|
||||
public void testVisualizeFileFileConfigNull() throws InterruptedException {
|
||||
engine.visualize(new File(""), new File(dataFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.ui.VisualizationMain#visualize(java.io.File, java.io.File)}.
|
||||
* Test correct visualization
|
||||
* @throws InterruptedException
|
||||
* @throws SAXException
|
||||
* @throws JAXBException
|
||||
*/
|
||||
@Test
|
||||
public void testVisualizeFileFile() throws InterruptedException {
|
||||
engine.visualize(new File(configurationFile), new File(dataFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether main can automatically determine the configuration file for a given data file
|
||||
* Test method for {@link ch.psi.fda.ui.VisualizationMain#main(String[])}
|
||||
*/
|
||||
@Test
|
||||
public void testMain(){
|
||||
// ATTENTION - This test will never fail because possible exceptions are caught in the main method !!!!
|
||||
VisualizationMain.main(new String[]{dataFile});
|
||||
}
|
||||
}
|
||||
222
src/test/java/ch/psi/fda/ui/visualizer/DataVisualizerTest.java
Normal file
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but without any
|
||||
* warranty; without even the implied warranty of merchantability or fitness for
|
||||
* a particular purpose. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.fda.ui.visualizer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.messages.Metadata;
|
||||
import ch.psi.fda.messages.StreamDelimiterMessage;
|
||||
import ch.psi.fda.ui.visualizer.Visualizer;
|
||||
import ch.psi.fda.vdescriptor.VDescriptor;
|
||||
import ch.psi.fda.vdescriptor.XYSeries;
|
||||
import ch.psi.fda.vdescriptor.XYZSeries;
|
||||
import ch.psi.fda.vdescriptor.YSeries;
|
||||
|
||||
/**
|
||||
* All test cases in this test class are meant to be executed manually Remove @Ignore
|
||||
* in front of the test function to be able to run it.
|
||||
*/
|
||||
public class DataVisualizerTest {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(DataVisualizerTest.class.getName());
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testRun() throws InterruptedException {
|
||||
List<Metadata> metadata = new ArrayList<>();
|
||||
metadata.add(new Metadata("id1"));
|
||||
metadata.add(new Metadata("id2"));
|
||||
metadata.add(new Metadata("id3"));
|
||||
|
||||
EventBus bus = new EventBus();
|
||||
|
||||
VDescriptor vdescriptor = new VDescriptor();
|
||||
|
||||
ch.psi.fda.vdescriptor.LinePlot plot = new ch.psi.fda.vdescriptor.LinePlot("One");
|
||||
plot.getData().add(new XYSeries("id1", "id2"));
|
||||
vdescriptor.getPlots().add(plot);
|
||||
|
||||
plot = new ch.psi.fda.vdescriptor.LinePlot("Two");
|
||||
plot.getData().add(new XYSeries("id1", "id3"));
|
||||
vdescriptor.getPlots().add(plot);
|
||||
|
||||
// Create visualizer
|
||||
Visualizer visualizer = new Visualizer(vdescriptor);
|
||||
bus.register(visualizer);
|
||||
|
||||
JFrame f = new JFrame();
|
||||
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
f.setSize(600, 400);
|
||||
JPanel pan = new JPanel();
|
||||
for (JPanel pp : visualizer.getPlotPanels()) {
|
||||
pan.add(pp);
|
||||
}
|
||||
f.add(pan);
|
||||
f.setVisible(true);
|
||||
|
||||
DataMessage m;
|
||||
for (double t = 0; t < 4; t++) {
|
||||
for (double i = 0; i < 100; i = i + 0.1) {
|
||||
m = new DataMessage(metadata);
|
||||
m.getData().add(i);
|
||||
m.getData().add(t + Math.sin(i));
|
||||
m.getData().add(t + Math.cos(i));
|
||||
bus.post(m);
|
||||
|
||||
Thread.sleep(5);
|
||||
}
|
||||
bus.post(new StreamDelimiterMessage(0));
|
||||
}
|
||||
|
||||
bus.post(new EndOfStreamMessage());
|
||||
|
||||
Thread.sleep(10000);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testRunArray() throws InterruptedException {
|
||||
|
||||
List<Metadata> metadata = new ArrayList<>();
|
||||
metadata.add(new Metadata("id1"));
|
||||
|
||||
EventBus bus = new EventBus();
|
||||
|
||||
VDescriptor vdescriptor = new VDescriptor();
|
||||
|
||||
ch.psi.fda.vdescriptor.LinePlot plot = new ch.psi.fda.vdescriptor.LinePlot("One");
|
||||
plot.getData().add(new YSeries("id1"));
|
||||
vdescriptor.getPlots().add(plot);
|
||||
|
||||
// Create visualizer
|
||||
Visualizer visualizer = new Visualizer(vdescriptor);
|
||||
bus.register(visualizer);
|
||||
|
||||
JFrame f = new JFrame();
|
||||
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
f.setSize(600, 400);
|
||||
JPanel pan = new JPanel();
|
||||
for (JPanel pp : visualizer.getPlotPanels()) {
|
||||
pan.add(pp);
|
||||
}
|
||||
f.add(pan);
|
||||
f.setVisible(true);
|
||||
|
||||
DataMessage m;
|
||||
int npoints = 10000;
|
||||
for (double t = 0; t < 10; t++) {
|
||||
double[] values = new double[npoints];
|
||||
|
||||
for (int i = 0; i < npoints; i++) {
|
||||
values[i] = Math.sin(i * 0.01) + Math.cos(t);
|
||||
}
|
||||
|
||||
m = new DataMessage(metadata);
|
||||
m.getData().add(values);
|
||||
bus.post(m);
|
||||
|
||||
Thread.sleep(500);
|
||||
}
|
||||
bus.post(new StreamDelimiterMessage(0));
|
||||
bus.post(new EndOfStreamMessage());
|
||||
|
||||
Thread.sleep(10000);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testRun2D() throws InterruptedException {
|
||||
|
||||
double nx = 1000;
|
||||
double ny = 1000;
|
||||
|
||||
List<Metadata> metadata = new ArrayList<>();
|
||||
metadata.add(new Metadata("id1"));
|
||||
metadata.add(new Metadata("id2"));
|
||||
metadata.add(new Metadata("id3"));
|
||||
|
||||
// EventBus bus = new AsyncEventBus(Executors.newFixedThreadPool(1));
|
||||
EventBus bus = new EventBus();
|
||||
|
||||
VDescriptor vdescriptor = new VDescriptor();
|
||||
|
||||
ch.psi.fda.vdescriptor.LinePlot lplot = new ch.psi.fda.vdescriptor.LinePlot("One");
|
||||
lplot.getData().add(new XYSeries("id2", "id3"));
|
||||
vdescriptor.getPlots().add(lplot);
|
||||
|
||||
ch.psi.fda.vdescriptor.MatrixPlot mplot = new ch.psi.fda.vdescriptor.MatrixPlot("One");
|
||||
mplot.setMinX(1.0);
|
||||
mplot.setMaxX(nx);
|
||||
mplot.setnX((int)nx);
|
||||
mplot.setMinY(1.0);
|
||||
mplot.setMaxY(ny);
|
||||
mplot.setnY((int)ny);
|
||||
mplot.getData().add(new XYZSeries("id1", "id2", "id3"));
|
||||
vdescriptor.getPlots().add(mplot);
|
||||
|
||||
// Create visualizer
|
||||
Visualizer visualizer = new Visualizer(vdescriptor);
|
||||
bus.register(visualizer);
|
||||
|
||||
JFrame f = new JFrame();
|
||||
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
f.setSize(600, 400);
|
||||
// f.add(plot.getPlotPanel());
|
||||
JPanel pan = new JPanel();
|
||||
for (JPanel pp : visualizer.getPlotPanels()) {
|
||||
pan.add(pp);
|
||||
}
|
||||
f.add(pan);
|
||||
f.setVisible(true);
|
||||
|
||||
DataMessage m;
|
||||
for (double t = 1; t <= nx; t++) {
|
||||
for (double i = 1; i <= ny; i++) {
|
||||
m = new DataMessage(metadata);
|
||||
m.getData().add(t);
|
||||
m.getData().add(i);
|
||||
m.getData().add(t + Math.cos(i));
|
||||
bus.post(m);
|
||||
|
||||
// Thread.sleep(5);
|
||||
}
|
||||
bus.post(new StreamDelimiterMessage(0));
|
||||
}
|
||||
|
||||
bus.post(new EndOfStreamMessage());
|
||||
|
||||
logger.info("Generation done");
|
||||
|
||||
Thread.sleep(100000);
|
||||
}
|
||||
|
||||
}
|
||||
4
src/test/resources/cdump.properties
Normal file
@@ -0,0 +1,4 @@
|
||||
ch.psi.fda.cdump.dataChannel=CDUMP:WAVE
|
||||
ch.psi.fda.cdump.controlChannel=CDUMP:CONTROL
|
||||
ch.psi.fda.cdump.samplingRateChannel=CDUMP:SAMPLING
|
||||
ch.psi.fda.cdump.nelements=4
|
||||
1
src/test/resources/fdaq.properties
Normal file
@@ -0,0 +1 @@
|
||||
ch.psi.fda.fdaq.hostname=localhost
|
||||
2
src/test/resources/home/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/data
|
||||
/logs
|
||||
0
src/test/resources/home/config/cdump.properties
Normal file
15
src/test/resources/home/config/fda.properties
Normal file
@@ -0,0 +1,15 @@
|
||||
# Serialization properties
|
||||
ch.psi.fda.aq.data.dir=../data
|
||||
ch.psi.fda.aq.data.filePrefix=${yyyy_MM}/${yyyyMMdd}/${yyyyMMddHHmmss}_${name}/${yyyyMMddHHmm}_
|
||||
|
||||
# OTF scan related configuration
|
||||
ch.psi.fda.aq.otf.channelPrefix=MTEST-HW3-OTFX
|
||||
ch.psi.fda.aq.otf.nfsServer=yoke.psi.ch
|
||||
ch.psi.fda.aq.otf.nfsShare=/usr/nfs
|
||||
ch.psi.fda.aq.otf.smbShare=smb://:@yoke.psi.ch/nfs/
|
||||
|
||||
ch.psi.fda.aq.otf.useCrlogic=true
|
||||
ch.psi.fda.aq.otf.crlogicPrefix=MTEST-HW3-CRL
|
||||
ch.psi.fda.aq.otf.scalerPrefix=MTEST-HW3:JS
|
||||
|
||||
ch.psi.fda.aq.notification.recipients=simon.ebner@psi.ch
|
||||
6
src/test/resources/home/config/jcae.properties
Normal file
@@ -0,0 +1,6 @@
|
||||
ch.psi.jcae.ContextFactory.addressList=129.129.130.188 129.129.130.255 129.129.130.37 129.129.145.26 129.129.130.88 129.129.130.142
|
||||
ch.psi.jcae.ChannelFactory.timeout=2000
|
||||
ch.psi.jcae.ChannelFactory.retries=4
|
||||
ch.psi.jcae.ChannelBeanFactory.timeout=10000
|
||||
ch.psi.jcae.ChannelBeanFactory.waitTimeout=3600000
|
||||
ch.psi.jcae.ChannelBeanFactory.retries=4
|
||||
14
src/test/resources/home/config/logging.properties
Normal file
@@ -0,0 +1,14 @@
|
||||
# Specify the handlers to create in the root logger
|
||||
handlers = java.util.logging.ConsoleHandler
|
||||
|
||||
# Set the default logging level for the root logger
|
||||
.level=INFO
|
||||
|
||||
# Set the default logging level for new ConsoleHandler instances
|
||||
java.util.logging.ConsoleHandler.level=ALL
|
||||
|
||||
# Set the default formatter for new ConsoleHandler instances
|
||||
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
|
||||
|
||||
# Set the default logging level for the logger named com.mycompany
|
||||
ch.psi.level=ALL
|
||||
97
src/test/resources/home/scans/templates/Co_EXAFS_GeD.xml
Normal file
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="1" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 http://www.psi.ch/~ebner/models/scan/1.0">
|
||||
<data format="txt"/>
|
||||
<scan id="">
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:START-CSMPL" value="0" delay="0.1" /> <!-- continuous=OFF -->
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-OP-MO1:KohzuModeBO.VAL" value="Auto" delay="0.1" />
|
||||
|
||||
<dimension>
|
||||
<!-- <positioner id="posX" name="X10DA-OP-MO1:BraggEAO" readback="X10DA-OP-MO1:BraggERdbkAO" settlingTime="0.4" xsi:type="RegionPositioner">
|
||||
-->
|
||||
<positioner id="posX" name="X10DA-OP-MO1:BraggEAO" readback="X10DA-OP-MO1:BraggERdbkAO" settlingTime="0.4" xsi:type="RegionPositioner">
|
||||
<!-- REGIONS -->
|
||||
<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="5" type="Integer" />
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:PresetReal" value="1" type="Integer" />
|
||||
<start>7.7</start>
|
||||
<end>7.71</end>
|
||||
<stepSize>0.005</stepSize>
|
||||
</region>
|
||||
<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="5" type="Integer" />
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:PresetReal" value="1" type="Integer" />
|
||||
<start>7.71</start>
|
||||
<end>7.732</end>
|
||||
<stepSize>0.001</stepSize>
|
||||
</region>
|
||||
<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="5" type="Integer" />
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:PresetReal" value="1" type="Integer" />
|
||||
<start>7.732</start>
|
||||
<end>7.75</end>
|
||||
<stepSize>0.0005</stepSize>
|
||||
</region>
|
||||
<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="5" type="Integer" />
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:PresetReal" value="1" type="Integer" />
|
||||
<start>7.75</start>
|
||||
<end>7.8</end>
|
||||
<stepSize>0.001</stepSize>
|
||||
</region>
|
||||
<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="10" type="Integer" />
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:PresetReal" value="2" type="Integer" />
|
||||
<start>7.8</start>
|
||||
<end>7.9</end>
|
||||
<stepSize>0.0015</stepSize>
|
||||
</region>
|
||||
<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="15" type="Integer" />
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:PresetReal" value="3" type="Integer" />
|
||||
<start>7.9</start>
|
||||
<end>8.0</end>
|
||||
<stepSize>0.002</stepSize>
|
||||
</region>
|
||||
<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="20" type="Integer" />
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:PresetReal" value="4" type="Integer" />
|
||||
<start>8.0</start>
|
||||
<end>8.1</end>
|
||||
<stepSize>0.0025</stepSize>
|
||||
</region>
|
||||
<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="20" type="Integer" />
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:PresetReal" value="4" type="Integer" />
|
||||
<start>8.1</start>
|
||||
<end>8.2</end>
|
||||
<stepSize>0.003</stepSize>
|
||||
</region>
|
||||
|
||||
</positioner>
|
||||
<detector id="SAI01-MEAN" xsi:type="ScalarDetector" name="X10DA-ES1-SAI_01:MEAN"/>
|
||||
<detector id="SAI02-MEAN" xsi:type="ScalarDetector" name="X10DA-ES1-SAI_02:MEAN"/>
|
||||
<detector id="SAI03-MEAN" xsi:type="ScalarDetector" name="X10DA-ES1-SAI_03:MEAN"/>
|
||||
|
||||
<detector id="Ring-current" xsi:type="ScalarDetector" name="ARIDI-PCT:CURRENT"/>
|
||||
|
||||
<detector id="IntegrTimeSet" xsi:type="ScalarDetector" name="X10DA-ES1:TOTAL-CYCLES"/>
|
||||
<detector id="IntegrTimeGet" xsi:type="ScalarDetector" name="X10DA-ES1:INTR-COUNT"/>
|
||||
<detector id="Timestamp" xsi:type="Timestamp"/>
|
||||
|
||||
|
||||
<detector id="GeD_avg_corr" xsi:type="ScalarDetector" name="X10DA-GeD:CNT_Average">
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:EraseStart" value="1" delay="0.1" operation="putq"/>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:Acquiring" value="Acquiring" operation="wait"/>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:SMPL" value="1" delay="0.1"/>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:SMPL-DONE" type="Integer" value="1" delay="0.3" operation="wait"/>
|
||||
<!--<preAction xsi:type="ChannelAction" channel="X10DA-GeD:StopAll" value="1" delay="0.1" /> -->
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:Acquiring" value="Done" operation="wait"/>
|
||||
</detector>
|
||||
|
||||
</dimension>
|
||||
</scan>
|
||||
<visualization xsi:type="LinePlot" x="posX" y="SAI01-MEAN" title="SAI01-MEAN" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="SAI02-MEAN" title="SAI02-MEAN" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="SAI03-MEAN" title="SAI03-MEAN" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="GeD_avg_corr" title="Ge detector" />
|
||||
</configuration>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<configuration xmlns="http://www.psi.ch/~ebner/models/scan/1.0" numberOfExecution="1" failOnSensorError="true">
|
||||
<data format="txt" fileName="FDA_OTF_calc_test1_extMot"/>
|
||||
<scan>
|
||||
<preAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ChannelAction" channel="X10DA-TEST1-TMP-SC.CNT" value="0" operation="put" delay="0.1"/>
|
||||
<preAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ChannelAction" channel="X10DA-TEST1-TMP-SC.G1" value="0" operation="put" delay="0.1"/>
|
||||
<preAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ChannelAction" channel="X10DA-TEST1-TMP-SC.CONT" value="0" operation="put" delay="0.1"/>
|
||||
<cdimension>
|
||||
<positioner name="X10DA-ES2-PP2:MOT1" readback="X10DA-TEST1-TMP:EC1" id="id0">
|
||||
<start>0.0</start>
|
||||
<end>0.5</end>
|
||||
<stepSize>0.0020</stepSize>
|
||||
<integrationTime>0.05</integrationTime>
|
||||
</positioner>
|
||||
<detector name="X10DA-TEST1-TMP:EC1" id="Encoder"/>
|
||||
<detector name="X10DA-TEST1-OTFX:FCNT" id="line"/>
|
||||
<detector name="X10DA-TST-SAI_01:MEAN" id="SAI01-MEAN"/>
|
||||
<detector name="X10DA-TST-SAI_02:MEAN" id="SAI02-MEAN"/>
|
||||
<detector name="X10DA-TST-SAI_03:MEAN" id="SAI03-MEAN"/>
|
||||
<detector name="ARIDI-PCT:CURRENT" id="Ring-current"/>
|
||||
<detector name="X10DA-VME-TEST1:LOAD" id="VMELoad"/>
|
||||
<detector name="X10DA-TST:INTR-COUNT" id="IntegrTimeGet"/>
|
||||
<!--<detector name="X10DA-TEST1-OMS:MOT8.SPMG" id="id758511"/>-->
|
||||
<scaler channel="0" id="id01"/>
|
||||
<scaler channel="1" id="id02"/>
|
||||
<timestamp id="Timestamp"/>
|
||||
</cdimension>
|
||||
<dimension zigzag="false">
|
||||
<positioner xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="PseudoPositioner" id="id1">
|
||||
<counts>10</counts>
|
||||
</positioner>
|
||||
<guard>
|
||||
<condition channel="X10DA-TEST1-OMS:MOT8.SPMG" value="Go" type="Integer"/>
|
||||
</guard>
|
||||
</dimension>
|
||||
<manipulation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScriptManipulation" id="idM1">
|
||||
<mapping xsi:type="IDParameterMapping" refid="id0" variable="a"/>
|
||||
<mapping xsi:type="IDParameterMapping" refid="Encoder" variable="b"/>
|
||||
<script>
|
||||
import math
|
||||
def process(a,b):
|
||||
return a + b
|
||||
</script>
|
||||
</manipulation>
|
||||
<manipulation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScriptManipulation" id="idM2">
|
||||
<mapping xsi:type="IDParameterMapping" refid="Timestamp" variable="c"/>
|
||||
<script>
|
||||
import math
|
||||
before=0.0
|
||||
first = True
|
||||
def process(c):
|
||||
global before
|
||||
global first
|
||||
if first:
|
||||
first=False
|
||||
before=c
|
||||
ret=0.0
|
||||
else:
|
||||
ret = c-before
|
||||
return ret / 1000
|
||||
</script>
|
||||
</manipulation>
|
||||
</scan>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="Encoder" title="Encoder"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="idM1" title="Encoder-error"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="id01" title="Ref-scaler"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="MatrixPlot" x="id0" y="id1" z="idM1" title="Encoder-error"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="MatrixPlot" x="id0" y="id1" z="line" title="count-nr"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="idM2" title="Time-sec"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="VMELoad" title="VMELoad"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="MatrixPlot" x="id0" y="id1" z="id01" title="Reference"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="Ring-current" title=" ringcurrent"/>
|
||||
<!--<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="id758511" title=" guard"/>-->
|
||||
</configuration>
|
||||
156
src/test/resources/home/scans/templates/StopGo_X10DA-DCM_Fl.xml
Normal file
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="0" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 http://www.psi.ch/~ebner/models/scan/1.0">
|
||||
<data format="txt"/>
|
||||
<scan id="">
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:START-CSMPL" value="0" delay="0.1" /> <!-- continuous=OFF -->
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:StopAll" value="0" delay="0.1" /> <!-- preset = 0, acquisition time defined by simultan -->
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:PresetReal" value="0" delay="0.1" />
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-OP-MO1:KohzuModeBO.VAL" value="Auto" delay="0.1" />
|
||||
|
||||
<dimension>
|
||||
<positioner id="posX" name="X10DA-OP-MO1:BraggEAO" readback="X10DA-OP-MO1:BraggERdbkAO" settlingTime="0.4" xsi:type="RegionPositioner">
|
||||
<!--<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="5" type="Integer" />
|
||||
<start> 8.89 </start>
|
||||
<end> 8.9300 </end>
|
||||
<stepSize> 0.005 </stepSize>
|
||||
</region>
|
||||
<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="5" type="Integer" />
|
||||
<start> 8.9300 </start>
|
||||
<end> 8.9700 </end>
|
||||
<stepSize> 0.001 </stepSize>
|
||||
</region> -->
|
||||
<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="10" type="Integer" />
|
||||
<start> 8.97 </start>
|
||||
<end> 9.000 </end>
|
||||
<stepSize> 0.0005 </stepSize>
|
||||
</region>
|
||||
<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="10" type="Integer" />
|
||||
<start> 9.000 </start>
|
||||
<end> 9.170 </end>
|
||||
<stepSize> 0.001 </stepSize>
|
||||
</region>
|
||||
<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="15" type="Integer" />
|
||||
<start> 9.170 </start>
|
||||
<end> 9.320 </end>
|
||||
<stepSize> 0.002 </stepSize>
|
||||
</region>
|
||||
<region>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:TOTAL-CYCLES" value="20" type="Integer" />
|
||||
<start> 9.320 </start>
|
||||
<end> 9.690 </end>
|
||||
<stepSize> 0.003 </stepSize>
|
||||
</region>
|
||||
|
||||
</positioner>
|
||||
|
||||
<detector id="SAI01-MEAN" xsi:type="ScalarDetector" name="X10DA-ES1-SAI_01:MEAN"/>
|
||||
<detector id="SAI02-MEAN" xsi:type="ScalarDetector" name="X10DA-ES1-SAI_02:MEAN"/>
|
||||
<detector id="SAI03-MEAN" xsi:type="ScalarDetector" name="X10DA-ES1-SAI_03:MEAN"/>
|
||||
|
||||
<detector id="mca1.R0" xsi:type="ScalarDetector" name="X10DA-GeD:mca1.R0"/>
|
||||
<detector id="R1_Fast_peaks" xsi:type="ScalarDetector" name="X10DA-GeD:dxp1.FAST_PEAKS"/>
|
||||
<detector id="R1_Slow_peaks" xsi:type="ScalarDetector" name="X10DA-GeD:dxp1.SLOW_PEAKS"/>
|
||||
<detector id="R1_ELTM" xsi:type="ScalarDetector" name="X10DA-GeD:mca1.ELTM"/>
|
||||
<detector id="GeD_elapsed_real" xsi:type="ScalarDetector" name="X10DA-GeD:ElapsedReal"/>
|
||||
<detector id="GeD_elapsed_live" xsi:type="ScalarDetector" name="X10DA-GeD:ElapsedLive"/>
|
||||
|
||||
<detector id="GeD_corrected_1" xsi:type="ScalarDetector" name="X10DA-GeD:CNT1"/>
|
||||
<detector id="GeD_corrected_2" xsi:type="ScalarDetector" name="X10DA-GeD:CNT2"/>
|
||||
<detector id="GeD_corrected_3" xsi:type="ScalarDetector" name="X10DA-GeD:CNT3"/>
|
||||
<detector id="GeD_corrected_4" xsi:type="ScalarDetector" name="X10DA-GeD:CNT4"/>
|
||||
<detector id="GeD_corrected_5" xsi:type="ScalarDetector" name="X10DA-GeD:CNT5"/>
|
||||
<detector id="GeD_corrected_6" xsi:type="ScalarDetector" name="X10DA-GeD:CNT6"/>
|
||||
<detector id="GeD_corrected_7" xsi:type="ScalarDetector" name="X10DA-GeD:CNT7"/>
|
||||
<detector id="GeD_corrected_8" xsi:type="ScalarDetector" name="X10DA-GeD:CNT8"/>
|
||||
<detector id="GeD_corrected_9" xsi:type="ScalarDetector" name="X10DA-GeD:CNT9"/>
|
||||
<detector id="GeD_corrected_10" xsi:type="ScalarDetector" name="X10DA-GeD:CNT10"/>
|
||||
<detector id="GeD_corrected_11" xsi:type="ScalarDetector" name="X10DA-GeD:CNT11"/>
|
||||
<detector id="GeD_corrected_12" xsi:type="ScalarDetector" name="X10DA-GeD:CNT12"/>
|
||||
<detector id="sample_count" xsi:type="ScalarDetector" name="X10DA-ES1:INTR-COUNT"/>
|
||||
<detector id="GeD_corrected_avg" xsi:type="ScalarDetector" name="X10DA-GeD:CNT_Average"/>
|
||||
|
||||
<detector id="energyRB" xsi:type="ScalarDetector" name="X10DA-OP-MO1:BraggERdbkAO"/>
|
||||
<!--<detector id="Ring-current" xsi:type="ScalarDetector" name="ARIDI-PCT:CURRENT"/>-->
|
||||
<detector id="IntegrTimeSet" xsi:type="ScalarDetector" name="X10DA-ES1:TOTAL-CYCLES"/>
|
||||
<detector id="IntegrTimeGet" xsi:type="ScalarDetector" name="X10DA-ES1:INTR-COUNT"/>
|
||||
<detector id="Timestamp" xsi:type="Timestamp"/>
|
||||
|
||||
|
||||
<detector id="ElapsedRT" xsi:type="ScalarDetector" name="X10DA-GeD:mca1.ERTM">
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:EraseStart" value="1" delay="0.1" operation="putq"/> <!-- was putq -->
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:Acquiring" value="Acquiring" operation="wait"/>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:SMPL" value="1" delay="0.1"/>
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-ES1:SMPL-DONE" type="Integer" value="1" delay="0.2" operation="wait"/>
|
||||
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:StopAll" value="1" delay="0.1" />
|
||||
<!--<preAction xsi:type="ChannelAction" channel="X10DA-ES1:SMPL" value="0" /> -->
|
||||
<preAction xsi:type="ChannelAction" channel="X10DA-GeD:Acquiring" value="Done" operation="wait"/>
|
||||
</detector>
|
||||
|
||||
</dimension>
|
||||
|
||||
<manipulation id="idM_IF" xsi:type="ScriptManipulation">
|
||||
<mapping xsi:type="IDParameterMapping" variable="a" refid="SAI01-MEAN"/>
|
||||
<mapping xsi:type="IDParameterMapping" variable="b" refid="GeD_corrected_avg"/>
|
||||
<script>
|
||||
import math
|
||||
def process(a,b):
|
||||
return (b / a)
|
||||
</script>
|
||||
</manipulation>
|
||||
|
||||
<manipulation id="idM_It" xsi:type="ScriptManipulation">
|
||||
<mapping xsi:type="IDParameterMapping" variable="c" refid="SAI01-MEAN"/>
|
||||
<mapping xsi:type="IDParameterMapping" variable="d" refid="SAI02-MEAN"/>
|
||||
<script>
|
||||
import math
|
||||
def process(c,d):
|
||||
return math.log(c / d)
|
||||
</script>
|
||||
</manipulation>
|
||||
|
||||
<manipulation id="idM_C1_dtc" xsi:type="ScriptManipulation">
|
||||
<mapping xsi:type="IDParameterMapping" variable="e" refid="mca1.R0"/>
|
||||
<mapping xsi:type="IDParameterMapping" variable="f" refid="R1_Fast_peaks"/>
|
||||
<mapping xsi:type="IDParameterMapping" variable="g" refid="R1_Slow_peaks"/>
|
||||
<mapping xsi:type="IDParameterMapping" variable="h" refid="R1_ELTM"/>
|
||||
<script>
|
||||
import math
|
||||
def process(e,f,g,h):
|
||||
return (e / h / g * f)
|
||||
</script>
|
||||
</manipulation>
|
||||
|
||||
</scan>
|
||||
<!--<visualization xsi:type="LinePlot" x="posX" y="FAST_PEAKS" title="FAST_PEAKS" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="SLOW_PEAKS" title="SLOW_PEAKS" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="ICR" title="ICR" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="OCR" title="OCR" />-->
|
||||
|
||||
<visualization xsi:type="LinePlot" x="posX" y="idM_IF" title="If_calculated" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="GeD_corrected_avg" title="GeD_corrected_avg" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="mca1.R0" title="mca1.R0" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="R1_Fast_peaks" title="R1_Fast_peaks" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="R1_Slow_peaks" title="R1_Slow_peaks" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="GeD_elapsed_real" title="GeD_elapsed_real" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="GeD_elapsed_live" title="GeD_elapsed_live" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="idM_C1_dtc" title="GeD_C1_deadtimecorrected" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="sample_count" title="actual sample count" />
|
||||
<!--<visualization xsi:type="LinePlot" x="posX" y="idM_It" title="It_calculated" />
|
||||
|
||||
<visualization xsi:type="LinePlot" x="posX" y="energyRB" title="Energy Readback" />
|
||||
|
||||
<visualization xsi:type="LinePlot" x="posX" y="ElapsedRT" title="ElapsedRT" />
|
||||
|
||||
<visualization xsi:type="LinePlot" x="posX" y="SAI01-MEAN" title="SAI01-MEAN" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="SAI02-MEAN" title="SAI02-MEAN" />
|
||||
<visualization xsi:type="LinePlot" x="posX" y="SAI03-MEAN" title="SAI03-MEAN" /> -->
|
||||
<!--<visualization xsi:type="LinePlot" x="posX" y="Ring-current" title="Ring-current" /> -->
|
||||
<visualization xsi:type="LinePlot" x="posX" y="Timestamp" title="Timestamp" />
|
||||
|
||||
</configuration>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<configuration xmlns="http://www.psi.ch/~ebner/models/scan/1.0" numberOfExecution="1" failOnSensorError="true">
|
||||
<data format="txt" fileName="TestXY__OTF_2D_v01_small-map"/>
|
||||
<scan>
|
||||
<cdimension dataGroup="false">
|
||||
<positioner name="X10DA-TEST1-OMS:MOT8" id="id0">
|
||||
<start>-1.0</start>
|
||||
<end>1.0</end>
|
||||
<stepSize>0.01</stepSize>
|
||||
<integrationTime>0.0050</integrationTime>
|
||||
</positioner>
|
||||
<detector name="X10DA-TEST1-TMP:ai07" id="Diode"/>
|
||||
<scaler channel="0" id="diodeS"/>
|
||||
<scaler channel="11" id="refS"/>
|
||||
<timestamp id="timestamp"/>
|
||||
</cdimension>
|
||||
<dimension zigzag="false" dataGroup="false">
|
||||
<positioner xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinearPositioner" name="X10DA-TEST1-OMS:MOT7" id="scanY">
|
||||
<start>-1.0</start>
|
||||
<end>1.0</end>
|
||||
<stepSize>0.25</stepSize>
|
||||
</positioner>
|
||||
</dimension>
|
||||
</scan>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="MatrixPlot" x="id0" y="scanY" z="Diode" title=" Diode"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="Diode" title=" Diode"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="diodeS" title=" Diode Scaler"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="refS" title=" Reference Scaler"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="timestamp" y="diodeS" title=" Diode Scaler f (t)"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="timestamp" y="refS" title=" Ref Scaler f (t)"/>
|
||||
</configuration>
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="0" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 ../../../src/model-v1.xsd">
|
||||
<data format="txt" />
|
||||
<scan id="">
|
||||
|
||||
<!-- Ensure that scaler is configured the correct way -->
|
||||
<preAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.CONT" value="OneShot" operation="putq"/> <!-- Mode -->
|
||||
<preAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.G1" value="0" /> <!-- Gate -->
|
||||
<preAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.PR1" value="0" /> <!-- Preset Count -->
|
||||
|
||||
<cdimension zigzag="false">
|
||||
|
||||
<!-- start scaler -->
|
||||
<preAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.CNT" value="Count" operation="putq" />
|
||||
|
||||
<positioner id="id0" name="MTEST-HW3:MOT1" xsi:type="ContinuousPositioner">
|
||||
<start>0.0</start>
|
||||
<end>2.0</end>
|
||||
<stepSize>0.01</stepSize>
|
||||
<integrationTime>0.01</integrationTime>
|
||||
</positioner>
|
||||
<detector id="idD0" xsi:type="SimpleScalarDetector" name="TRIGGER0" />
|
||||
<detector id="idD1" xsi:type="SimpleScalarDetector" name="TRIGGER1" />
|
||||
<!-- <detector id="jsChannel2" xsi:type="SimpleScalarDetector" name="MTEST-HW3:JS.S2"/> -->
|
||||
|
||||
<scaler id="scaler0" channel="0" />
|
||||
<scaler id="scaler1" channel="1" />
|
||||
<!-- <scaler id="scaler2" channel="2"/> -->
|
||||
<timestamp id="test" />
|
||||
|
||||
<!-- stop scaler -->
|
||||
<postAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.CNT" value="Done" />
|
||||
</cdimension>
|
||||
|
||||
|
||||
</scan>
|
||||
|
||||
<visualization title="Scaler 0" xsi:type="LinePlot" x="id0" y="scaler0" />
|
||||
<visualization title="Scaler 1" xsi:type="LinePlot" x="id0" y="scaler1" />
|
||||
<visualization title="Trigger Count 1" xsi:type="LinePlot" x="id0" y="idD0"/>
|
||||
<visualization title="Trigger Count 2" xsi:type="LinePlot" x="id0" y="idD1"/>
|
||||
<visualization xsi:type="LinePlot" x="id0" y="test" title="Timestamp" />
|
||||
</configuration>
|
||||
41
src/test/resources/home/scans/templates/cscan1d-crlogic.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="0" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 ../../../src/model-v1.xsd">
|
||||
<data format="txt" />
|
||||
<scan id="">
|
||||
|
||||
<!-- Ensure that scaler is configured the correct way -->
|
||||
<preAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.CONT" value="OneShot" operation="putq"/> <!-- Mode -->
|
||||
<preAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.G1" value="0" /> <!-- Gate -->
|
||||
<preAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.PR1" value="0" /> <!-- Preset Count -->
|
||||
|
||||
<cdimension zigzag="false">
|
||||
|
||||
<!-- start scaler -->
|
||||
<preAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.CNT" value="Count" operation="putq" />
|
||||
|
||||
<positioner id="id0" name="MTEST-HW3:MOT1" xsi:type="ContinuousPositioner">
|
||||
<start>0.0</start>
|
||||
<end>2.0</end>
|
||||
<stepSize>0.01</stepSize>
|
||||
<integrationTime>0.01</integrationTime>
|
||||
</positioner>
|
||||
<detector id="idD0" xsi:type="SimpleScalarDetector" name="TRIGGER0" />
|
||||
<!-- <detector id="jsChannel2" xsi:type="SimpleScalarDetector" name="MTEST-HW3:JS.S2"/> -->
|
||||
|
||||
<scaler id="scaler0" channel="0" />
|
||||
<scaler id="scaler1" channel="1" />
|
||||
<!-- <scaler id="scaler2" channel="2"/> -->
|
||||
<timestamp id="test" />
|
||||
|
||||
<!-- stop scaler -->
|
||||
<postAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.CNT" value="Done" />
|
||||
</cdimension>
|
||||
|
||||
|
||||
</scan>
|
||||
|
||||
<visualization title="Scaler 0" xsi:type="LinePlot" x="id0" y="scaler0" />
|
||||
<visualization title="Scaler 1" xsi:type="LinePlot" x="id0" y="scaler1" />
|
||||
<visualization title="Trigger Count" xsi:type="LinePlot" x="id0" y="idD0"/>
|
||||
<visualization xsi:type="LinePlot" x="id0" y="test" title="Timestamp" />
|
||||
</configuration>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="1" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 ../../src/model-v1.xsd">
|
||||
<data format="txt"/>
|
||||
<scan id="">
|
||||
<preAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.G1" value="0"/>
|
||||
<cdimension zigzag="false">
|
||||
<positioner id="id0" name="MTEST-HW3:MOT1">
|
||||
<start>0.0</start>
|
||||
<end>8.0</end>
|
||||
<stepSize>0.5</stepSize>
|
||||
<integrationTime>0.5</integrationTime>
|
||||
</positioner>
|
||||
|
||||
<detector name="MTEST-HW3:MOT1.RBV" id="id00"/>
|
||||
<scaler id="idXX01" channel="0"/>
|
||||
<timestamp id="test"/>
|
||||
</cdimension>
|
||||
|
||||
<manipulation id="idM1" xsi:type="ScriptManipulation">
|
||||
<!-- <mapping xsi:type="IDParameterMapping" variable="a" refid="id0"/> -->
|
||||
<mapping xsi:type="IDParameterMapping" variable="b" refid="idXX01"/>
|
||||
<mapping xsi:type="IDParameterMapping" variable="c" refid="id00"/>
|
||||
<script>
|
||||
import math
|
||||
def process(b,c):
|
||||
print b
|
||||
return math.cos(c)
|
||||
</script>
|
||||
</manipulation>
|
||||
</scan>
|
||||
|
||||
<visualization title="Line Plot One" xsi:type="LinePlot" x="id0" y="idXX01"/>
|
||||
<visualization xsi:type="LinePlot" x="id0" y="test" title="Timestamp" />
|
||||
<visualization xsi:type="LinePlot" x="id0" y="idM1" title="Manipulation" />
|
||||
</configuration>
|
||||
27
src/test/resources/home/scans/templates/cscan1d-maxv.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="0" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 ../../src/model-v1.xsd">
|
||||
<data format="txt"/>
|
||||
<scan id="">
|
||||
<preAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.G1" value="0"/>
|
||||
<cdimension zigzag="false">
|
||||
<positioner id="id0" name="MTEST-HW3:MMOT1" xsi:type="ContinuousPositioner">
|
||||
<start>8.0</start>
|
||||
<end>14.0</end>
|
||||
<stepSize>0.5</stepSize>
|
||||
<integrationTime>0.5</integrationTime>
|
||||
</positioner>
|
||||
<detector id="idD0" xsi:type="SimpleScalarDetector" name="MTEST-HW3:MMOT1.RRBV"/>
|
||||
<detector id="jsChannel2" xsi:type="SimpleScalarDetector" name="MTEST-HW3:JS.S2"/>
|
||||
|
||||
<scaler id="scaler0" channel="0"/>
|
||||
<scaler id="scaler1" channel="1"/>
|
||||
<scaler id="scaler2" channel="2"/>
|
||||
<timestamp id="test"/>
|
||||
</cdimension>
|
||||
</scan>
|
||||
|
||||
<visualization title="Scaler 0" xsi:type="LinePlot" x="id0" y="scaler0"/>
|
||||
<visualization title="Scaler 1" xsi:type="LinePlot" x="id0" y="scaler1"/>
|
||||
<visualization title="Scaler 1 Count via CA" xsi:type="LinePlot" x="id0" y="jsChannel2"/>
|
||||
<visualization xsi:type="LinePlot" x="id0" y="test" title="Timestamp" />
|
||||
</configuration>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="0" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 ../../src/model-v1.xsd">
|
||||
<data format="txt"/>
|
||||
<scan id="">
|
||||
<preAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.G1" value="0"/>
|
||||
<cdimension zigzag="false">
|
||||
|
||||
<preAction xsi:type="ShellAction" command="echo 'This is a continuous dimension pre action'"/>
|
||||
|
||||
<positioner id="id0" name="MTEST-HW3:MOT1" xsi:type="ContinuousPositioner">
|
||||
<start>0.0</start>
|
||||
<end>8.0</end>
|
||||
<stepSize>0.5</stepSize>
|
||||
<integrationTime>0.5</integrationTime>
|
||||
</positioner>
|
||||
<detector id="idD0" xsi:type="SimpleScalarDetector" name="MTEST-HW3:MOT1.RRBV"/>
|
||||
|
||||
<scaler id="idXX01" channel="0"/>
|
||||
<timestamp id="test"/>
|
||||
|
||||
<postAction xsi:type="ShellAction" command="echo 'This is a continuous dimension post action'"/>
|
||||
</cdimension>
|
||||
</scan>
|
||||
|
||||
<visualization title="Line Plot One" xsi:type="LinePlot" x="id0" y="idXX01"/>
|
||||
<visualization xsi:type="LinePlot" x="id0" y="test" title="Timestamp" />
|
||||
</configuration>
|
||||
30
src/test/resources/home/scans/templates/cscan1d-scrlogic.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="0" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 ../../../src/model-v1.xsd">
|
||||
<data format="txt"/>
|
||||
<scan id="">
|
||||
<preAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.G1" value="0"/>
|
||||
<cdimension zigzag="false">
|
||||
<positioner id="id0" name="MTEST-HW3:MOT1" xsi:type="ContinuousPositioner">
|
||||
<start>0.0</start>
|
||||
<end>2.0</end>
|
||||
<stepSize>0.01</stepSize>
|
||||
<integrationTime>0.01</integrationTime>
|
||||
</positioner>
|
||||
<detector id="idD0" xsi:type="SimpleScalarDetector" name="TRIGGER0" />
|
||||
|
||||
<!-- NORMAL CHANNEL -->
|
||||
<detector id="idCD0" xsi:type="SimpleScalarDetector" name="MTEST-HW3:MOT1.RBV" scr="true"/>
|
||||
|
||||
<scaler id="scaler0" channel="0"/>
|
||||
<scaler id="scaler1" channel="1"/>
|
||||
<!-- <scaler id="scaler2" channel="2"/>-->
|
||||
<timestamp id="test"/>
|
||||
</cdimension>
|
||||
</scan>
|
||||
|
||||
<visualization title="Scaler 0" xsi:type="LinePlot" x="id0" y="scaler0"/>
|
||||
<visualization title="Scaler 1" xsi:type="LinePlot" x="id0" y="scaler1"/>
|
||||
<!-- <visualization title="Scaler 1 Count via CA" xsi:type="LinePlot" x="id0" y="jsChannel2"/>-->
|
||||
<visualization xsi:type="LinePlot" x="id0" y="test" title="Timestamp" />
|
||||
<visualization xsi:type="LinePlot" x="id0" y="idCD0" title="Readback Channel Access" />
|
||||
</configuration>
|
||||
27
src/test/resources/home/scans/templates/cscan1d.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="0" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 ../../src/model-v1.xsd">
|
||||
<data format="txt"/>
|
||||
<scan id="">
|
||||
<preAction xsi:type="ChannelAction" channel="MTEST-HW3:JS.G1" value="0"/>
|
||||
<cdimension zigzag="false">
|
||||
<positioner id="id0" name="MTEST-HW3:MOT1" xsi:type="ContinuousPositioner">
|
||||
<start>0.0</start>
|
||||
<end>8.0</end>
|
||||
<stepSize>0.5</stepSize>
|
||||
<integrationTime>0.5</integrationTime>
|
||||
</positioner>
|
||||
<detector id="idD0" xsi:type="SimpleScalarDetector" name="MTEST-HW3:MOT1.RRBV"/>
|
||||
<detector id="jsChannel2" xsi:type="SimpleScalarDetector" name="MTEST-HW3:JS.S2"/>
|
||||
|
||||
<scaler id="scaler0" channel="0"/>
|
||||
<scaler id="scaler1" channel="1"/>
|
||||
<scaler id="scaler2" channel="2"/>
|
||||
<timestamp id="test"/>
|
||||
</cdimension>
|
||||
</scan>
|
||||
|
||||
<visualization title="Scaler 0" xsi:type="LinePlot" x="id0" y="scaler0"/>
|
||||
<visualization title="Scaler 1" xsi:type="LinePlot" x="id0" y="scaler1"/>
|
||||
<visualization title="Scaler 1 Count via CA" xsi:type="LinePlot" x="id0" y="jsChannel2"/>
|
||||
<visualization xsi:type="LinePlot" x="id0" y="test" title="Timestamp" />
|
||||
</configuration>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<configuration xmlns="http://www.psi.ch/~ebner/models/scan/1.0" numberOfExecution="1">
|
||||
<data fileName="cscan2d-crlogic" format="txt"/>
|
||||
<scan id="">
|
||||
<preAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ChannelAction" operation="putq" value="OneShot" channel="MTEST-HW3:JS.CONT"/>
|
||||
<preAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ChannelAction" value="0" channel="MTEST-HW3:JS.G1"/>
|
||||
<preAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ChannelAction" value="0" channel="MTEST-HW3:JS.PR1"/>
|
||||
<cdimension zigzag="true">
|
||||
<preAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ChannelAction" operation="putq" value="Count" channel="MTEST-HW3:JS.CNT"/>
|
||||
<positioner name="MTEST-HW3:MOT1" id="id0">
|
||||
<start>0.0</start>
|
||||
<end>2.0</end>
|
||||
<stepSize>0.01</stepSize>
|
||||
<integrationTime>0.01</integrationTime>
|
||||
</positioner>
|
||||
<detector name="TRIGGER0" id="idD0"/>
|
||||
<detector scr="true" name="MTEST-HW3:MOT1.RBV" id="id500224"/>
|
||||
<scaler channel="0" id="scaler0"/>
|
||||
<scaler channel="1" id="scaler1"/>
|
||||
<timestamp id="test"/>
|
||||
<postAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ChannelAction" value="Done" channel="MTEST-HW3:JS.CNT"/>
|
||||
</cdimension>
|
||||
<dimension>
|
||||
<positioner xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="PseudoPositioner" id="p1">
|
||||
<counts>30</counts>
|
||||
</positioner>
|
||||
</dimension>
|
||||
</scan>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" y="scaler0" x="id0" title="Scaler 0"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" y="scaler1" x="id0" title="Scaler 1"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" y="test" x="id0" title="Timestamp"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" y="id500224" x="id0" title=" Readback"/>
|
||||
</configuration>
|
||||
31
src/test/resources/home/scans/templates/cscan2d-crlogic.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<configuration xmlns="http://www.psi.ch/~ebner/models/scan/1.0" numberOfExecution="1">
|
||||
<data format="txt" fileName="cscan2d-crlogic"/>
|
||||
<scan id="">
|
||||
<preAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ChannelAction" channel="MTEST-HW3:JS.CONT" value="OneShot" operation="putq"/>
|
||||
<preAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ChannelAction" channel="MTEST-HW3:JS.G1" value="0"/>
|
||||
<preAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ChannelAction" channel="MTEST-HW3:JS.PR1" value="0"/>
|
||||
<cdimension zigzag="true">
|
||||
<preAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ChannelAction" channel="MTEST-HW3:JS.CNT" value="Count" operation="putq"/>
|
||||
<positioner name="MTEST-HW3:MOT1" id="id0">
|
||||
<start>0.0</start>
|
||||
<end>2.0</end>
|
||||
<stepSize>0.01</stepSize>
|
||||
<integrationTime>0.01</integrationTime>
|
||||
</positioner>
|
||||
<detector name="TRIGGER0" id="idD0"/>
|
||||
<scaler channel="0" id="scaler0"/>
|
||||
<scaler channel="1" id="scaler1"/>
|
||||
<timestamp id="test"/>
|
||||
<postAction xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ChannelAction" channel="MTEST-HW3:JS.CNT" value="Done"/>
|
||||
</cdimension>
|
||||
<dimension>
|
||||
<positioner xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="PseudoPositioner" id="p1">
|
||||
<counts>30</counts>
|
||||
</positioner>
|
||||
</dimension>
|
||||
</scan>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="scaler0" title="Scaler 0"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="scaler1" title="Scaler 1"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="test" title="Timestamp"/>
|
||||
</configuration>
|
||||
27
src/test/resources/home/scans/templates/cscan2d-zigzag.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<configuration xmlns="http://www.psi.ch/~ebner/models/scan/1.0" numberOfExecution="1">
|
||||
<data format="txt" fileName="cscan2d-zigzag"/>
|
||||
<scan id="">
|
||||
<cdimension zigzag="true">
|
||||
<positioner name="MTEST-HW3:MOT1" id="id0">
|
||||
<start>0.0</start>
|
||||
<end>8.0</end>
|
||||
<stepSize>0.5</stepSize>
|
||||
<integrationTime>0.5</integrationTime>
|
||||
</positioner>
|
||||
<scaler channel="0" id="idD0"/>
|
||||
<scaler channel="1" id="idD1"/>
|
||||
</cdimension>
|
||||
<dimension>
|
||||
<positioner xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinearPositioner" name="MTEST-HW3:MOT2" settlingTime="1.0" id="id2">
|
||||
<start>-1.0</start>
|
||||
<end>-2.0</end>
|
||||
<stepSize>0.1</stepSize>
|
||||
</positioner>
|
||||
</dimension>
|
||||
</scan>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="idD0" title="Line Plot One"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="idD1" title="Line Plot One"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="id2" title="Line Plot Two"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="MatrixPlot" x="id0" y="id2" z="idD0" title="Matrix Plot"/>
|
||||
</configuration>
|
||||
29
src/test/resources/home/scans/templates/cscan2d.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="0" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 ../../src/model-v1.xsd">
|
||||
<data format="txt"/>
|
||||
<scan id="">
|
||||
<cdimension>
|
||||
<positioner id="id0" name="MTEST-HW3:MOT1">
|
||||
<start>0.0</start>
|
||||
<end>8.0</end>
|
||||
<stepSize>0.5</stepSize>
|
||||
<integrationTime>0.5</integrationTime>
|
||||
</positioner>
|
||||
<scaler id="idD0" channel="0"/>
|
||||
<scaler id="idD1" channel="1"/>
|
||||
</cdimension>
|
||||
<dimension>
|
||||
<positioner id="id2" name="MTEST-HW3:MOT2" settlingTime="1" xsi:type="LinearPositioner">
|
||||
<start>-1.0</start>
|
||||
<end>-2.0</end>
|
||||
<stepSize>0.1</stepSize>
|
||||
</positioner>
|
||||
</dimension>
|
||||
</scan>
|
||||
|
||||
<visualization title="Line Plot One" xsi:type="LinePlot" x="id0" y="idD0"/>
|
||||
<visualization title="Line Plot One" xsi:type="LinePlot" x="id0" y="idD1"/>
|
||||
<visualization title="Line Plot Two" xsi:type="LinePlot" x="id0" y="id2"/>
|
||||
<visualization title="Matrix Plot" xsi:type="MatrixPlot" x="id0" y="id2" z="idD0"/>
|
||||
|
||||
</configuration>
|
||||
14
src/test/resources/home/scans/templates/scan0d-pseudo.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="1" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 http://www.psi.ch/~ebner/models/scan/1.0">
|
||||
<data format="txt"/>
|
||||
<scan id="">
|
||||
<dimension>
|
||||
<positioner id="id2" xsi:type="PseudoPositioner">
|
||||
<counts>100</counts>
|
||||
</positioner>
|
||||
<detector id="x" xsi:type="ScalarDetector" name="CHANNEL-TO-TRIGGER">
|
||||
<preAction xsi:type="ChannelAction" channel="CHANNEL-TO-TRIGGER" value="TRIGGER-VALUE"/>
|
||||
</detector>
|
||||
</dimension>
|
||||
</scan>
|
||||
</configuration>
|
||||
7
src/test/resources/home/scans/templates/scan0d.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<configuration xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" numberOfExecution="1" failOnSensorError="true">
|
||||
<data format="txt"/>
|
||||
<scan>
|
||||
<preAction xsi:type="ShellAction" command="testfiles/testscript.sh"/>
|
||||
</scan>
|
||||
</configuration>
|
||||
25
src/test/resources/home/scans/templates/scan1d-array.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="0" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 ../../../src/model-v1.xsd">
|
||||
<!--
|
||||
1D scan reading out an array channel
|
||||
-->
|
||||
<data format="txt"/>
|
||||
<scan id="">
|
||||
<dimension>
|
||||
<positioner id="id0" name="MTEST-HW3:MOT1" settlingTime="0.1" xsi:type="LinearPositioner">
|
||||
<start>0.0</start>
|
||||
<end>8.0</end>
|
||||
<stepSize>0.5</stepSize>
|
||||
</positioner>
|
||||
<detector id="idD0" xsi:type="ScalarDetector" name="MTEST-HW3:MOT1.RRBV"/>
|
||||
<detector id="idD2" xsi:type="ArrayDetector" name="MTEST-PC-SSCAN:scan2.P1PA" arraySize="10"/>
|
||||
<detector id="idD20" xsi:type="ArrayDetector" name="MTEST-PC-SSCAN:scan1.P1PA" arraySize="10"/>
|
||||
<detector id="idD1" xsi:type="ScalarDetector" name="MTEST-HW3:MOT1.RBV"/>
|
||||
</dimension>
|
||||
</scan>
|
||||
|
||||
<visualization title="Array" xsi:type="LinePlotArray" y="idD2 idD20" maxSeries="4"/>
|
||||
<visualization title="Array Offset/Size" xsi:type="LinePlotArray" y="idD2" offset="2" size="4" maxSeries="4"/>
|
||||
<visualization title="Array 2D" xsi:type="MatrixPlotArray" y="id0" z="idD2" offset="2" size="10"/>
|
||||
|
||||
</configuration>
|
||||
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="0" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 ../../../src/model-v1.xsd">
|
||||
<!--
|
||||
1D scan reading out an array channel
|
||||
-->
|
||||
<data format="txt"/>
|
||||
<scan id="">
|
||||
<dimension>
|
||||
<positioner id="id0" name="MTEST-HW3:MOT1" settlingTime="0.1" xsi:type="LinearPositioner">
|
||||
<start>0.0</start>
|
||||
<end>8.0</end>
|
||||
<stepSize>0.5</stepSize>
|
||||
</positioner>
|
||||
<detector id="idD0" xsi:type="ScalarDetector" name="MTEST-HW3:MOT1.RRBV"/>
|
||||
<detector id="idD2" xsi:type="ArrayDetector" name="MTEST-PC-SSCAN:scan2.P1PA" arraySize="10"/>
|
||||
<detector id="idD20" xsi:type="ArrayDetector" name="MTEST-PC-SSCAN:scan1.P1PA" arraySize="10"/>
|
||||
<detector id="idD1" xsi:type="ScalarDetector" name="MTEST-HW3:MOT1.RBV"/>
|
||||
</dimension>
|
||||
|
||||
<!-- <manipulation id="idM2" xsi:type="ScriptManipulation" returnArray="true">
|
||||
<mapping xsi:type="IDParameterMapping" variable="a" refid="idD2"/>
|
||||
<script>
|
||||
import math
|
||||
def process(a):
|
||||
return float(len(a))
|
||||
</script>
|
||||
</manipulation> -->
|
||||
<manipulation id="idM2" xsi:type="ScriptManipulation" returnArray="true">
|
||||
<mapping xsi:type="IDParameterMapping" variable="a" refid="idD2"/>
|
||||
<script>
|
||||
import math
|
||||
import operator
|
||||
from jarray import array
|
||||
|
||||
var = True
|
||||
|
||||
def process(a):
|
||||
global var
|
||||
global ovalue
|
||||
|
||||
if var:
|
||||
ovalue = a
|
||||
var = False
|
||||
return a
|
||||
ovalue = map(operator.add, ovalue, a)
|
||||
return array(ovalue, 'd')
|
||||
</script>
|
||||
</manipulation>
|
||||
<!-- <manipulation id="idM2" xsi:type="ScriptManipulation" returnArray="true">
|
||||
<mapping xsi:type="IDParameterMapping" variable="a" refid="idD2"/>
|
||||
<script>
|
||||
from jarray import array
|
||||
def process(a):
|
||||
return array((1.0, 0.1), 'd')
|
||||
</script>
|
||||
</manipulation> -->
|
||||
</scan>
|
||||
|
||||
|
||||
|
||||
<visualization title="Array" xsi:type="LinePlotArray" y="idD2 idD20" maxSeries="4"/>
|
||||
<visualization title="Array Offset/Size" xsi:type="LinePlotArray" y="idD2" offset="2" size="4" maxSeries="4"/>
|
||||
<visualization title="Array 2D" xsi:type="MatrixPlotArray" y="id0" z="idD2" offset="2" size="10"/>
|
||||
<!-- <visualization xsi:type="LinePlot" x="id0" y="idM2"/> -->
|
||||
<!-- <visualization title="Array Manipulated" xsi:type="LinePlotArray" y="idM2" maxSeries="10"/> -->
|
||||
<visualization title="Array Manipulated 2D" xsi:type="MatrixPlotArray" y="id0" z="idM2" offset="2" size="10"/>
|
||||
|
||||
</configuration>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<configuration xmlns="http://www.psi.ch/~ebner/models/scan/1.0" numberOfExecution="1">
|
||||
<data format="txt" fileName="scan1d-arrayManipulation2"/>
|
||||
<description>hello wolrd</description>
|
||||
<scan id="">
|
||||
<dimension>
|
||||
<positioner xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinearPositioner" name="MTEST-HW3:MOT1" settlingTime="0.1" id="id0">
|
||||
<start>0.0</start>
|
||||
<end>8.0</end>
|
||||
<stepSize>0.5</stepSize>
|
||||
</positioner>
|
||||
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScalarDetector" name="MTEST-HW3:MOT1.RRBV" id="idD0"/>
|
||||
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ArrayDetector" arraySize="10" name="MTEST-PC-SSCAN:scan2.P1PA" id="idD2"/>
|
||||
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ArrayDetector" arraySize="10" name="MTEST-PC-SSCAN:scan1.P1PA" id="idD20"/>
|
||||
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScalarDetector" name="MTEST-HW3:MOT1.RBV" id="idD1"/>
|
||||
</dimension>
|
||||
<manipulation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScriptManipulation" returnArray="true" id="idM2">
|
||||
<mapping xsi:type="IDParameterMapping" refid="idD2" variable="a"/>
|
||||
<script>import math
|
||||
import operator
|
||||
from jarray import array
|
||||
|
||||
var = True
|
||||
|
||||
def process(a):
|
||||
global var
|
||||
global ovalue
|
||||
|
||||
if var:
|
||||
ovalue = a
|
||||
var = False
|
||||
return a
|
||||
ovalue = map(operator.add, ovalue, a)
|
||||
return array(ovalue, 'd')</script>
|
||||
</manipulation>
|
||||
</scan>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlotArray" y="idD2 idD20" maxSeries="4" title="Array"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlotArray" y="idD2" maxSeries="4" offset="2" size="4" title="Array Offset/Size"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="MatrixPlotArray" y="id0" z="idD2" offset="2" size="10" title="Array 2D"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="MatrixPlotArray" y="id0" z="idM2" offset="2" size="10" title="Array Manipulated 2D"/>
|
||||
</configuration>
|
||||
20
src/test/resources/home/scans/templates/scan1d-condition.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<configuration xmlns="http://www.psi.ch/~ebner/models/scan/1.0" numberOfExecution="1" failOnSensorError="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 ../../../src/model-v1.xsd">
|
||||
<data format="txt" fileName="scan1d"/>
|
||||
<scan>
|
||||
<dimension zigzag="true">
|
||||
<positioner xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinearPositioner" name="MTEST-HW3:MOT1" settlingTime="0.1" doneValue="1" doneDelay="0.0" id="id0">
|
||||
<start>0.0</start>
|
||||
<end>8.0</end>
|
||||
<stepSize>0.5</stepSize>
|
||||
</positioner>
|
||||
<guard><condition channel="MTEST-PC-X10:AO" value="0" type="Integer"/></guard>
|
||||
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScalarDetector" name="MTEST-HW3:MOT1.RRBV" id="idD0"/>
|
||||
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ScalarDetector" name="MTEST-HW3:MOT1.RBV" id="idD1"/>
|
||||
<detector xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Timestamp" id="timestamp"/>
|
||||
</dimension>
|
||||
</scan>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="idD1" title="Readback"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="idD0" title="Raw"/>
|
||||
<visualization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="LinePlot" x="id0" y="timestamp idD0" title="Timestamp"/>
|
||||
</configuration>
|
||||
24
src/test/resources/home/scans/templates/scan1d-dod.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration numberOfExecution="0" xmlns="http://www.psi.ch/~ebner/models/scan/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.psi.ch/~ebner/models/scan/1.0 ../../../src/model-v1.xsd">
|
||||
<!--
|
||||
1D Scan with a non motor positioner (one set channel and one channel indicating done)
|
||||
-->
|
||||
<data format="txt"/>
|
||||
<scan id="">
|
||||
<dimension>
|
||||
<positioner id="id0" name="MTEST-HW3:MOT1" settlingTime="0.1" xsi:type="LinearPositioner" done="MTEST-PC-X10:BO2" doneValue="1">
|
||||
<start>0.0</start>
|
||||
<end>8.0</end>
|
||||
<stepSize>0.5</stepSize>
|
||||
</positioner>
|
||||
<detector id="idm" xsi:type="DetectorOfDetectors" name=""/>
|
||||
<detector id="idD0" xsi:type="ScalarDetector" name="MTEST-HW3:MOT1.RRBV"/>
|
||||
<detector id="idD1" xsi:type="ScalarDetector" name="MTEST-HW3:MOT1.RBV"/>
|
||||
<detector xsi:type="Timestamp" id="timestamp"/>
|
||||
</dimension>
|
||||
</scan>
|
||||
|
||||
<visualization title="Line Plot One" xsi:type="LinePlot" x="id0" y="idD0"/>
|
||||
<visualization title="Line Plot Two" xsi:type="LinePlot" x="id0" y="idD1"/>
|
||||
<visualization xsi:type="LinePlot" x="id0" y="timestamp" title="Timestamp" />
|
||||
</configuration>
|
||||