15 Commits

Author SHA1 Message Date
ebner ed35d4c922 Some performance test changes 2014-03-18 13:56:47 +01:00
ebner bc316bd710 renamed FdaqService to Fdaq 2014-03-18 12:46:36 +01:00
ebner 32406110b3 Discard first 1028 values
Added file exist check
Configured serializer to not append _0000 to the file name
2014-02-14 13:05:16 +01:00
ebner e1fe52473d New request parameter used for reading out data (reset) 2014-02-04 10:29:18 +01:00
ebner dedb9b62fd Fixed some more stuff 2014-01-23 15:22:54 +01:00
ebner c51d8dba5f fixed wrong argument parsing (array out of bounds) 2014-01-23 14:44:15 +01:00
ebner 79be3f392a New version 2014-01-22 13:30:33 +01:00
ebner 7ba589feba FDA-105
FDAQ is now configurable
2014-01-22 13:29:07 +01:00
ebner 10072d2c85 removed explicit stop command from cli client 2014-01-22 11:11:12 +01:00
ebner 8443ea7a11 Updated version
Updated readme
2014-01-22 11:04:15 +01:00
ebner 4cfad555fd Update readme 2014-01-22 11:01:34 +01:00
ebner 55689fd464 FDA-109
FDA-108
2014-01-22 11:00:29 +01:00
ebner e915cbc783 build and upload of 1.0.1 version 2014-01-14 11:08:06 +01:00
ebner 4c4c6de419 Added method to check whether fdaq is running 2014-01-09 09:42:33 +01:00
ebner 01260abfa1 updated version 2013-12-20 15:12:13 +01:00
7 changed files with 371 additions and 205 deletions
+19 -6
View File
@@ -11,14 +11,12 @@ and it can send a reset request on the reset channel.
To acquire data into a file use: To acquire data into a file use:
``` ```
java -jar java -jar ch.psi.fda.fdaq-<version>.jar acquire <file> java -jar ch.psi.fda.fdaq-<version>.jar <file>
``` ```
Send stop/reset request (to abort an data collection) You can terminate the acquisition with *CTRL+C*. If you submit 2 consequtive *CTRL+C* the program will terminate immediately (and data might be lost);
```
java -jar java -jar ch.psi.fda.fdaq-<version>.jar stop
```
This will take the default connections settings: This will take the default connections settings:
@@ -27,8 +25,23 @@ This will take the default connections settings:
* Kill Port: 2234 * Kill Port: 2234
* Number Of Elements: Integer.MAX_VALUE/2 * Number Of Elements: Integer.MAX_VALUE/2
If you need to specify different settings create a property files with following content:
```
ch.psi.fda.fdaq.hostname=myhost
ch.psi.fda.fdaq.port=1234
ch.psi.fda.fdaq.killPort=4321
```
Use `-Dch.psi.fda.fdaq.config=<file>` to use this property file as base configuration.
# Development # Development
A standalone jar can be build via `mvn clean compile assembly:single`. A standalone jar can be build via `mvn clean compile assembly:single`.
To upload the latest version to the artifact repository use ` mvn clean compile deploy`. To upload the latest version to the artifact repository use ` mvn clean compile deploy`.
# Notes
Trigger port is `Trigger In 1`. For testing apply a 1kHz signal.
+1 -1
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>ch.psi</groupId> <groupId>ch.psi</groupId>
<artifactId>ch.psi.fda.fdaq</artifactId> <artifactId>ch.psi.fda.fdaq</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>1.0.9</version>
<dependencies> <dependencies>
<dependency> <dependency>
@@ -0,0 +1,165 @@
/**
*
* 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.fdaq;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.common.eventbus.EventBus;
import ch.psi.fda.messages.DataMessage;
import ch.psi.fda.messages.EndOfStreamMessage;
import ch.psi.fda.messages.Metadata;
/**
* Fdaq service
*
*/
public class Fdaq {
private static final Logger logger = Logger.getLogger(Fdaq.class.getName());
private volatile boolean stopAcquisition = false;
private volatile boolean running = false;
private final EventBus bus;
private FdaqConfiguration configuration;
private final int numberOfElements = Integer.MAX_VALUE/2;
public Fdaq(EventBus bus, FdaqConfiguration configuration){
this.bus = bus;
this.configuration = configuration;
}
/**
* Acquire data from the fdaq box
* @param hostname
* @param port
* @param numberOfElements
*/
public void acquire() {
running = true; // potential threading problem
Socket echoSocket = null;
DataOutputStream out = null;
DataInputStream in = null;
boolean first = true;
while(running){
try {
stopAcquisition = false;
echoSocket = new Socket(configuration.getHostname(), configuration.getPort());
out = new DataOutputStream(echoSocket.getOutputStream());
in = new DataInputStream(echoSocket.getInputStream());
ByteBuffer bytebuffer = ByteBuffer.allocate(3 * 4); // 3 times Integer
bytebuffer.order(ByteOrder.LITTLE_ENDIAN);
bytebuffer.putInt(26); // Function number (index of pointer to function)
bytebuffer.putInt(numberOfElements);
if(first){
bytebuffer.putInt(1); // Reset FIFO flag - The first time there need to be a 1 in int to reset the fifo buffer on the box
first=false;
}
else{
bytebuffer.putInt(0);
}
out.write(bytebuffer.array());
out.flush();
for (int t = 0; t < numberOfElements; t++) {
// struct fdaqbloc_out {int trigindex;int adc1reg;int
// adc2reg;int encoder;};
ByteBuffer buffer = ByteBuffer.allocate(4 * 4); // 4 times Integers
int r = in.read(buffer.array());
if (r == -1) {
logger.info("End of Stream");
break;
}
if(t<1028){
// The first 1028 are wrong (not really wrong but there are repeated values/holes)
// It has to do with the fact that we asynchronously reset the FIFO.
// This is independent of the frequency
continue;
}
bus.post(buffer);
}
} catch (IOException e) {
// Ignore potential exceptions if stop was triggered before all messages were retrieved
if (!stopAcquisition) {
throw new RuntimeException(e);
}
} finally {
try {
out.close();
in.close();
echoSocket.close();
} catch (IOException e) {
// Ignore because not relevant at this stage
}
}
}
// bus.post(new EndOfStreamMessage());
}
/**
* Sending termination command to fdaq box
*/
public void stop() {
try {
running=false;
stopAcquisition = true;
Socket echoSocket = new Socket(configuration.getHostname(), configuration.getKillPort());
DataOutputStream out = new DataOutputStream(echoSocket.getOutputStream());
ByteBuffer bytebuffer = ByteBuffer.allocate(1 * 4); // 2
// times
// Integers
bytebuffer.order(ByteOrder.LITTLE_ENDIAN);
bytebuffer.putInt(666);
out.write(bytebuffer.array());
out.flush();
out.close();
echoSocket.close();
} catch (IOException e) {
logger.log(Level.SEVERE, "", e);
}
}
public boolean isRunning() {
return running;
}
}
@@ -0,0 +1,74 @@
/**
*
* Copyright 2014 Paul Scherrer Institute. All rights reserved.
*
* This code is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This code is distributed in the hope that it will be useful, but without any
* warranty; without even the implied warranty of merchantability or fitness for
* a particular purpose. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <http://www.gnu.org/licenses/>.
*
*/
package ch.psi.fda.fdaq;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import ch.psi.fda.messages.DataMessage;
import ch.psi.fda.messages.Metadata;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
/**
* Does the bit shuffle required for fdaq.
*/
public class FdaqBitShuffle {
private final EventBus bus;
private final List<Metadata> metadata;
public FdaqBitShuffle(EventBus bus){
this.bus = bus;
metadata = new ArrayList<>();
metadata.add(new Metadata("counter"));
metadata.add(new Metadata("ain1"));
metadata.add(new Metadata("ain2"));
metadata.add(new Metadata("ain3"));
metadata.add(new Metadata("ain4"));
metadata.add(new Metadata("enc1"));
}
@Subscribe
public void shuffle(ByteBuffer buffer){
buffer.order(ByteOrder.LITTLE_ENDIAN);
int a = buffer.getInt();
int b = buffer.getInt();
int b1 = b & 0xffff;
int b2 = (b >> 16) & 0xffff;
int c = buffer.getInt();
int c1 = c & 0xffff;
int c2 = (c >> 16) & 0xffff;
int d = buffer.getInt();
DataMessage message = new DataMessage(metadata);
message.getData().add(a);
message.getData().add(b1);
message.getData().add(b2);
message.getData().add(c1);
message.getData().add(c2);
message.getData().add(d);
bus.post(message);
}
}
@@ -0,0 +1,62 @@
/**
*
* Copyright 2014 Paul Scherrer Institute. All rights reserved.
*
* This code is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This code is distributed in the hope that it will be useful, but without any
* warranty; without even the implied warranty of merchantability or fitness for
* a particular purpose. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <http://www.gnu.org/licenses/>.
*
*/
package ch.psi.fda.fdaq;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
public class FdaqConfiguration {
private String hostname = "mchip015.psi.ch";
private int port = 2233;
private int killPort = 2234;
public void loadFile(File file) {
Properties properties = new Properties();
try {
properties.load(new FileReader(file));
} catch (IOException e) {
throw new RuntimeException("Cannot read file "+file, e);
}
hostname = properties.getProperty(FdaqConfiguration.class.getPackage().getName()+".hostname", hostname);
port = Integer.parseInt(properties.getProperty(FdaqConfiguration.class.getPackage().getName()+".port", port+""));
killPort = Integer.parseInt(properties.getProperty(FdaqConfiguration.class.getPackage().getName()+".killPort", killPort+""));
}
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public int getKillPort() {
return killPort;
}
public void setKillPort(int killPort) {
this.killPort = killPort;
}
}
@@ -21,48 +21,75 @@ package ch.psi.fda.fdaq;
import java.io.File; import java.io.File;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import sun.misc.Signal;
import sun.misc.SignalHandler;
import ch.psi.fda.messages.EndOfStreamMessage;
import ch.psi.fda.serializer.SerializerTXT; import ch.psi.fda.serializer.SerializerTXT;
import com.google.common.eventbus.AsyncEventBus; import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventBus; import com.google.common.eventbus.EventBus;
@SuppressWarnings("restriction")
public class FdaqMain { public class FdaqMain {
public final static String FDAQ_CONFIG = "ch.psi.fda.fdaq.config";
public static void main(String[] args) { public static void main(String[] args) {
if(args.length < 1 || args.length >2){ if(args.length != 1){
System.err.println("Usage:\n fdaq acquire <file>\n fdaq stop"); System.err.println("Usage:\n fdaq <file>");
System.exit(-1); System.exit(-1);
} }
boolean acquire = false; File file = new File(args[0]);
File file = null;
if(args[0].equals("acquire")){ if(file.exists()){
acquire = true; System.err.println("File "+file.getName()+ " already exists.");
file = new File(args[1]);
}
else if(args[0].equals("stop")){
}
else{
System.err.println("Usage:\n fdaq acquire <file>\n fdaq stop");
System.exit(-1); System.exit(-1);
} }
FdaqConfiguration configuration = new FdaqConfiguration();
String config = System.getProperty(FDAQ_CONFIG);
if(config != null){
configuration.loadFile(new File(config));
}
EventBus bus = new AsyncEventBus(Executors.newSingleThreadExecutor()); EventBus busA = new AsyncEventBus(Executors.newSingleThreadExecutor());
FdaqService fdaq = new FdaqService(bus); final EventBus bus = new AsyncEventBus(Executors.newSingleThreadExecutor());
final Fdaq fdaq = new Fdaq(busA, configuration);
final FdaqBitShuffle bshuffle= new FdaqBitShuffle(bus);
busA.register(bshuffle);
if(acquire){ Signal.handle(new Signal("INT"), new SignalHandler() {
SerializerTXT serializer = new SerializerTXT(file); int count = 0;
serializer.setShowDimensionHeader(false); public void handle(Signal sig) {
bus.register(serializer); if(count < 1){
fdaq.stop();
fdaq.acquire(); bus.post(new EndOfStreamMessage());
} count++;
else{ return;
fdaq.stop(); }
System.exit(0);
}
});
SerializerTXT serializer = new SerializerTXT(file, false);
serializer.setShowDimensionHeader(false);
bus.register(serializer);
// This stop ensures that the data server is in a good shape (i.e. gets restarted)
// We need to wait a certain amount of time to have the server restarted.
fdaq.stop();
try {
Thread.sleep(1000); // TODO check whether this sleep is really necessary
} catch (InterruptedException e) {
e.printStackTrace();
} }
fdaq.acquire();
} }
} }
@@ -1,175 +0,0 @@
/**
*
* 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.fdaq;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.common.eventbus.EventBus;
import ch.psi.fda.messages.DataMessage;
import ch.psi.fda.messages.EndOfStreamMessage;
import ch.psi.fda.messages.Metadata;
/**
* Fdaq service
*
*/
public class FdaqService {
private static final Logger logger = Logger.getLogger(FdaqService.class.getName());
private volatile boolean stopAcquisition = false;
private final EventBus bus;
private String hostname = "mchip015.psi.ch";
private int port = 2233;
private int killPort = 2234;
private int numberOfElements = Integer.MAX_VALUE/2;
public FdaqService(EventBus bus){
this.bus = bus;
}
public FdaqService(EventBus bus, String hostname, int port, int killPort, int numberOfElements){
this.bus = bus;
this.hostname = hostname;
this.port = port;
this.killPort = killPort;
this.numberOfElements = numberOfElements;
}
/**
* Acquire data from the fdaq box
* @param hostname
* @param port
* @param numberOfElements
*/
public void acquire() {
Socket echoSocket = null;
DataOutputStream out = null;
DataInputStream in = null;
try {
stopAcquisition = false;
echoSocket = new Socket(hostname, port);
out = new DataOutputStream(echoSocket.getOutputStream());
in = new DataInputStream(echoSocket.getInputStream());
// struct fdaqbloc_in {int fnum;int nsample;};
ByteBuffer bytebuffer = ByteBuffer.allocate(2 * 4); // 2 times
// Integers
bytebuffer.order(ByteOrder.LITTLE_ENDIAN);
bytebuffer.putInt(26);
bytebuffer.putInt(numberOfElements);
out.write(bytebuffer.array());
out.flush();
final List<Metadata> metadata = new ArrayList<>();
metadata.add(new Metadata("counter"));
metadata.add(new Metadata("ain1"));
metadata.add(new Metadata("ain2"));
metadata.add(new Metadata("ain3"));
metadata.add(new Metadata("ain4"));
metadata.add(new Metadata("enc1"));
for (int t = 0; t < numberOfElements; t++) {
// struct fdaqbloc_out {int trigindex;int adc1reg;int
// adc2reg;int encoder;};
ByteBuffer buffer = ByteBuffer.allocate(4 * 4); // 4 times
// Integers
buffer.order(ByteOrder.LITTLE_ENDIAN);
int r = in.read(buffer.array());
if (r == -1) {
break;
}
int a = buffer.getInt();
int b = buffer.getInt();
int b1 = b & 0xffff;
int b2 = (b >> 16) & 0xffff;
int c = buffer.getInt();
int c1 = c & 0xffff;
int c2 = (c >> 16) & 0xffff;
int d = buffer.getInt();
DataMessage message = new DataMessage(metadata);
message.getData().add(a);
message.getData().add(b1);
message.getData().add(b2);
message.getData().add(c1);
message.getData().add(c2);
message.getData().add(d);
bus.post(message);
}
} catch (IOException e) {
// Ignore potential exceptions if stop was triggered before all messages were retrieved
if (!stopAcquisition) {
throw new RuntimeException(e);
}
} finally {
bus.post(new EndOfStreamMessage());
try {
out.close();
in.close();
echoSocket.close();
} catch (IOException e) {
// Ignore because not relevant at this stage
}
}
}
/**
* Sending termination command to fdaq box
*/
public void stop() {
try {
stopAcquisition = true;
Socket echoSocket = new Socket(hostname, killPort);
DataOutputStream out = new DataOutputStream(echoSocket.getOutputStream());
ByteBuffer bytebuffer = ByteBuffer.allocate(1 * 4); // 2
// times
// Integers
bytebuffer.order(ByteOrder.LITTLE_ENDIAN);
bytebuffer.putInt(666);
out.write(bytebuffer.array());
out.flush();
out.close();
echoSocket.close();
} catch (IOException e) {
logger.log(Level.SEVERE, "", e);
}
}
}