Compare commits

34 Commits

Author SHA1 Message Date
8ab98e72c1 Added visualization to Fdaq 2014-08-29 16:29:08 +02:00
9f7f6dd84f Several bug fixes and small improvements 2014-08-28 14:26:31 +02:00
cd2ba11e98 fixed upload url pom 2014-07-28 11:57:36 +02:00
4929add1ab Updated hostname repository 2014-07-24 14:33:08 +02:00
9a52acf8b6 Updated version
Fixed javadoc
2014-05-12 11:12:31 +02:00
305e692270 Fixed termination of scan 2014-05-05 13:06:56 +02:00
4d8673e6e4 cleaned up cdump stuff 2014-04-30 08:33:59 +02:00
e72a5cc9e0 moved entry class, ... 2014-04-30 08:16:11 +02:00
58fa3d7a21 removed comments 2014-04-30 07:54:57 +02:00
1b98a5492d removed unnecessary config 2014-04-30 07:53:39 +02:00
20d5842510 configuration file 2014-04-29 11:51:19 +02:00
caa1c64fec renamed config file properties 2014-04-29 11:49:52 +02:00
02633139df removed stop() function from econtainer 2014-04-29 11:06:39 +02:00
c1441bdb5f updates 2014-04-28 16:05:44 +02:00
eb3fbcdab9 Added EDescriptor and EContainer interfaces so that it is able to be
easily integrated into fda ...
2014-04-28 10:52:25 +02:00
3d09aaf9b9 improved cdump 2014-04-28 09:25:14 +02:00
b77d8737ea build and upload of 1.0.1 package 2014-01-14 11:06:39 +01:00
b66085f7bd Updated documentation
Started FDA-104 - creating test ioc
2014-01-14 11:01:21 +01:00
9de1bf81f3 Updated readme on how to upload artifact to repository 2013-12-20 14:53:51 +01:00
eb1b79279e show not dimension header when writing file 2013-12-20 14:40:03 +01:00
6fc705a3d3 commented entries in properties file so that software defaults take
effect
2013-12-18 15:33:54 +01:00
4fde67bb78 Populated properties file with examples 2013-12-18 15:33:07 +01:00
bf623657ae Changed way configuration works 2013-12-18 15:29:15 +01:00
4b66cb27dc fixed start script and main 2013-12-18 15:06:03 +01:00
595119f705 Major reconstruction of the classes. Unnecessary classes were removed
and code was streamlined.
FDA-99
2013-12-18 15:01:18 +01:00
fc28ffad2f Removed unused / non functioning UI classes
FDA-99
2013-12-18 12:58:20 +01:00
1806a66ea6 renamed project directory 2013-12-18 12:43:02 +01:00
bb31a1ec1f renamed packages and project to include fda ..
FDA-99
2013-12-18 12:42:17 +01:00
54561c1957 cleanup ... 2013-10-23 09:54:19 +02:00
97a1dc9e65 Update readme 2013-10-16 09:48:18 +02:00
f0623e7453 update markup 2013-10-16 09:36:56 +02:00
03cd2f5b50 update 2013-10-16 09:34:54 +02:00
e7a8c60616 Update readme 2013-10-16 09:34:04 +02:00
6f691e1708 Use of EventBus instead of queues 2013-10-16 09:27:03 +02:00
41 changed files with 1017 additions and 1173 deletions

View File

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

View File

@@ -1,3 +0,0 @@
#Wed Oct 12 13:39:19 CEST 2011
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +0,0 @@
ch.psi.cdump.dataChannel=
ch.psi.cdump.controlChannel=
ch.psi.cdump.samplingRateChannel=

View File

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

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

View File

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

View File

@@ -0,0 +1,3 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8

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

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1 @@
ch.psi.fda.cdump.CdumpEDescriptorProvider

View File

@@ -0,0 +1 @@
ch.psi.fda.cdump.CdumpEContainerFactory

View File

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

View File

@@ -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) {
}
}
}
}

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