Compare commits
34 Commits
0.9.6-SNAP
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ab98e72c1 | |||
| 9f7f6dd84f | |||
| cd2ba11e98 | |||
| 4929add1ab | |||
| 9a52acf8b6 | |||
| 305e692270 | |||
| 4d8673e6e4 | |||
| e72a5cc9e0 | |||
| 58fa3d7a21 | |||
| 1b98a5492d | |||
| 20d5842510 | |||
| caa1c64fec | |||
| 02633139df | |||
| c1441bdb5f | |||
| eb3fbcdab9 | |||
| 3d09aaf9b9 | |||
| b77d8737ea | |||
| b66085f7bd | |||
| 9de1bf81f3 | |||
| eb1b79279e | |||
| 6fc705a3d3 | |||
| 4fde67bb78 | |||
| bf623657ae | |||
| 4b66cb27dc | |||
| 595119f705 | |||
| fc28ffad2f | |||
| 1806a66ea6 | |||
| bb31a1ec1f | |||
| 54561c1957 | |||
| 97a1dc9e65 | |||
| f0623e7453 | |||
| 03cd2f5b50 | |||
| e7a8c60616 | |||
| 6f691e1708 |
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
@@ -1,3 +0,0 @@
|
||||
#Wed Oct 12 13:39:19 CEST 2011
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
@@ -1,76 +0,0 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>ch.psi</groupId>
|
||||
<artifactId>cdump</artifactId>
|
||||
<version>0.9.6-SNAPSHOT</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ch.psi</groupId>
|
||||
<artifactId>jcae</artifactId>
|
||||
<version>RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.8.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- Generate Javadoc Jar -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Generate Source Jar -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Assembly Plugin -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<!-- The configuration of the plugin -->
|
||||
<configuration>
|
||||
<!-- Specifies the configuration file of the assembly plugin -->
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<distributionManagement>
|
||||
<snapshotRepository>
|
||||
<id>i.snapshots</id>
|
||||
<name>Artifactory Snapshots</name>
|
||||
<url>http://slsyoke1/artifactory/libs-snapshots-local</url>
|
||||
</snapshotRepository>
|
||||
<repository>
|
||||
<id>i.releases</id>
|
||||
<name>Atrifactory Releases</name>
|
||||
<url>http://slsyoke1/artifactory/libs-releases-local</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</project>
|
||||
@@ -1,27 +0,0 @@
|
||||
<assembly>
|
||||
<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>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@@ -1,106 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Queue;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import gov.aps.jca.CAException;
|
||||
import ch.psi.jcae.ChannelBean;
|
||||
import ch.psi.jcae.ChannelBeanFactory;
|
||||
|
||||
/**
|
||||
* Cdump client, creating a monitor on a Waveform channel of an fast ADC and split the data
|
||||
* for each channel and write it directly to file.
|
||||
*
|
||||
* @author ebner
|
||||
*
|
||||
*/
|
||||
public class CdumpAqLogic {
|
||||
|
||||
private enum AdcCmd {READY, GO};
|
||||
|
||||
// Get Logger
|
||||
private static final Logger logger = Logger.getLogger(CdumpAqLogic.class.getName());
|
||||
|
||||
private final String adcChannel;
|
||||
private final String adcStartStop;
|
||||
private ChannelBean<int[]> adcData;
|
||||
private ChannelBean<Integer> adcCmd;
|
||||
private Queue<int[]> dataQueue;
|
||||
private PropertyChangeListener listener;
|
||||
|
||||
public CdumpAqLogic(String adcChannel, String adcStartStop, Queue<int[]> queue){
|
||||
this.adcChannel = adcChannel;
|
||||
this.adcStartStop = adcStartStop;
|
||||
this.dataQueue = queue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
* @throws InterruptedException
|
||||
* @throws CAException
|
||||
*/
|
||||
public void initialize() throws CAException, InterruptedException{
|
||||
adcData = ChannelBeanFactory.getFactory().createChannelBean(int[].class, adcChannel, true);
|
||||
adcCmd = ChannelBeanFactory.getFactory().createChannelBean(Integer.class, adcStartStop, false);
|
||||
|
||||
// Create listner to
|
||||
listener = new PropertyChangeListener() {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
// Append data to processing queue
|
||||
dataQueue.add((int[]) evt.getNewValue());
|
||||
logger.info("Monitor fired");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire data
|
||||
* @throws InterruptedException
|
||||
* @throws CAException
|
||||
*/
|
||||
public void acquire() throws CAException, InterruptedException{
|
||||
adcCmd.setValue(AdcCmd.GO.ordinal());
|
||||
adcData.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
public void stop() throws CAException, InterruptedException{
|
||||
// Detach listener from channel - i.e. stop data acquisition
|
||||
adcData.removePropertyChangeListener(listener);
|
||||
adcCmd.setValue(AdcCmd.READY.ordinal());
|
||||
dataQueue.add(new int[]{});
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up used resources
|
||||
* @throws CAException
|
||||
*/
|
||||
public void cleanup() throws CAException{
|
||||
// Destroy channel
|
||||
adcData.destroy();
|
||||
adcCmd.destroy();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author ebner
|
||||
*
|
||||
*/
|
||||
public class CdumpConfiguration {
|
||||
|
||||
private static final CdumpConfiguration instance = new CdumpConfiguration();
|
||||
|
||||
private String dataChannel;
|
||||
private int nelements = 65536;
|
||||
private String controlChannel;
|
||||
private String samplingRateChannel;
|
||||
private String filePrefix = "${yyyy_MM}/${yyyyMMdd}/${yyyyMMddHHmmss}_${name}/${yyyyMMddHHmm}_";
|
||||
private String dataDirectory;
|
||||
|
||||
/**
|
||||
* Singleton - Private constructor
|
||||
*/
|
||||
private CdumpConfiguration(){
|
||||
loadConfiguration();
|
||||
}
|
||||
|
||||
public static CdumpConfiguration getInstance(){
|
||||
return instance;
|
||||
}
|
||||
|
||||
private void loadConfiguration() {
|
||||
String config = System.getProperty(CdumpService.APP_HOME);
|
||||
|
||||
if(config == null){
|
||||
throw new RuntimeException("No configuration file specified via -D"+CdumpService.APP_HOME+"=...");
|
||||
}
|
||||
|
||||
Properties properties = new Properties();
|
||||
try {
|
||||
properties.load(new FileReader(config+"/config/cdump.properties"));
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException("Configuration file "+config+" not found", e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Cannot read configuration file "+config, e);
|
||||
}
|
||||
|
||||
dataChannel = properties.getProperty(CdumpConfiguration.class.getPackage().getName()+".dataChannel", "");
|
||||
controlChannel = properties.getProperty(CdumpConfiguration.class.getPackage().getName()+".controlChannel", "");
|
||||
samplingRateChannel = properties.getProperty(CdumpConfiguration.class.getPackage().getName()+".samplingRateChannel", "");
|
||||
dataDirectory = config+"/data";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the dataChannel
|
||||
*/
|
||||
public String getDataChannel() {
|
||||
return dataChannel;
|
||||
}
|
||||
/**
|
||||
* @param dataChannel the dataChannel to set
|
||||
*/
|
||||
public void setDataChannel(String dataChannel) {
|
||||
this.dataChannel = dataChannel;
|
||||
}
|
||||
/**
|
||||
* @return the controlChannel
|
||||
*/
|
||||
public String getControlChannel() {
|
||||
return controlChannel;
|
||||
}
|
||||
/**
|
||||
* @param controlChannel the controlChannel to set
|
||||
*/
|
||||
public void setControlChannel(String controlChannel) {
|
||||
this.controlChannel = controlChannel;
|
||||
}
|
||||
/**
|
||||
* @return the samplingRateChannel
|
||||
*/
|
||||
public String getSamplingRateChannel() {
|
||||
return samplingRateChannel;
|
||||
}
|
||||
/**
|
||||
* @param samplingRateChannel the samplingRateChannel to set
|
||||
*/
|
||||
public void setSamplingRateChannel(String samplingRateChannel) {
|
||||
this.samplingRateChannel = samplingRateChannel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nelements
|
||||
*/
|
||||
public int getNelements() {
|
||||
return nelements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the filePrefix
|
||||
*/
|
||||
public String getFilePrefix() {
|
||||
return filePrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the dataDirectory
|
||||
*/
|
||||
public String getDataDirectory() {
|
||||
return dataDirectory;
|
||||
}
|
||||
|
||||
public String replaceMacros(String string, Date date, String name){
|
||||
String newString = string;
|
||||
|
||||
// Replace scan name macros
|
||||
newString = newString.replaceAll("\\$\\{name\\}", name);
|
||||
|
||||
|
||||
// Replace date macros
|
||||
Pattern pattern = Pattern.compile("\\$\\{[a-z,A-Z,-,_,:]*\\}");
|
||||
Matcher matcher = pattern.matcher(newString);
|
||||
while(matcher.find()){
|
||||
String datePattern = matcher.group();
|
||||
datePattern = datePattern.replaceAll("\\$\\{", "");
|
||||
datePattern = datePattern.replaceAll("\\}", "");
|
||||
SimpleDateFormat datef = new SimpleDateFormat(datePattern);
|
||||
newString = matcher.replaceFirst(datef.format(date));
|
||||
matcher = pattern.matcher(newString);
|
||||
}
|
||||
return newString;
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* Processing logic
|
||||
* @author ebner
|
||||
*
|
||||
*/
|
||||
public class CdumpPrLogic implements Runnable {
|
||||
|
||||
/**
|
||||
* Data file
|
||||
*/
|
||||
private final File file;
|
||||
private final BlockingQueue<int[]> dataQueue;
|
||||
|
||||
private final int numberOfElements;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param file
|
||||
* @param dataQueue
|
||||
* @param nelements Example 65536
|
||||
*/
|
||||
public CdumpPrLogic(File file, BlockingQueue<int[]> dataQueue, int nelements){
|
||||
this.file = file;
|
||||
this.dataQueue = dataQueue;
|
||||
this.numberOfElements=nelements;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
int[] value = new int[]{};
|
||||
boolean first = true;
|
||||
int nwaveforms = 0;
|
||||
|
||||
// Open file
|
||||
PrintWriter w = null;
|
||||
try {
|
||||
w = new PrintWriter(new BufferedWriter(new FileWriter(file)));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Cannot open file "+file.getAbsolutePath(), e);
|
||||
}
|
||||
|
||||
while(true){
|
||||
try {
|
||||
value = dataQueue.take();
|
||||
} catch (InterruptedException e) {
|
||||
// Abort loop
|
||||
break;
|
||||
}
|
||||
|
||||
if(value.length==0){
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(first){
|
||||
int nelements = value.length;
|
||||
int n = nelements%numberOfElements;
|
||||
if(n!=0){
|
||||
throw new RuntimeException("Array size is not a multiple of 65536");
|
||||
}
|
||||
nwaveforms = nelements/numberOfElements;
|
||||
|
||||
}
|
||||
|
||||
// Split and rotate array/waveform
|
||||
boolean f = true;
|
||||
for(int x=0;x<numberOfElements;x++){
|
||||
f=true;
|
||||
for(int t=0;t<nwaveforms;t++){
|
||||
if(f){
|
||||
f=false;
|
||||
}
|
||||
else{
|
||||
w.print("\t");
|
||||
}
|
||||
w.print(value[x+t*numberOfElements]);
|
||||
}
|
||||
w.print("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Close file
|
||||
w.close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump;
|
||||
|
||||
import gov.aps.jca.CAException;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import ch.psi.jcae.ChannelBean;
|
||||
import ch.psi.jcae.ChannelBeanFactory;
|
||||
|
||||
/**
|
||||
* @author ebner
|
||||
*
|
||||
*/
|
||||
public class CdumpService {
|
||||
|
||||
public final static String APP_HOME = "ch.psi.cdump.home";
|
||||
|
||||
|
||||
// Get Logger
|
||||
private static final Logger logger = Logger.getLogger(CdumpService.class.getName());
|
||||
|
||||
private CdumpAqLogic aqlogic = null;
|
||||
private CdumpPrLogic prlogic = null;
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public void startAcquisition(RunConfiguration c) {
|
||||
|
||||
logger.info("Start acquisition");
|
||||
|
||||
CdumpConfiguration configuration = CdumpConfiguration.getInstance();
|
||||
|
||||
try {
|
||||
|
||||
// Set ADC sampling rate
|
||||
ChannelBean<Integer> smplRate = ChannelBeanFactory.getFactory().createChannelBean(Integer.class, configuration.getSamplingRateChannel(), false);
|
||||
smplRate.setValue(c.getSamplingRate());
|
||||
smplRate.destroy();
|
||||
|
||||
BlockingQueue<int[]> queue = new LinkedBlockingQueue<int[]>();
|
||||
|
||||
aqlogic = new CdumpAqLogic(configuration.getDataChannel(), configuration.getControlChannel(), queue);
|
||||
prlogic = new CdumpPrLogic(c.getDatafile(), queue, configuration.getNelements());
|
||||
Thread t = new Thread(prlogic);
|
||||
|
||||
// Initialize acquisition logic
|
||||
logger.info("Initialize acquisition logic");
|
||||
aqlogic.initialize();
|
||||
|
||||
// Start writer thread
|
||||
logger.info("Start serialization logic");
|
||||
t.start();
|
||||
|
||||
logger.info("Start acquisition");
|
||||
aqlogic.acquire();
|
||||
|
||||
|
||||
} catch (CAException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the data acquisition
|
||||
*/
|
||||
public void stopAcquisition(){
|
||||
logger.info("Stop acquisition");
|
||||
try {
|
||||
aqlogic.stop();
|
||||
aqlogic.cleanup();
|
||||
} catch (CAException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author ebner
|
||||
*
|
||||
*/
|
||||
public class RunConfiguration {
|
||||
|
||||
public final static String[] rates = new String[] {"1Hz","2Hz", "5Hz", "10Hz", "20Hz", "50Hz", "100Hz", "200Hz", "500Hz",
|
||||
"1kHz", "2kHz", "5kHz", "10kHz", "20kHz", "50kHz", "100kHz"};
|
||||
|
||||
/**
|
||||
* 0 = 1Hz
|
||||
* 1 = 2Hz
|
||||
* 2 = 5Hz
|
||||
* 3 = 10Hz
|
||||
* 4 = 20Hz
|
||||
* 5 = 50Hz
|
||||
* 6 = 100Hz
|
||||
* 7 = 200Hz
|
||||
* 8 = 500Hz
|
||||
* 9 = 1000Hz
|
||||
* 10 = 2000Hz
|
||||
* 11 = 5000Hz
|
||||
* 12 = 10000Hz
|
||||
* 13 = 20000Hz
|
||||
* 14 = 50000Hz
|
||||
* 15 = 100000Hz
|
||||
*/
|
||||
private int samplingRate = 0;
|
||||
|
||||
/**
|
||||
* Data file
|
||||
*/
|
||||
private File datafile;
|
||||
|
||||
/**
|
||||
* Time to take data
|
||||
*/
|
||||
private Long executionTime = null ;
|
||||
|
||||
/**
|
||||
* @param samplingRate the samplingRate to set
|
||||
*/
|
||||
public void setSamplingRate(int samplingRate) {
|
||||
this.samplingRate = samplingRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set sampling rate based on the passed rate string.
|
||||
* If the string does not match any of the strings specified in the rates variable
|
||||
* this function will set the rate to 1Hz
|
||||
* @param rate
|
||||
*/
|
||||
public void setSamplingRate(String rate){
|
||||
// Default sampling rate 10kHz
|
||||
setSamplingRate(12);
|
||||
|
||||
for(int i=0;i<rates.length; i++){
|
||||
if(rate.equals(rates[i])){
|
||||
setSamplingRate(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the samplingRate
|
||||
*/
|
||||
public int getSamplingRate() {
|
||||
return samplingRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the executionTime
|
||||
*/
|
||||
public Long getExecutionTime() {
|
||||
return executionTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param executionTime the executionTime to set
|
||||
*/
|
||||
public void setExecutionTime(Long executionTime) {
|
||||
this.executionTime = executionTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param datafile the datafile to set
|
||||
*/
|
||||
public void setDatafile(File datafile) {
|
||||
this.datafile = datafile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the datafile
|
||||
*/
|
||||
public File getDatafile() {
|
||||
return datafile;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump.ui;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import java.awt.BorderLayout;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
/**
|
||||
* @author ebner
|
||||
*
|
||||
*/
|
||||
public class CalibratePanel extends JPanel {
|
||||
|
||||
/**
|
||||
* Create the panel.
|
||||
*/
|
||||
public CalibratePanel() {
|
||||
setLayout(new BorderLayout(0, 0));
|
||||
|
||||
JLabel label = new JLabel("");
|
||||
label.setIcon(new ImageIcon(CalibratePanel.class.getResource("/ch/psi/cdump/gui/sine.png")));
|
||||
add(label, BorderLayout.CENTER);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,249 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump.ui;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.GroupLayout;
|
||||
import javax.swing.GroupLayout.Alignment;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.LayoutStyle.ComponentPlacement;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JButton;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Font;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
/**
|
||||
* @author ebner
|
||||
*
|
||||
*/
|
||||
public class ControlPanel extends JPanel {
|
||||
private JTextField tfScanName;
|
||||
private JButton btnCalibrate;
|
||||
private JComboBox cbSamplingRate;
|
||||
private JButton btnAcquire;
|
||||
private JLabel lblRunning;
|
||||
private JTextField tfMonoFrequency;
|
||||
private JLabel lblScanName;
|
||||
private JLabel lblMonoFrequency;
|
||||
private JLabel lblSamplingRate;
|
||||
|
||||
/**
|
||||
* Create the panel.
|
||||
*/
|
||||
public ControlPanel() {
|
||||
|
||||
tfMonoFrequency = new JTextField();
|
||||
tfMonoFrequency.setColumns(10);
|
||||
|
||||
lblMonoFrequency = new JLabel("Mono Frequency [rpm]");
|
||||
|
||||
JLabel lblFrequency = new JLabel("frequency");
|
||||
|
||||
cbSamplingRate = new JComboBox();
|
||||
|
||||
lblSamplingRate = new JLabel("Sampling Rate");
|
||||
|
||||
tfScanName = new JTextField();
|
||||
tfScanName.setColumns(10);
|
||||
|
||||
lblScanName = new JLabel("Scan Name");
|
||||
|
||||
btnAcquire = new JButton("Acquire");
|
||||
btnAcquire.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if(btnAcquire.getText().equals("Acquire")){
|
||||
lblRunning.setVisible(true);
|
||||
btnAcquire.setText("Stop");
|
||||
btnAcquire.requestFocus();
|
||||
|
||||
// Disable calibrate button
|
||||
btnCalibrate.setEnabled(false);
|
||||
cbSamplingRate.setEnabled(false);
|
||||
lblSamplingRate.setEnabled(false);
|
||||
lblMonoFrequency.setEnabled(false);
|
||||
tfMonoFrequency.setEnabled(false);
|
||||
|
||||
tfScanName.setEnabled(false);
|
||||
lblScanName.setEnabled(false);
|
||||
|
||||
ControlPanel.this.validate();
|
||||
|
||||
acquire();
|
||||
}
|
||||
else{
|
||||
lblRunning.setVisible(false);
|
||||
btnAcquire.setText("Acquire");
|
||||
tfScanName.requestFocus();
|
||||
|
||||
// Enable calibrate button again
|
||||
btnCalibrate.setEnabled(true);
|
||||
cbSamplingRate.setEnabled(true);
|
||||
lblSamplingRate.setEnabled(true);
|
||||
lblMonoFrequency.setEnabled(true);
|
||||
tfMonoFrequency.setEnabled(true);
|
||||
|
||||
tfScanName.setEnabled(true);
|
||||
lblScanName.setEnabled(true);
|
||||
|
||||
ControlPanel.this.validate();
|
||||
|
||||
stopAcquire();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
lblRunning = new JLabel("[running]");
|
||||
lblRunning.setVisible(false);
|
||||
lblRunning.setFont(new Font("Lucida Grande", Font.BOLD, 13));
|
||||
|
||||
btnCalibrate = new JButton("Calibrate");
|
||||
btnCalibrate.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if(btnCalibrate.getText().equals("Calibrate")){
|
||||
|
||||
btnCalibrate.setText("Stop");
|
||||
btnCalibrate.requestFocus();
|
||||
|
||||
// Disable acquire components
|
||||
tfScanName.setEnabled(false);
|
||||
lblScanName.setEnabled(false);
|
||||
btnAcquire.setEnabled(false);
|
||||
lblRunning.setEnabled(false);
|
||||
|
||||
ControlPanel.this.validate();
|
||||
|
||||
calibrate();
|
||||
}
|
||||
else{
|
||||
|
||||
btnCalibrate.setText("Calibrate");
|
||||
tfScanName.requestFocus();
|
||||
|
||||
// Enable acquire components
|
||||
tfScanName.setEnabled(true);
|
||||
lblScanName.setEnabled(true);
|
||||
btnAcquire.setEnabled(true);
|
||||
lblRunning.setEnabled(true);
|
||||
|
||||
ControlPanel.this.validate();
|
||||
|
||||
stopCalibrate();
|
||||
}
|
||||
}
|
||||
});
|
||||
GroupLayout groupLayout = new GroupLayout(this);
|
||||
groupLayout.setHorizontalGroup(
|
||||
groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING, false)
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(btnAcquire, GroupLayout.PREFERRED_SIZE, 113, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(lblRunning))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addComponent(tfMonoFrequency, 113, 113, Short.MAX_VALUE)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(lblMonoFrequency)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(lblFrequency)
|
||||
.addGap(29))
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING, false)
|
||||
.addComponent(cbSamplingRate, Alignment.LEADING, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btnCalibrate, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(tfScanName, 113, 113, Short.MAX_VALUE))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addComponent(lblSamplingRate)
|
||||
.addComponent(lblScanName))
|
||||
.addGap(148)))
|
||||
.addContainerGap(38, Short.MAX_VALUE))
|
||||
);
|
||||
groupLayout.setVerticalGroup(
|
||||
groupLayout.createParallelGroup(Alignment.LEADING)
|
||||
.addGroup(groupLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(tfMonoFrequency, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblMonoFrequency)
|
||||
.addComponent(lblFrequency))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(cbSamplingRate, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblSamplingRate))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addComponent(btnCalibrate)
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(tfScanName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(lblScanName))
|
||||
.addPreferredGap(ComponentPlacement.RELATED)
|
||||
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
|
||||
.addComponent(btnAcquire)
|
||||
.addComponent(lblRunning))
|
||||
.addContainerGap(131, Short.MAX_VALUE))
|
||||
);
|
||||
setLayout(groupLayout);
|
||||
}
|
||||
|
||||
private void acquire(){
|
||||
}
|
||||
|
||||
private void stopAcquire() {
|
||||
}
|
||||
|
||||
private JFrame calibratePlot = null;
|
||||
|
||||
private void calibrate(){
|
||||
|
||||
Point p = this.getLocationOnScreen();
|
||||
|
||||
Point p1 = new Point(p.getLocation().x+this.getWidth(), p.getLocation().y);
|
||||
|
||||
final JFrame frame = new JFrame();
|
||||
frame.setLocation(p1);
|
||||
frame.add(new CalibratePanel());
|
||||
|
||||
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||
frame.setUndecorated(true);
|
||||
frame.pack();
|
||||
|
||||
calibratePlot = frame;
|
||||
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
frame.setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void stopCalibrate(){
|
||||
if(calibratePlot!=null){
|
||||
calibratePlot.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump.ui;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
|
||||
/**
|
||||
* @author ebner
|
||||
*
|
||||
*/
|
||||
public class MainGui {
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// TODO Auto-generated method stub
|
||||
final JFrame frame = new JFrame();
|
||||
frame.add(new ControlPanel());
|
||||
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.pack();
|
||||
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
frame.setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
ch.psi.cdump.dataChannel=
|
||||
ch.psi.cdump.controlChannel=
|
||||
ch.psi.cdump.samplingRateChannel=
|
||||
@@ -1,64 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author ebner
|
||||
*
|
||||
*/
|
||||
public class CdumpPrLogicTest {
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.cdump.CdumpPrLogic#run()}.
|
||||
*/
|
||||
@Test
|
||||
public void testRun() {
|
||||
BlockingQueue<int[]> queue = new LinkedBlockingQueue<int[]>();
|
||||
queue.add(new int[] {1,2,3,4,11,12,13,14});
|
||||
queue.add(new int[] {5,6,7,8,15,16,17,18});
|
||||
queue.add(new int[]{});
|
||||
CdumpPrLogic logic = new CdumpPrLogic(new File("test.txt"), queue, 4);
|
||||
|
||||
logic.run();
|
||||
}
|
||||
|
||||
}
|
||||
36
ch.psi.fda.cdump/.classpath
Normal file
36
ch.psi.fda.cdump/.classpath
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ch.psi.cdump</name>
|
||||
<name>ch.psi.fda.cdump</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
@@ -0,0 +1,3 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding//src/test/java=UTF-8
|
||||
5
ch.psi.fda.cdump/.settings/org.eclipse.jdt.core.prefs
Normal file
5
ch.psi.fda.cdump/.settings/org.eclipse.jdt.core.prefs
Normal file
@@ -0,0 +1,5 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
|
||||
org.eclipse.jdt.core.compiler.compliance=1.7
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.7
|
||||
177
ch.psi.fda.cdump/Readme.md
Normal file
177
ch.psi.fda.cdump/Readme.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# Overview
|
||||
Cdump enables users to record data via an ADC in a continuous way. Cdump requires a special IOC based configuration.
|
||||
|
||||
The basic setup and function of cdump is as follows:
|
||||
|
||||
```
|
||||
IOC
|
||||
[waveform (adcData)] < data
|
||||
[sampling rate (smplRate)] < set/control sampling rate of the controller
|
||||
[command (adcCmd)] < start stop acquisition process
|
||||
```
|
||||
|
||||
There are 3 channels on the IOC. One for the data, and 2 for controlling the acquisition.
|
||||
|
||||
|
||||
# Usage
|
||||
To start the cdump client use the provided `bin/cdump` executable.
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
bin/cdump
|
||||
Usage: cdump <samplingRate> <datafilename>
|
||||
Supported rates: 1Hz 2Hz 5Hz 10Hz 20Hz 50Hz 100Hz 200Hz 500Hz 1kHz 2kHz 5kHz 10kHz 20kHz 50kHz 100kHz
|
||||
```
|
||||
|
||||
|
||||
# Installation
|
||||
## Client
|
||||
Cdump is provided as a single zip file. To install extract the file at any location on your file system.
|
||||
The zip will include a `bin` and `lib` directory holding the executable and required libraries.
|
||||
|
||||
### Configuration
|
||||
The cdump config file can be specified with the following vm option: `-Dch.psi.fda.cdump.config.file=<file>`.
|
||||
|
||||
## IOC
|
||||
There need to be a special IOC based installation/configuration for Cdump.
|
||||
|
||||
***The number of channels that the logic will read out is fixed in through the configuration in the substitution file.
|
||||
Depending on the number of configured channels and the update rate chosen, this logic might bring a lot of load to
|
||||
the IOC once it is started! Always monitor the IOC load while running a "scan". Also, only configure as many channels
|
||||
as really needed for an experiment!***
|
||||
|
||||
### Template (adcRT.template)
|
||||
|
||||
```
|
||||
record(waveform,"$(SYSTEM):convWf$(CARD)-0") {
|
||||
field(DTYP,"Adc8401Rt")
|
||||
field(INP, "#C$(SLOT) S0 @$(CARD)")
|
||||
field(NELM,"327680") # Include first 5 channels (5*65536) in the waveform
|
||||
field(FTVL,"USHORT")
|
||||
field(SCAN,"I/O Intr")
|
||||
}
|
||||
|
||||
record(bo,"$(SYSTEM):SWTRIG$(CARD)") {
|
||||
field(DESC,"soft trig")
|
||||
field(DTYP,"Adc8401Rt")
|
||||
field(OUT, "#C$(SLOT) S @$(CARD)ST")
|
||||
field(SCAN,"Passive")
|
||||
field(ONAM,"GO")
|
||||
field(ZNAM,"READY")
|
||||
}
|
||||
|
||||
record(bo,"$(SYSTEM):ARMadc$(CARD)") {
|
||||
field(DESC,"arm adc")
|
||||
field(DTYP,"Adc8401Rt")
|
||||
field(OUT, "#C$(SLOT) S @$(CARD)AR")
|
||||
field(SCAN,"Passive")
|
||||
field(ONAM,"GO")
|
||||
field(ZNAM,"READY")
|
||||
}
|
||||
|
||||
# Record to set clock frequency of the ADC card - i.e. sampling rate
|
||||
record(ao,"$(SYSTEM):CLOCK-SET$(CARD)") {
|
||||
field(DESC,"sampling clock")
|
||||
field(DTYP,"Adc8401Rt")
|
||||
field(HOPR,"15")
|
||||
field(LOPR,"0")
|
||||
field(OUT, "#C$(SLOT) S @$(CARD)CK")
|
||||
field(VAL,"13")
|
||||
field(PINI,"YES")
|
||||
}
|
||||
|
||||
# Easy to use record to set clock frequency of the ADC card
|
||||
record (mbbo,"$(SYSTEM):CLOCK-FREQ$(CARD)")
|
||||
{
|
||||
field (DESC,"Sampling clock freq.")
|
||||
field (DTYP,"Soft Channel")
|
||||
field (NOBT,"4")
|
||||
field (OUT,"$(SYSTEM):CLOCK-SET$(CARD) PP")
|
||||
field (ZRVL,"1")
|
||||
field (ZRST,"1 Hz")
|
||||
field (ONVL,"2")
|
||||
field (ONST,"2 Hz")
|
||||
field (TWVL,"5")
|
||||
field (TWST,"5 Hz")
|
||||
field (THVL,"10")
|
||||
field (THST,"10 Hz")
|
||||
field (FRVL,"20")
|
||||
field (FRST,"20 Hz")
|
||||
field (FVVL,"50")
|
||||
field (FVST,"50 Hz")
|
||||
field (SXVL,"100")
|
||||
field (SXST,"100 Hz")
|
||||
field (SVVL,"200")
|
||||
field (SVST,"200 Hz")
|
||||
field (EIVL,"500")
|
||||
field (EIST,"500 Hz")
|
||||
field (NIVL,"1000")
|
||||
field (NIST,"1 kHz")
|
||||
field (TEVL,"2000")
|
||||
field (TEST,"2 kHz")
|
||||
field (ELVL,"5000")
|
||||
field (ELST,"5 kHz")
|
||||
field (TVVL,"10000")
|
||||
field (TVST,"10 kHz")
|
||||
field (TTVL,"20000")
|
||||
field (TTST,"20 kHz")
|
||||
field (FTVL,"50000")
|
||||
field (FTST,"50 kHz")
|
||||
field (FFVL,"100000")
|
||||
field (FFST,"100 kHz")
|
||||
field (PINI,"YES")
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Substitution File (adc.subs)
|
||||
|
||||
```
|
||||
file adcRT_continuous.template
|
||||
{ pattern
|
||||
{ SYSTEM, SLOT, CARD}
|
||||
{ "X10DA-ES1-DMA", "6", "2"} # SLOT is VME slot = 1,2,3,4... CARD is A,B,C,D position on the IP carrier
|
||||
}
|
||||
```
|
||||
|
||||
### Startup Script
|
||||
|
||||
```
|
||||
require "ADC8401RT", "test"
|
||||
|
||||
#vicb8002* configCarrier8004(
|
||||
# int vmeSlot, /* = carrierCardNumber */
|
||||
# unsigned long memBaseAddr,
|
||||
# unsigned short intrLevel)
|
||||
|
||||
#adc8401rt* addADC8401RTipac(
|
||||
# unsigned short ipacArea, /* A=0, B=1, C=2, D=3 as after @ of INP/OUT field */
|
||||
# int vmeSlot,
|
||||
# int intrVector, /* interrupt vector */
|
||||
# unsigned short trigMode, /* 0 = free-running, 1 = triggered */
|
||||
# unsigned short clkSrc, /* 0 = internal, 1 = external */
|
||||
# unsigned short clockRate, /*
|
||||
# 0 = 1Hz, 1 = 2Hz
|
||||
# 2 = 5Hz, 3 = 10Hz
|
||||
# 4 = 20Hz, 5 = 50Hz
|
||||
# 6 = 100Hz, 7 = 200Hz
|
||||
# 8 = 500Hz, 9 = 1000Hz
|
||||
# 10 = 2000Hz, 11 = 5000Hz
|
||||
# 12 = 10000Hz, 13 = 20000Hz
|
||||
# 14 = 50000Hz, 15 = 100000Hz */
|
||||
# unsigned short samples) /* number of samples for single-shot
|
||||
NOTE: if continuous --> samples=64K --> 65536 */
|
||||
|
||||
# 8404 carrier board (with DMA) at VME slot #6
|
||||
configCarrier8004(6, 0x01800000, 4)
|
||||
|
||||
# ADC at carrier pos. C (2) at VME slot #6
|
||||
# Configure for continuous waveform 64k bins
|
||||
addADC8401RTipac(2, 6, 0xc2, 0, 0, 13, 65536)
|
||||
```
|
||||
|
||||
# Development
|
||||
To build and package the cdump code use `mvn clean compile assembly:assembly` . This will generate a all in one zip file in the `/target` directory.
|
||||
|
||||
To upload the latest version to the artifact repository use ` mvn clean compile deploy`.
|
||||
93
ch.psi.fda.cdump/pom.xml
Normal file
93
ch.psi.fda.cdump/pom.xml
Normal file
@@ -0,0 +1,93 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>ch.psi</groupId>
|
||||
<artifactId>ch.psi.fda.cdump</artifactId>
|
||||
<version>2.3.4</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ch.psi</groupId>
|
||||
<artifactId>ch.psi.fda.core</artifactId>
|
||||
<version>2.3.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
<version>1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.psi</groupId>
|
||||
<artifactId>jcae</artifactId>
|
||||
<version>2.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.8.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<encoding>UTF-8</encoding>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<distributionManagement>
|
||||
<snapshotRepository>
|
||||
<id>i.snapshots</id>
|
||||
<name>Artifactory Snapshots</name>
|
||||
<url>http://yoke.psi.ch:8081/artifactory/libs-snapshots-local</url>
|
||||
</snapshotRepository>
|
||||
<repository>
|
||||
<id>i.releases</id>
|
||||
<name>Atrifactory Releases</name>
|
||||
<url>http://yoke.psi.ch:8081/artifactory/libs-snapshots-local</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</project>
|
||||
35
ch.psi.fda.cdump/src/main/assembly/assembly.xml
Normal file
35
ch.psi.fda.cdump/src/main/assembly/assembly.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<assembly>
|
||||
<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>
|
||||
<fileMode>0755</fileMode>
|
||||
<directory>src/main/assembly/config</directory>
|
||||
<outputDirectory>config</outputDirectory>
|
||||
<includes>
|
||||
<include>*</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@@ -35,4 +35,4 @@ do
|
||||
done
|
||||
|
||||
# Execute java
|
||||
java $VM_ARGUMENTS -Dch.psi.cdump.home=$BASEDIR/../.. -cp $CLASSPATH ch.psi.cdump.CdumpMain $ARGUMENTS
|
||||
java $VM_ARGUMENTS -Dch.psi.fda.cdump.config.file=$BASEDIR/../../config/cdump.properties -cp $CLASSPATH ch.psi.fda.cdump.ui.CdumpMain $ARGUMENTS
|
||||
@@ -0,0 +1,4 @@
|
||||
#ch.psi.fda.cdump.dataChannel=
|
||||
#ch.psi.fda.cdump.nelements=65536
|
||||
#ch.psi.fda.cdump.controlChannel=
|
||||
#ch.psi.fda.cdump.samplingRateChannel=
|
||||
151
ch.psi.fda.cdump/src/main/java/ch/psi/fda/cdump/Cdump.java
Normal file
151
ch.psi.fda.cdump/src/main/java/ch/psi/fda/cdump/Cdump.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import ch.psi.jcae.Channel;
|
||||
import ch.psi.jcae.ChannelDescriptor;
|
||||
import ch.psi.jcae.ChannelException;
|
||||
import ch.psi.jcae.ChannelService;
|
||||
|
||||
/**
|
||||
* Cdump readout logic - i.e. put monitor on a data waveform channel of the fast
|
||||
* ADC and send data to the eventbus
|
||||
*/
|
||||
public class Cdump {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(Cdump.class.getName());
|
||||
|
||||
public final static String[] SAMPLING_RATES = new String[] {"1Hz","2Hz", "5Hz", "10Hz", "20Hz", "50Hz", "100Hz", "200Hz", "500Hz",
|
||||
"1kHz", "2kHz", "5kHz", "10kHz", "20kHz", "50kHz", "100kHz"};
|
||||
|
||||
private Channel<int[]> adcData;
|
||||
|
||||
private enum AdcCmd {
|
||||
READY, GO
|
||||
};
|
||||
|
||||
private Channel<Integer> adcCmd;
|
||||
|
||||
private CdumpListener listener;
|
||||
private ChannelService cservice;
|
||||
private CdumpConfiguration configuration;
|
||||
|
||||
public Cdump(ChannelService cservice, EventBus ebus, CdumpConfiguration configuration) {
|
||||
this.cservice = cservice;
|
||||
this.configuration = configuration;
|
||||
this.listener = new CdumpListener(ebus, configuration.getNelements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire data with the given sampling rate
|
||||
* @param samplingRate
|
||||
*/
|
||||
public void acquire(String samplingRate) {
|
||||
|
||||
logger.info("Start acquisition with sampling rate "+ samplingRate);
|
||||
|
||||
try {
|
||||
// Set ADC sampling rate
|
||||
Channel<Integer> smplRate = cservice.createChannel(new ChannelDescriptor<>(Integer.class, configuration.getSamplingRateChannel(), false));
|
||||
smplRate.setValue(getIntSamplingRate(samplingRate));
|
||||
smplRate.destroy();
|
||||
|
||||
adcData = cservice.createChannel(new ChannelDescriptor<>(int[].class, configuration.getDataChannel(), true));
|
||||
adcCmd = cservice.createChannel(new ChannelDescriptor<>(Integer.class, configuration.getControlChannel(), false));
|
||||
|
||||
adcCmd.setValue(AdcCmd.GO.ordinal());
|
||||
adcData.addPropertyChangeListener(listener);
|
||||
} catch (ChannelException | TimeoutException | InterruptedException | ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until acquire is done
|
||||
*/
|
||||
public void waitAcquireDone(){
|
||||
try {
|
||||
adcCmd.waitForValue(AdcCmd.READY.ordinal());
|
||||
} catch (InterruptedException | ExecutionException | ChannelException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
|
||||
logger.info("Stop acquisition");
|
||||
|
||||
try {
|
||||
// Detach listener from channel - i.e. stop data acquisition
|
||||
adcData.removePropertyChangeListener(listener);
|
||||
adcCmd.setValue(AdcCmd.READY.ordinal());
|
||||
|
||||
listener.terminate();
|
||||
|
||||
adcCmd.destroy();
|
||||
adcData.destroy();
|
||||
} catch (ChannelException | InterruptedException | ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sampling rate int value based on the passed rate string.
|
||||
* If the string does not match any of the strings specified in the rates variable
|
||||
* this function will set the rate to 1Hz
|
||||
*
|
||||
* 0 = 1Hz
|
||||
* 1 = 2Hz
|
||||
* 2 = 5Hz
|
||||
* 3 = 10Hz
|
||||
* 4 = 20Hz
|
||||
* 5 = 50Hz
|
||||
* 6 = 100Hz
|
||||
* 7 = 200Hz
|
||||
* 8 = 500Hz
|
||||
* 9 = 1000Hz
|
||||
* 10 = 2000Hz
|
||||
* 11 = 5000Hz
|
||||
* 12 = 10000Hz
|
||||
* 13 = 20000Hz
|
||||
* 14 = 50000Hz
|
||||
* 15 = 100000Hz
|
||||
*
|
||||
* @param rate
|
||||
*/
|
||||
private int getIntSamplingRate(String rate){
|
||||
|
||||
for(int i=0;i<SAMPLING_RATES.length; i++){
|
||||
if(rate.equals(SAMPLING_RATES[i])){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// Default sampling rate 10kHz
|
||||
logger.info("Using default sampling rate 12");
|
||||
return 12;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
|
||||
public class CdumpConfiguration {
|
||||
|
||||
public final static String CDUMP_CONFIG = "ch.psi.fda.cdump.config.file";
|
||||
|
||||
private String dataChannel;
|
||||
private int nelements = 65536;
|
||||
private String controlChannel;
|
||||
private String samplingRateChannel;
|
||||
|
||||
public CdumpConfiguration(){
|
||||
String config = System.getProperty(CDUMP_CONFIG);
|
||||
|
||||
if(config != null){
|
||||
loadFile(new File(config));
|
||||
}
|
||||
else{
|
||||
throw new RuntimeException("No configuration file specified via -D"+CDUMP_CONFIG+"=...");
|
||||
}
|
||||
}
|
||||
|
||||
public void loadFile(File file) {
|
||||
Properties properties = new Properties();
|
||||
|
||||
if(file!=null){
|
||||
try {
|
||||
properties.load(new FileReader(file));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Cannot read file "+file, e);
|
||||
}
|
||||
}
|
||||
|
||||
dataChannel = properties.getProperty(CdumpConfiguration.class.getPackage().getName()+".dataChannel", "");
|
||||
controlChannel = properties.getProperty(CdumpConfiguration.class.getPackage().getName()+".controlChannel", "");
|
||||
samplingRateChannel = properties.getProperty(CdumpConfiguration.class.getPackage().getName()+".samplingRateChannel", "");
|
||||
nelements = Integer.parseInt(properties.getProperty(CdumpConfiguration.class.getPackage().getName()+".nelements", "65536"));
|
||||
|
||||
}
|
||||
|
||||
public String getDataChannel() {
|
||||
return dataChannel;
|
||||
}
|
||||
public void setDataChannel(String dataChannel) {
|
||||
this.dataChannel = dataChannel;
|
||||
}
|
||||
public String getControlChannel() {
|
||||
return controlChannel;
|
||||
}
|
||||
public void setControlChannel(String controlChannel) {
|
||||
this.controlChannel = controlChannel;
|
||||
}
|
||||
public String getSamplingRateChannel() {
|
||||
return samplingRateChannel;
|
||||
}
|
||||
public void setSamplingRateChannel(String samplingRateChannel) {
|
||||
this.samplingRateChannel = samplingRateChannel;
|
||||
}
|
||||
public int getNelements() {
|
||||
return nelements;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package ch.psi.fda.cdump;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import ch.psi.fda.EContainer;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.serializer.SerializerTXT;
|
||||
import ch.psi.jcae.ChannelService;
|
||||
|
||||
public class CdumpEContainer implements EContainer {
|
||||
|
||||
private final ChannelService cservice;
|
||||
private final CdumpEDescriptor edescriptor;
|
||||
private final EventBus eventbus;
|
||||
|
||||
private Cdump cdump;
|
||||
private SerializerTXT serializer;
|
||||
|
||||
private volatile boolean running = false;
|
||||
|
||||
public CdumpEContainer(ChannelService cservice, EventBus eventbus, CdumpEDescriptor edescriptor) {
|
||||
this.cservice = cservice;
|
||||
this.eventbus = eventbus;
|
||||
this.edescriptor = edescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
cdump = new Cdump(cservice, eventbus, new CdumpConfiguration());
|
||||
|
||||
File file = new File(edescriptor.getFileName());
|
||||
file.getParentFile().mkdirs(); // Create data base directory
|
||||
|
||||
serializer = new SerializerTXT(file);
|
||||
serializer.setShowDimensionHeader(false);
|
||||
|
||||
eventbus.register(serializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
running = true;
|
||||
try{
|
||||
cdump.acquire(edescriptor.getSamplingRate());
|
||||
cdump.waitAcquireDone();
|
||||
}
|
||||
finally{
|
||||
running=false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort() {
|
||||
eventbus.post(new EndOfStreamMessage());
|
||||
cdump.stop();
|
||||
running = false;
|
||||
|
||||
eventbus.unregister(serializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return running;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
abort();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package ch.psi.fda.cdump;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import ch.psi.fda.EContainer;
|
||||
import ch.psi.fda.EContainerFactory;
|
||||
import ch.psi.fda.edescriptor.EDescriptor;
|
||||
import ch.psi.jcae.ChannelService;
|
||||
|
||||
public class CdumpEContainerFactory implements EContainerFactory {
|
||||
|
||||
@Inject
|
||||
private ChannelService cservice;
|
||||
|
||||
@Override
|
||||
public boolean supportsEDescriptor(EDescriptor descriptor) {
|
||||
return descriptor instanceof CdumpEDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EContainer getEContainer(EDescriptor descriptor, EventBus bus) {
|
||||
return new CdumpEContainer(cservice, bus, (CdumpEDescriptor) descriptor);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package ch.psi.fda.cdump;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import ch.psi.fda.edescriptor.EDescriptor;
|
||||
|
||||
@XmlRootElement(name="cdump")
|
||||
public class CdumpEDescriptor implements EDescriptor {
|
||||
|
||||
private String samplingRate;
|
||||
private String fileName;
|
||||
|
||||
public String getSamplingRate() {
|
||||
return samplingRate;
|
||||
}
|
||||
public void setSamplingRate(String samplingRate) {
|
||||
this.samplingRate = samplingRate;
|
||||
}
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package ch.psi.fda.cdump;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
|
||||
import ch.psi.fda.DescriptorProvider;
|
||||
import ch.psi.fda.edescriptor.EDescriptor;
|
||||
import ch.psi.fda.vdescriptor.VDescriptor;
|
||||
|
||||
public class CdumpEDescriptorProvider implements DescriptorProvider {
|
||||
|
||||
private EDescriptor edescriptor;
|
||||
|
||||
@Override
|
||||
public void load(File... files) {
|
||||
try {
|
||||
JAXBContext context = JAXBContext.newInstance(CdumpEDescriptor.class);
|
||||
Unmarshaller u = context.createUnmarshaller();
|
||||
edescriptor = (EDescriptor) u.unmarshal(files[0]);
|
||||
} catch (JAXBException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public EDescriptor getEDescriptor() {
|
||||
return edescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VDescriptor getVDescriptor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getEDescriptorClass() {
|
||||
return CdumpEDescriptor.class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ch.psi.fda.messages.DataMessage;
|
||||
import ch.psi.fda.messages.EndOfStreamMessage;
|
||||
import ch.psi.fda.messages.Metadata;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* Listener that monitors the adc data channel and splitting up the data
|
||||
*/
|
||||
public class CdumpListener implements PropertyChangeListener {
|
||||
|
||||
private final EventBus bus;
|
||||
private final int numberOfElements;
|
||||
|
||||
private boolean first = true;
|
||||
private int numberOfWaveforms = 0;
|
||||
private final List<Metadata> metadata = new ArrayList<>();
|
||||
|
||||
public CdumpListener(EventBus bus, int numberOfElements){
|
||||
this.bus = bus;
|
||||
this.numberOfElements = numberOfElements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if(evt.getPropertyName().equals("value")){
|
||||
transform((int[]) evt.getNewValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transform received waveform
|
||||
* 1. Take channel waveform
|
||||
* [wavefrom .......................................................]
|
||||
* 2. Split up waveform
|
||||
* [1-number of elements][2-number of elements][3-number of elements]
|
||||
* 3. Rotate splitted waveforms
|
||||
* [1-0,2-0,3-0] thats one message
|
||||
* [1-1,2-1,3-1]
|
||||
* ...
|
||||
* [1-noe, 2-noe, 3-noe]
|
||||
*
|
||||
*/
|
||||
public void transform(int[] value){
|
||||
|
||||
// The first time check whether received waveform is a multiple of the specified number of elements number
|
||||
// Calculate how many waveforms are within the received waveform
|
||||
if(first){
|
||||
first=false;
|
||||
int nelements = value.length;
|
||||
int n = nelements % numberOfElements;
|
||||
if (n != 0) {
|
||||
throw new RuntimeException("Array size is not a multiple of "+numberOfElements);
|
||||
}
|
||||
numberOfWaveforms = nelements / numberOfElements;
|
||||
for(int i=0;i<numberOfWaveforms;i++){
|
||||
metadata.add(new Metadata("waveform-"+i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Split and rotate waveform
|
||||
for (int x = 0; x < numberOfElements; x++) {
|
||||
|
||||
DataMessage m = new DataMessage(metadata);
|
||||
for (int t = 0; t < numberOfWaveforms; t++) {
|
||||
m.getData().add(value[x + t * numberOfElements]);
|
||||
}
|
||||
bus.post(m);
|
||||
}
|
||||
}
|
||||
|
||||
public void terminate(){
|
||||
bus.post(new EndOfStreamMessage());
|
||||
}
|
||||
}
|
||||
@@ -17,38 +17,34 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.psi.cdump;
|
||||
|
||||
import gov.aps.jca.CAException;
|
||||
package ch.psi.fda.cdump.ui;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import ch.psi.jcae.ChannelBeanFactory;
|
||||
import com.google.common.eventbus.AsyncEventBus;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import ch.psi.fda.cdump.Cdump;
|
||||
import ch.psi.fda.cdump.CdumpConfiguration;
|
||||
import ch.psi.fda.serializer.SerializerTXT;
|
||||
import ch.psi.jcae.ChannelService;
|
||||
import ch.psi.jcae.impl.DefaultChannelService;
|
||||
import sun.misc.Signal;
|
||||
import sun.misc.SignalHandler;
|
||||
|
||||
/**
|
||||
* @author ebner
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class CdumpMain {
|
||||
|
||||
// Get Logger
|
||||
private static final Logger logger = Logger.getLogger(CdumpMain.class.getName());
|
||||
|
||||
public static void main(String[] args){
|
||||
|
||||
|
||||
RunConfiguration c = new RunConfiguration();
|
||||
final ChannelService cservice = new DefaultChannelService();
|
||||
|
||||
if(args.length != 2){
|
||||
System.err.println("Usage: cdump <samplingRate> <datafilename>");
|
||||
StringBuilder b = new StringBuilder();
|
||||
for(String s: RunConfiguration.rates){
|
||||
for(String s: Cdump.SAMPLING_RATES){
|
||||
b.append(s);
|
||||
b.append(" ");
|
||||
}
|
||||
@@ -56,22 +52,23 @@ public class CdumpMain {
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
c.setSamplingRate(args[0]);
|
||||
String samplingRate = args[0];
|
||||
|
||||
// Calculate data file location/name
|
||||
String fname = args[1];
|
||||
CdumpConfiguration cc = CdumpConfiguration.getInstance();
|
||||
String d = cc.getDataDirectory()+"/"+cc.replaceMacros(cc.getFilePrefix(), new Date(), fname)+fname+".txt";
|
||||
File f = new File(d);
|
||||
|
||||
File f = new File(fname);
|
||||
f.getParentFile().mkdirs(); // Create data base directory
|
||||
// Set file to save data
|
||||
logger.info("Set data file to: "+f.getAbsolutePath());
|
||||
c.setDatafile(f);
|
||||
|
||||
// Create execution service
|
||||
final CdumpService service = new CdumpService();
|
||||
EventBus eventbus = new AsyncEventBus(Executors.newSingleThreadExecutor());
|
||||
final Cdump service = new Cdump(cservice, eventbus, new CdumpConfiguration());
|
||||
|
||||
SerializerTXT serializer = new SerializerTXT(f);
|
||||
serializer.setShowDimensionHeader(false);
|
||||
|
||||
eventbus.register(serializer);
|
||||
|
||||
// Stop/abort handling of acquisition
|
||||
Signal.handle(new Signal("INT"), new SignalHandler() {
|
||||
/**
|
||||
@@ -98,22 +95,13 @@ public class CdumpMain {
|
||||
System.exit(2);
|
||||
}
|
||||
|
||||
service.stopAcquisition();
|
||||
service.stop();
|
||||
|
||||
// Destroy jca context to let the program abort
|
||||
try {
|
||||
ChannelBeanFactory.getFactory().getChannelFactory().destroyContext();
|
||||
} catch (IllegalStateException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (CAException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
cservice.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
// Take data
|
||||
service.startAcquisition(c);
|
||||
|
||||
service.acquire(samplingRate);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
ch.psi.fda.cdump.CdumpEDescriptorProvider
|
||||
@@ -0,0 +1 @@
|
||||
ch.psi.fda.cdump.CdumpEContainerFactory
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ch.psi.fda.messages.Message;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
public class CdumpListenerTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
EventBus bus = new EventBus();
|
||||
|
||||
bus.register(new Object(){
|
||||
@Subscribe
|
||||
public void onMessage(Message m){
|
||||
System.out.println(m);
|
||||
}
|
||||
});
|
||||
|
||||
CdumpListener l = new CdumpListener(bus, 4);
|
||||
l.transform(new int[] {1,2,3,4,11,12,13,14});
|
||||
l.transform(new int[] {5,6,7,8,15,16,17,18});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
*
|
||||
* 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.cdump;
|
||||
|
||||
import gov.aps.jca.cas.ProcessVariable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import ch.psi.jcae.cas.CaServer;
|
||||
import ch.psi.jcae.cas.ProcessVariableInt;
|
||||
import ch.psi.jcae.cas.ProcessVariableIntWaveform;
|
||||
|
||||
public class CdumpTestIOC {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(CdumpTestIOC.class.getName());
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
List<ProcessVariable> processVariables = new ArrayList<ProcessVariable>();
|
||||
|
||||
// Data channel
|
||||
ProcessVariableIntWaveform pv = new ProcessVariableIntWaveform("CDUMP:WAVE", null, 8);
|
||||
processVariables.add(pv);
|
||||
|
||||
// This PV has the states READY (0) and GO (1)
|
||||
ProcessVariableInt pvControl = new ProcessVariableInt("CDUMP:CONTROL", null);
|
||||
processVariables.add(pvControl);
|
||||
|
||||
// Sampling rate channel
|
||||
//{"1Hz","2Hz", "5Hz", "10Hz", "20Hz", "50Hz", "100Hz", "200Hz", "500Hz", "1kHz", "2kHz", "5kHz", "10kHz", "20kHz", "50kHz", "100kHz"};
|
||||
ProcessVariableInt pvSamplingRate = new ProcessVariableInt("CDUMP:SAMPLING", null);
|
||||
processVariables.add(pvSamplingRate);
|
||||
|
||||
|
||||
CaServer s = new CaServer(processVariables);
|
||||
s.startAsDaemon();
|
||||
|
||||
Deque<int[]> deque = new LinkedList<int[]>();
|
||||
deque.push(new int[] { 1, 2, 3, 4, 11, 12, 13, 14 });
|
||||
deque.push(new int[] { 5, 6, 7, 8, 15, 16, 17, 18 });
|
||||
|
||||
while (true) {
|
||||
if (pvControl.getValue() == 1) { // if control channel is on GO
|
||||
int[] v = deque.pollFirst();
|
||||
logger.finest(Arrays.toString(v));
|
||||
pv.setValue(v);
|
||||
|
||||
deque.addLast(v);
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
4
ch.psi.fda.cdump/src/test/resources/cdump.properties
Normal file
4
ch.psi.fda.cdump/src/test/resources/cdump.properties
Normal file
@@ -0,0 +1,4 @@
|
||||
ch.psi.fda.cdump.dataChannel=CDUMP:WAVE
|
||||
ch.psi.fda.cdump.controlChannel=CDUMP:CONTROL
|
||||
ch.psi.fda.cdump.samplingRateChannel=CDUMP:SAMPLING
|
||||
ch.psi.fda.cdump.nelements=4
|
||||
Reference in New Issue
Block a user