moved files to top level

This commit is contained in:
2015-08-14 13:26:17 +02:00
parent 19d2b28f25
commit 10f0fcdde2
171 changed files with 0 additions and 0 deletions

View 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>

View 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

View 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

View 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

View 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

View 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

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

6158
src/main/assembly/www/css/bootstrap.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,22 @@
/* ==========================================================================
Author's custom styles
========================================================================== */

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View 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> - &copy; 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>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View 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();
}

View 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
*
*/

View 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);
}
}
}

View 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);
}
}

View 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;
}
}

View 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");
}
}

View 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();
}
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

View 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();
}
}

View 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;
}
}

View File

@@ -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;
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

View 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);
}
}
}

View 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();
}
}

View 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
}
}

View 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());
}
}

View 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);
}
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

View 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);
}
}
}

View 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);
}
}
}

View File

@@ -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;
}
}

View 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();
}

View 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
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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
View File

View 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();
}
}

View File

@@ -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();
}
}

View 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();
}
}

View 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"});
}
}

View 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();
}
}

View 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});
}
}

View 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);
}
}

View 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

View File

@@ -0,0 +1 @@
ch.psi.fda.fdaq.hostname=localhost

2
src/test/resources/home/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/data
/logs

View 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

View 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

View 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

View 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>

View File

@@ -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>

View 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>

View 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" 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>

View File

@@ -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>

View 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>

View File

@@ -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>

View 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>

View 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">
<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>

View 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>

View 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>

View File

@@ -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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View File

@@ -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>

View File

@@ -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>

View 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>

View 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>

Some files were not shown because too many files have changed in this diff Show More