Using tasks in numass viewer

This commit is contained in:
Alexander Nozik 2015-12-27 18:04:05 +03:00
parent c8ad2a51bc
commit cbfbe27958
23 changed files with 1454 additions and 1277 deletions

View File

@ -89,7 +89,7 @@ public class PrepareDataAction extends OneToOneAction<NMFile, DataSet> {
double cr = point.getCountRate(a, b, deadTime); double cr = point.getCountRate(a, b, deadTime);
double crErr = point.getCountRateErr(a, b, deadTime); double crErr = point.getCountRateErr(a, b, deadTime);
Instant timestamp = point.getAbsouteTime().toInstant(ZoneOffset.UTC); Instant timestamp = point.getStartTime();
dataList.add(new MapDataPoint(parnames, new Object[]{Uset, Uread, time, total, wind, corr, cr, crErr, timestamp})); dataList.add(new MapDataPoint(parnames, new Object[]{Uset, Uread, time, total, wind, corr, cr, crErr, timestamp}));
} }

View File

@ -31,6 +31,8 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static java.lang.String.format; import static java.lang.String.format;
import static java.lang.String.format;
import static java.lang.String.format;
/** /**
* *

View File

@ -17,13 +17,13 @@ package inr.numass.data;
import hep.dataforge.data.DataPoint; import hep.dataforge.data.DataPoint;
import hep.dataforge.data.MapDataPoint; import hep.dataforge.data.MapDataPoint;
import java.time.LocalDateTime; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import static java.util.Arrays.sort;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static java.util.Arrays.sort;
/** /**
* *
@ -32,7 +32,7 @@ import java.util.Map;
public class NMPoint { public class NMPoint {
static final String[] dataNames = {"chanel", "count"}; static final String[] dataNames = {"chanel", "count"};
private LocalDateTime absouteTime; private Instant startTime;
// private MonitorCorrector corrector = null; // private MonitorCorrector corrector = null;
// private double deadTime; // private double deadTime;
@ -54,7 +54,7 @@ public class NMPoint {
this.pointLength = point.getLength(); this.pointLength = point.getLength();
this.uset = point.getUset(); this.uset = point.getUset();
this.uread = point.getUread(); this.uread = point.getUread();
this.absouteTime = point.getAbsouteTime(); this.startTime = point.getStartTime();
this.eventsCount = point.getEventsCount(); this.eventsCount = point.getEventsCount();
// this.point = point; // this.point = point;
spectrum = calculateSpectrum(point); spectrum = calculateSpectrum(point);
@ -106,8 +106,12 @@ public class NMPoint {
/** /**
* @return the absouteTime * @return the absouteTime
*/ */
public LocalDateTime getAbsouteTime() { public Instant getStartTime() {
return absouteTime; if (startTime == null) {
return Instant.EPOCH;
} else {
return startTime;
}
} }
public int getCountInChanel(int chanel) { public int getCountInChanel(int chanel) {

View File

@ -24,6 +24,7 @@ import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Scanner; import java.util.Scanner;
@ -227,7 +228,7 @@ public class NumassDataReader {
absoluteTime = absoluteTime.plusDays(1); absoluteTime = absoluteTime.plusDays(1);
} }
point.setAbsouteTime(absoluteTime); point.setStartTime(absoluteTime.toInstant(ZoneOffset.UTC));
rx = readBlock(4); rx = readBlock(4);
int Uread = rx[2] + 256 * rx[3]; int Uread = rx[2] + 256 * rx[3];

View File

@ -15,7 +15,7 @@
*/ */
package inr.numass.data; package inr.numass.data;
import java.time.LocalDateTime; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -27,9 +27,9 @@ import java.util.List;
public class RawNMPoint implements Cloneable { public class RawNMPoint implements Cloneable {
public static int MAX_CHANEL = 4095; public static int MAX_CHANEL = 4095;
private LocalDateTime absouteTime; private Instant startTime;
private final List<NMEvent> events; private final List<NMEvent> events;
private double t; private double length;
private double uread; private double uread;
private double uset; private double uset;
@ -38,21 +38,21 @@ public class RawNMPoint implements Cloneable {
this.uset = U; this.uset = U;
this.uread = U; this.uread = U;
this.events = events; this.events = events;
this.t = t; this.length = t;
} }
public RawNMPoint(double Uset, double Uread, List<NMEvent> events, double t) { public RawNMPoint(double Uset, double Uread, List<NMEvent> events, double t) {
this.uset = Uset; this.uset = Uset;
this.uread = Uread; this.uread = Uread;
this.events = events; this.events = events;
this.t = t; this.length = t;
} }
public RawNMPoint(double uset, double uread, List<NMEvent> events, double t, LocalDateTime absouteTime) { public RawNMPoint(double uset, double uread, List<NMEvent> events, double t, Instant absouteTime) {
this.uset = uset; this.uset = uset;
this.uread = uread; this.uread = uread;
this.t = t; this.length = t;
this.absouteTime = absouteTime; this.startTime = absouteTime;
this.events = events; this.events = events;
} }
@ -60,7 +60,7 @@ public class RawNMPoint implements Cloneable {
events = new ArrayList<>(); events = new ArrayList<>();
uset = 0; uset = 0;
uread = 0; uread = 0;
t = Double.NaN; length = Double.NaN;
} }
@Override @Override
@ -72,8 +72,8 @@ public class RawNMPoint implements Cloneable {
return new RawNMPoint(getUset(), getUread(), newevents, getLength()); return new RawNMPoint(getUset(), getUread(), newevents, getLength());
} }
public LocalDateTime getAbsouteTime() { public Instant getStartTime() {
return absouteTime; return startTime;
} }
public double getCR() { public double getCR() {
@ -100,10 +100,10 @@ public class RawNMPoint implements Cloneable {
* @return the tset * @return the tset
*/ */
public double getLength() { public double getLength() {
if (Double.isNaN(t)) { if (Double.isNaN(length)) {
throw new Error(); throw new Error();
} }
return t; return length;
} }
/** /**
@ -132,7 +132,7 @@ public class RawNMPoint implements Cloneable {
for (NMEvent newEvent : point.getEvents()) { for (NMEvent newEvent : point.getEvents()) {
res.putEvent(new NMEvent(newEvent.getChanel(), newEvent.getTime() + this.getLength())); res.putEvent(new NMEvent(newEvent.getChanel(), newEvent.getTime() + this.getLength()));
} }
res.t += point.getLength(); res.length += point.getLength();
res.uread = (this.uread + point.uread) / 2; res.uread = (this.uread + point.uread) / 2;
return res; return res;
} }
@ -153,15 +153,15 @@ public class RawNMPoint implements Cloneable {
return new RawNMPoint(getUset(), getUread(), res, getLength()); return new RawNMPoint(getUset(), getUread(), res, getLength());
} }
void setAbsouteTime(LocalDateTime absouteTime) { void setStartTime(Instant absouteTime) {
this.absouteTime = absouteTime; this.startTime = absouteTime;
} }
/** /**
* @param tset the tset to set * @param tset the tset to set
*/ */
void setLength(double tset) { void setLength(double tset) {
this.t = tset; this.length = tset;
} }
/** /**
@ -178,4 +178,5 @@ public class RawNMPoint implements Cloneable {
void setUset(double Uset) { void setUset(double Uset) {
this.uset = Uset; this.uset = Uset;
} }
} }

View File

@ -15,13 +15,14 @@
*/ */
package inr.numass.data; package inr.numass.data;
import hep.dataforge.data.DataAdapter;
import hep.dataforge.meta.Meta; import hep.dataforge.meta.Meta;
import hep.dataforge.data.DataPoint; import hep.dataforge.data.DataPoint;
import hep.dataforge.data.MapDataPoint; import hep.dataforge.data.MapDataPoint;
import hep.dataforge.data.XYDataAdapter; import hep.dataforge.data.XYDataAdapter;
import hep.dataforge.exceptions.DataFormatException; import hep.dataforge.exceptions.DataFormatException;
import hep.dataforge.exceptions.NameNotFoundException; import hep.dataforge.exceptions.NameNotFoundException;
import hep.dataforge.names.Names; import hep.dataforge.meta.MetaBuilder;
import hep.dataforge.values.Value; import hep.dataforge.values.Value;
/** /**
@ -30,54 +31,48 @@ import hep.dataforge.values.Value;
*/ */
public class SpectrumDataAdapter extends XYDataAdapter { public class SpectrumDataAdapter extends XYDataAdapter {
private static final String ANNOTATION_TIMENAME = "timeName"; private static final String POINT_LENGTH_NAME = "time";
private String timeName = "time";
public SpectrumDataAdapter() { public SpectrumDataAdapter() {
} }
public SpectrumDataAdapter(Meta aliasAnnotation) { public SpectrumDataAdapter(Meta meta) {
super(aliasAnnotation); super(meta);
this.timeName = aliasAnnotation.getString(ANNOTATION_TIMENAME, "X");
} }
public SpectrumDataAdapter(String xName, String yName, String yErrName, String timeTime) { public SpectrumDataAdapter(String xName, String yName, String yErrName, String measurementTime) {
super(xName, yName, yErrName); super(new MetaBuilder(DataAdapter.DATA_ADAPTER_ANNOTATION_NAME)
this.timeName = timeTime; .setValue(X_NAME, xName)
.setValue(Y_NAME, yName)
.setValue(Y_ERR_NAME, yErrName)
.setValue(POINT_LENGTH_NAME, measurementTime)
.build()
);
} }
public SpectrumDataAdapter(String xName, String yName, String timeTime) { public SpectrumDataAdapter(String xName, String yName, String measurementTime) {
super(xName, yName); super(new MetaBuilder(DataAdapter.DATA_ADAPTER_ANNOTATION_NAME)
this.timeName = timeTime; .setValue(X_NAME, xName)
.setValue(Y_NAME, yName)
.setValue(POINT_LENGTH_NAME, measurementTime)
.build()
);
} }
public double getTime(DataPoint point) { public double getTime(DataPoint point) {
if (point.names().contains(timeName)) { return this.getFrom(point, POINT_LENGTH_NAME, 1d).doubleValue();
return point.getDouble(timeName);
} else {
return 1d;
}
} }
public DataPoint buildSpectrumDataPoint(double x, long count, double t) { public DataPoint buildSpectrumDataPoint(double x, long count, double t) {
return new MapDataPoint(new String[]{xName,yName,timeName}, x,count,t); return new MapDataPoint(new String[]{getValueName(X_NAME), getValueName(Y_NAME),
getValueName(POINT_LENGTH_NAME)},
x, count, t);
} }
public DataPoint buildSpectrumDataPoint(double x, long count, double countErr, double t) { public DataPoint buildSpectrumDataPoint(double x, long count, double countErr, double t) {
return new MapDataPoint(new String[]{xName,yName,yErrName,timeName}, x,count,countErr,t); return new MapDataPoint(new String[]{getValueName(X_NAME), getValueName(Y_NAME),
} getValueName(Y_ERR_NAME), getValueName(POINT_LENGTH_NAME)},
x, count, countErr, t);
@Override
public Meta buildAnnotation() {
Meta res = super.buildAnnotation();
res.getBuilder().putValue(ANNOTATION_TIMENAME, timeName);
return res;
}
@Override
public Names getNames() {
return Names.of(xName,yName);
} }
@Override @Override
@ -85,23 +80,22 @@ public class SpectrumDataAdapter extends XYDataAdapter {
return true; return true;
} }
@Override @Override
public Value getYerr(DataPoint point) throws NameNotFoundException { public Value getYerr(DataPoint point) throws NameNotFoundException {
if (point.names().contains(yErrName)) { if (providesYError(point)) {
return Value.of(super.getYerr(point).doubleValue()/getTime(point)); return Value.of(super.getYerr(point).doubleValue() / getTime(point));
} else{ } else {
double y = super.getY(point).doubleValue(); double y = super.getY(point).doubleValue();
if(y<=0) throw new DataFormatException(); if (y <= 0) {
else { throw new DataFormatException();
return Value.of(Math.sqrt(y)/getTime(point)); } else {
return Value.of(Math.sqrt(y) / getTime(point));
} }
} }
} }
public long getCount(DataPoint point){ public long getCount(DataPoint point) {
return point.getValue(yName).numberValue().longValue(); return super.getY(point).numberValue().longValue();
} }
@Override @Override

View File

@ -27,6 +27,7 @@ import java.util.Iterator;
import org.apache.commons.math3.random.JDKRandomGenerator; import org.apache.commons.math3.random.JDKRandomGenerator;
import org.apache.commons.math3.random.RandomDataGenerator; import org.apache.commons.math3.random.RandomDataGenerator;
import org.apache.commons.math3.random.RandomGenerator; import org.apache.commons.math3.random.RandomGenerator;
import static java.lang.Double.isNaN;
/** /**
* Генератор наборов данных для спектров. На входе требуется набор данных, * Генератор наборов данных для спектров. На входе требуется набор данных,
@ -64,7 +65,7 @@ public class SpectrumGenerator implements Generator {
@Override @Override
public ListDataSet generateData(Iterable<DataPoint> config) { public ListDataSet generateData(Iterable<DataPoint> config) {
ListDataSet res = adapter.buildEmptyDataSet(""); ListDataSet res = new ListDataSet(adapter.getFormat());
for (Iterator<DataPoint> it = config.iterator(); it.hasNext();) { for (Iterator<DataPoint> it = config.iterator(); it.hasNext();) {
res.add(this.generateDataPoint(it.next())); res.add(this.generateDataPoint(it.next()));
} }

View File

@ -39,7 +39,7 @@ public class DebunchReportImpl implements DebunchReport {
DebunchReportImpl(RawNMPoint pointBefore, DebunchData debunchData) { DebunchReportImpl(RawNMPoint pointBefore, DebunchData debunchData) {
this.pointBefore = pointBefore; this.pointBefore = pointBefore;
pointAfter = new RawNMPoint(pointBefore.getUset(),pointBefore.getUread(), pointAfter = new RawNMPoint(pointBefore.getUset(),pointBefore.getUread(),
debunchData.getDebunchedEvents(), debunchData.getDebunchedLength(),pointBefore.getAbsouteTime()); debunchData.getDebunchedEvents(), debunchData.getDebunchedLength(),pointBefore.getStartTime());
this.bunches = debunchData.getBunches(); this.bunches = debunchData.getBunches();
} }

View File

@ -21,6 +21,9 @@ import static java.lang.Math.max;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static java.lang.Math.max;
import static java.lang.Math.max;
import static java.lang.Math.max;
/** /**
* *

View File

@ -23,8 +23,8 @@ import inr.numass.data.SpectrumDataAdapter;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.util.Locale; import java.util.Locale;
import static java.util.Locale.setDefault;
import java.util.Scanner; import java.util.Scanner;
import static java.util.Locale.setDefault;
/** /**
* *
@ -56,7 +56,7 @@ public class OldDataReader {
public static ListDataSet readData(String path, double Elow) { public static ListDataSet readData(String path, double Elow) {
SpectrumDataAdapter factory = new SpectrumDataAdapter(); SpectrumDataAdapter factory = new SpectrumDataAdapter();
ListDataSet res = factory.buildEmptyDataSet(""); ListDataSet res = new ListDataSet(factory.getFormat());
File file = GlobalContext.instance().io().getFile(path); File file = GlobalContext.instance().io().getFile(path);
double x; double x;
int count; int count;
@ -108,7 +108,7 @@ public class OldDataReader {
public static ListDataSet readDataAsGun(String path, double Elow) { public static ListDataSet readDataAsGun(String path, double Elow) {
SpectrumDataAdapter factory = new SpectrumDataAdapter(); SpectrumDataAdapter factory = new SpectrumDataAdapter();
ListDataSet res = factory.buildEmptyDataSet(""); ListDataSet res = new ListDataSet(factory.getFormat());
File file = GlobalContext.instance().io().getFile(path); File file = GlobalContext.instance().io().getFile(path);
double x; double x;
long count; long count;
@ -141,7 +141,7 @@ public class OldDataReader {
public static ListDataSet readSpectrumData(String path){ public static ListDataSet readSpectrumData(String path){
SpectrumDataAdapter factory = new SpectrumDataAdapter(); SpectrumDataAdapter factory = new SpectrumDataAdapter();
ListDataSet res = factory.buildEmptyDataSet(""); ListDataSet res = new ListDataSet(factory.getFormat());
File file = GlobalContext.instance().io().getFile(path); File file = GlobalContext.instance().io().getFile(path);
double x; double x;
double count; double count;

View File

@ -23,6 +23,8 @@ import static java.lang.Math.sqrt;
import org.apache.commons.math3.analysis.UnivariateFunction; import org.apache.commons.math3.analysis.UnivariateFunction;
import static java.lang.Math.abs; import static java.lang.Math.abs;
import static java.lang.Math.abs; import static java.lang.Math.abs;
import static java.lang.Math.abs;
import static java.lang.Math.abs;
/** /**
* *

View File

@ -19,7 +19,7 @@ import hep.dataforge.description.ActionDescriptor;
import hep.dataforge.description.DescriptorUtils; import hep.dataforge.description.DescriptorUtils;
import hep.dataforge.exceptions.NameNotFoundException; import hep.dataforge.exceptions.NameNotFoundException;
import hep.dataforge.fx.LogOutputPane; import hep.dataforge.fx.LogOutputPane;
import hep.dataforge.fx.MetaEditorComponent; import hep.dataforge.fx.MetaEditor;
import hep.dataforge.fx.MetaTreeItem; import hep.dataforge.fx.MetaTreeItem;
import hep.dataforge.io.IOManager; import hep.dataforge.io.IOManager;
import hep.dataforge.io.MetaFileReader; import hep.dataforge.io.MetaFileReader;
@ -67,8 +67,8 @@ public class NumassWorkbenchController implements Initializable, StagePaneHolder
Context parentContext; Context parentContext;
MetaFactory<Context> contextFactory; MetaFactory<Context> contextFactory;
List<MetaEditorComponent> actionEditors = new ArrayList<>(); List<MetaEditor> actionEditors = new ArrayList<>();
MetaEditorComponent dataEditor; MetaEditor dataEditor;
Context context; Context context;
Configuration dataConfig; Configuration dataConfig;
@ -187,7 +187,7 @@ public class NumassWorkbenchController implements Initializable, StagePaneHolder
} }
}); });
MetaEditorComponent contextEditor = MetaEditorComponent.build(contextValues, null); MetaEditor contextEditor = MetaEditor.build(contextValues, null);
contextEditor.geTable().setShowRoot(false); contextEditor.geTable().setShowRoot(false);
contextPane.setContent(contextEditor); contextPane.setContent(contextEditor);
@ -203,7 +203,7 @@ public class NumassWorkbenchController implements Initializable, StagePaneHolder
} else { } else {
dataConfig = new Configuration("data"); dataConfig = new Configuration("data");
} }
dataEditor = MetaEditorComponent.build(dataConfig, dataEditor = MetaEditor.build(dataConfig,
DescriptorUtils.buildDescriptor( DescriptorUtils.buildDescriptor(
DescriptorUtils.findAnnotatedElement("method::hep.dataforge.data.DataManager.read") DescriptorUtils.findAnnotatedElement("method::hep.dataforge.data.DataManager.read")
)); ));
@ -219,7 +219,7 @@ public class NumassWorkbenchController implements Initializable, StagePaneHolder
actionsConfig.setNode("action", actions); actionsConfig.setNode("action", actions);
for (Configuration action : actions) { for (Configuration action : actions) {
MetaEditorComponent actionEditor = new MetaEditorComponent(); MetaEditor actionEditor = new MetaEditor();
MetaTreeItem rootItem = new MetaTreeItem(action, getDescriptorForAction(action.getString("type"))); MetaTreeItem rootItem = new MetaTreeItem(action, getDescriptorForAction(action.getString("type")));
//Freezing actions names //Freezing actions names

View File

@ -34,10 +34,14 @@ import java.net.URL;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -172,13 +176,26 @@ public class NumassDataLoader extends AbstractLoader implements BinaryLoader<Env
} }
// LocalDateTime startTime = envelope.meta().get // LocalDateTime startTime = envelope.meta().get
RawNMPoint raw = new RawNMPoint(envelope.meta().getDouble("external_meta.HV1_value", 0), double u = envelope.meta().getDouble("external_meta.HV1_value", 0);
RawNMPoint raw = new RawNMPoint(u, u,
events, events,
envelope.meta().getValue("external_meta.acquisition_time").doubleValue()); envelope.meta().getValue("external_meta.acquisition_time").doubleValue(),
readTime(envelope.meta()));
return transformation.apply(raw); return transformation.apply(raw);
} }
private static Instant readTime(Meta meta) {
if (meta.hasValue("date") && meta.hasValue("start_time")) {
LocalDate date = LocalDate.parse(meta.getString("date"), DateTimeFormatter.ofPattern("uuuu.MM.dd"));
LocalTime time = LocalTime.parse(meta.getString("start_time"));
LocalDateTime dateTime = LocalDateTime.of(date, time);
return dateTime.toInstant(ZoneOffset.UTC);
} else {
return Instant.EPOCH;
}
}
/** /**
* Read numass point without transformation * Read numass point without transformation
* *
@ -244,7 +261,7 @@ public class NumassDataLoader extends AbstractLoader implements BinaryLoader<Env
this.getPoints().stream().forEachOrdered((point) -> { this.getPoints().stream().forEachOrdered((point) -> {
res.add(readPoint(point)); res.add(readPoint(point));
}); });
// res.sort((NMPoint o1, NMPoint o2) -> o1.getAbsouteTime().compareTo(o2.getAbsouteTime())); // res.sort((NMPoint o1, NMPoint o2) -> o1.getStartTime().compareTo(o2.getStartTime()));
return res; return res;
} }
@ -287,13 +304,17 @@ public class NumassDataLoader extends AbstractLoader implements BinaryLoader<Env
@Override @Override
public Instant startTime() { public Instant startTime() {
//TODO read meta
return null; return null;
// List<NMPoint> points = getNMPoints();
// if(!points.isEmpty()){
// return points.get(0).getStartTime();
// } else {
// return null;
// }
} }
@Override @Override
public String getDescription() { public String getDescription() {
//TODO read from annotation return meta().getString("description", "").replace("\\n", "\n");
return "";
} }
} }

View File

@ -85,12 +85,12 @@ public class NumassStorage extends FileStorage {
} }
} }
public static NumassStorage buildRemoteNumassRoot(String uri) throws StorageException { public static NumassStorage buildNumassRoot(String uri, boolean readOnly, boolean monitor) throws StorageException {
try { try {
Meta meta = new MetaBuilder("storage") Meta meta = new MetaBuilder("storage")
.setValue("type", "file.numass") .setValue("type", "file.numass")
.setValue("readOnly", true) .setValue("readOnly", readOnly)
.setValue("monitor", false); .setValue("monitor", monitor);
return new NumassStorage(VFSUtils.getRemoteFile(uri), meta); return new NumassStorage(VFSUtils.getRemoteFile(uri), meta);
} catch (FileSystemException ex) { } catch (FileSystemException ex) {
throw new RuntimeException(ex); throw new RuntimeException(ex);

View File

@ -5,7 +5,7 @@ if (!hasProperty('mainClass')) {
} }
mainClassName = mainClass mainClassName = mainClass
version = "0.2.2" version = "0.2.3"
description = "The viewer for numass data" description = "The viewer for numass data"

View File

@ -5,11 +5,12 @@
*/ */
package inr.numass.viewer; package inr.numass.viewer;
import javafx.concurrent.Task;
/** /**
* *
* @author Alexander Nozik <altavir@gmail.com> * @author Alexander Nozik <altavir@gmail.com>
*/ */
public interface ProgressUpdateCallback { public interface FXTaskManager {
void setProgressText(String text); void postTask(Task task);
void setProgress(double progress);
} }

View File

@ -24,10 +24,13 @@ import java.io.File;
import java.net.URL; import java.net.URL;
import java.util.Optional; import java.util.Optional;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
@ -48,6 +51,7 @@ import javafx.scene.control.TreeTableView;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.stage.DirectoryChooser; import javafx.stage.DirectoryChooser;
import javafx.util.Duration;
import javafx.util.Pair; import javafx.util.Pair;
import org.controlsfx.control.StatusBar; import org.controlsfx.control.StatusBar;
@ -56,7 +60,7 @@ import org.controlsfx.control.StatusBar;
* *
* @author Alexander Nozik * @author Alexander Nozik
*/ */
public class MainViewerController implements Initializable, ProgressUpdateCallback { public class MainViewerController implements Initializable, FXTaskManager {
public static MainViewerController build(NumassStorage root) { public static MainViewerController build(NumassStorage root) {
MainViewerController res = new MainViewerController(); MainViewerController res = new MainViewerController();
@ -111,14 +115,14 @@ public class MainViewerController implements Initializable, ProgressUpdateCallba
// TabPaneDetacher.create().makeTabsDetachable(tabPane); // TabPaneDetacher.create().makeTabsDetachable(tabPane);
ConsoleDude.hookStdStreams(consoleArea); ConsoleDude.hookStdStreams(consoleArea);
SplitPaneDividerSlider slider = new SplitPaneDividerSlider(consoleSplit, 0, SplitPaneDividerSlider.Direction.DOWN); SplitPaneDividerSlider slider = new SplitPaneDividerSlider(consoleSplit, 0,
SplitPaneDividerSlider.Direction.DOWN, Duration.seconds(1));
consoleButton.selectedProperty().addListener((ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) -> { slider.aimContentVisibleProperty().bindBidirectional(consoleButton.selectedProperty());
slider.setAimContentVisible(t1);
});
slider.setAimContentVisible(false);
consoleButton.setSelected(false);
loadRemoteButton.setDisable(true); loadRemoteButton.setDisable(true);
mspController.setCallback(this);
} }
@FXML @FXML
@ -131,39 +135,72 @@ public class MainViewerController implements Initializable, ProgressUpdateCallba
final File rootDir = chooser.showDialog(((Node) event.getTarget()).getScene().getWindow()); final File rootDir = chooser.showDialog(((Node) event.getTarget()).getScene().getWindow());
if (rootDir != null) { if (rootDir != null) {
storagePathLabel.setText("Storage: " + rootDir.getAbsolutePath()); Task dirLoadTask = new DirectoryLoadTask(rootDir.toURI().toString());
setProgress(-1); postTask(dirLoadTask);
setProgressText("Building numass storage tree..."); Viewer.runTask(dirLoadTask);
new Thread(() -> { }
}
private class DirectoryLoadTask extends Task<Void> {
private final String uri;
public DirectoryLoadTask(String uri) {
this.uri = uri;
}
@Override
protected Void call() throws Exception {
updateTitle("Load storage ("+uri+")");
updateProgress(-1, 1);
updateMessage("Building numass storage tree...");
try { try {
NumassStorage root = NumassStorage.buildNumassRoot(uri, true, false);
NumassStorage root = NumassStorage.buildLocalNumassRoot(rootDir, true);
setRootStorage(root); setRootStorage(root);
Platform.runLater(() -> storagePathLabel.setText("Storage: " + uri));
} catch (StorageException ex) { } catch (StorageException ex) {
setProgress(0); updateProgress(0, 1);
setProgressText("Failed to load local storage"); updateMessage("Failed to load storage " + uri);
Logger.getLogger(MainViewerController.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(MainViewerController.class.getName()).log(Level.SEVERE, null, ex);
} }
}, "loader thread").start(); return null;
} }
} }
@Override @Override
public void setProgress(double progress) { @SuppressWarnings("unchecked")
Platform.runLater(() -> statusBar.setProgress(progress)); public void postTask(Task task) {
//statusBar.setProgress(progress); task.setOnRunning((e) -> {
} statusBar.setText(task.getTitle() + ": " + task.getMessage());
statusBar.setProgress(task.getProgress());
});
@Override task.messageProperty().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
public void setProgressText(String text) { statusBar.setText(task.getTitle() + ": " +newValue);
Platform.runLater(() -> statusBar.setText(text)); });
//statusBar.setText(text);
task.progressProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
statusBar.setProgress(newValue.doubleValue());
});
task.setOnSucceeded((e) -> {
statusBar.setText(task.getTitle() + ": Complete");
statusBar.setProgress(0);
});
task.setOnFailed((e) -> {
statusBar.setText(task.getTitle() + ": Failed");
statusBar.setProgress(0);
});
} }
public void setRootStorage(NumassStorage root) { public void setRootStorage(NumassStorage root) {
fillNumassStorageData(root); Task fillTask = new StorageDataFillTask(root);
postTask(fillTask);
Viewer.runTask(fillTask);
if (mspController != null) { if (mspController != null) {
mspController.setCallback(this); mspController.setCallback(this);
mspController.fillMspData(root); mspController.fillMspData(root);
@ -176,14 +213,24 @@ public class MainViewerController implements Initializable, ProgressUpdateCallba
} }
private void fillNumassStorageData(NumassStorage rootStorage) { private class StorageDataFillTask extends Task<Void> {
if (rootStorage != null) {
setProgress(-1);
setProgressText("Loading numass storage tree...");
try { private final NumassStorage root;
new NumassLoaderTreeBuilder(MainViewerController.this).fillTree(numassLoaderDataTree, rootStorage, (NumassData loader) -> {
NumassLoaderViewComponent component = NumassLoaderViewComponent.build(loader); public StorageDataFillTask(NumassStorage root) {
this.root = root;
}
@Override
protected Void call() throws Exception {
updateTitle("Fill data to UI ("+root.getName()+")");
this.updateProgress(-1, 1);
this.updateMessage("Loading numass storage tree...");
Task treeBuilderTask = new NumassLoaderTreeBuilder(numassLoaderDataTree, root, (NumassData loader) -> {
NumassLoaderViewComponent component = new NumassLoaderViewComponent();
component.loadData(loader);
component.setCallback(MainViewerController.this);
numassLoaderViewContainer.getChildren().clear(); numassLoaderViewContainer.getChildren().clear();
numassLoaderViewContainer.getChildren().add(component); numassLoaderViewContainer.getChildren().add(component);
AnchorPane.setTopAnchor(component, 0.0); AnchorPane.setTopAnchor(component, 0.0);
@ -192,12 +239,20 @@ public class MainViewerController implements Initializable, ProgressUpdateCallba
AnchorPane.setBottomAnchor(component, 0.0); AnchorPane.setBottomAnchor(component, 0.0);
numassLoaderViewContainer.requestLayout(); numassLoaderViewContainer.requestLayout();
}); });
setProgress(0); postTask(treeBuilderTask);
setProgressText("Loaded"); Viewer.runTask(treeBuilderTask);
} catch (StorageException ex) { try {
treeBuilderTask.get();
this.updateProgress(0, 1);
this.updateMessage("Numass storage tree loaded.");
this.succeeded();
} catch (InterruptedException | ExecutionException ex) {
this.failed();
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
return null;
} }
} }
@FXML @FXML
@ -230,7 +285,7 @@ public class MainViewerController implements Initializable, ProgressUpdateCallba
dialog.getDialogPane().setContent(grid); dialog.getDialogPane().setContent(grid);
// Request focus on the username field by default. // Request focus on the username field by default.
Platform.runLater(() -> storageText.requestFocus()); storageText.requestFocus();
// Convert the result to a username-password-pair when the login button is clicked. // Convert the result to a username-password-pair when the login button is clicked.
dialog.setResultConverter(dialogButton -> { dialog.setResultConverter(dialogButton -> {
@ -243,21 +298,9 @@ public class MainViewerController implements Initializable, ProgressUpdateCallba
Optional<Pair<String, String>> result = dialog.showAndWait(); Optional<Pair<String, String>> result = dialog.showAndWait();
if (result.isPresent()) { if (result.isPresent()) {
storagePathLabel.setText("Storage: remote/" + result.get().getValue()); Task dirLoadTask = new DirectoryLoadTask(result.get().getKey() + "/data/" + result.get().getValue());
postTask(dirLoadTask);
setProgress(-1); Viewer.runTask(dirLoadTask);
setProgressText("Building numass storage tree...");
new Thread(() -> {
try {
NumassStorage root = NumassStorage.buildRemoteNumassRoot(result.get().getKey() + "/data/" + result.get().getValue());
setRootStorage(root);
} catch (StorageException ex) {
setProgress(0);
setProgressText("Failed to load remote storage");
Logger.getLogger(MainViewerController.class.getName()).log(Level.SEVERE, null, ex);
}
}, "loader thread").start();
} }
} }
} }

View File

@ -22,7 +22,6 @@ package inr.numass.viewer;
*/ */
import hep.dataforge.data.DataPoint; import hep.dataforge.data.DataPoint;
import hep.dataforge.data.MapDataPoint; import hep.dataforge.data.MapDataPoint;
import hep.dataforge.exceptions.StorageException;
import hep.dataforge.storage.api.PointLoader; import hep.dataforge.storage.api.PointLoader;
import hep.dataforge.storage.api.Storage; import hep.dataforge.storage.api.Storage;
import hep.dataforge.values.Value; import hep.dataforge.values.Value;
@ -35,6 +34,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
@ -58,7 +58,7 @@ import org.slf4j.LoggerFactory;
*/ */
public class MspViewController implements Initializable { public class MspViewController implements Initializable {
private ProgressUpdateCallback callback; private FXTaskManager callback;
@FXML @FXML
private AnchorPane mspPlotPane; private AnchorPane mspPlotPane;
@ -119,8 +119,31 @@ public class MspViewController implements Initializable {
public void fillMspData(Storage rootStorage) { public void fillMspData(Storage rootStorage) {
if (rootStorage != null) { if (rootStorage != null) {
try { MspDataFillTask fillTask = new MspDataFillTask(rootStorage);
List<DataPoint> mspData = getMspData(rootStorage); if(callback!= null){
callback.postTask(fillTask);
}
Viewer.runTask(fillTask);
}
}
private class MspDataFillTask extends Task<Void> {
private final Storage storage;
public MspDataFillTask(Storage storage) {
this.storage = storage;
}
@Override
protected Void call() throws Exception {
updateTitle("Fill msp data ("+storage.getName()+")");
MspDataLoadTask loadTask = new MspDataLoadTask(storage);
if(callback!= null){
callback.postTask(loadTask);
}
Viewer.runTask(loadTask);
List<DataPoint> mspData = loadTask.get();
Map<String, XYSeries> series = new HashMap<>(); Map<String, XYSeries> series = new HashMap<>();
for (DataPoint point : mspData) { for (DataPoint point : mspData) {
@ -150,21 +173,30 @@ public class MspViewController implements Initializable {
mspSeriesCollection.addSeries(series.get(name)); mspSeriesCollection.addSeries(series.get(name));
} }
updateMspPane(mspSeriesCollection); updateMspPane(mspSeriesCollection);
} catch (StorageException ex) { return null;
throw new RuntimeException(ex);
}
}
} }
private List<DataPoint> getMspData(Storage storage) throws StorageException { }
private class MspDataLoadTask extends Task<List<DataPoint>> {
private final Storage storage;
public MspDataLoadTask(Storage storage) {
this.storage = storage;
}
@Override
protected List<DataPoint> call() throws Exception {
updateTitle("Load msp data ("+storage.getName()+")");
List<DataPoint> mspData = new ArrayList<>(); List<DataPoint> mspData = new ArrayList<>();
DataPoint last = null; DataPoint last = null;
for (String loaderName : storage.loaders().keySet()) { for (String loaderName : storage.loaders().keySet()) {
if (loaderName.startsWith("msp")) { if (loaderName.startsWith("msp")) {
try (PointLoader mspLoader = (PointLoader) storage.getLoader(loaderName)) { try (PointLoader mspLoader = (PointLoader) storage.getLoader(loaderName)) {
mspLoader.open(); mspLoader.open();
updateProgress("Loading mass spectrometer data from " + mspLoader.getName()); updateMessage("Loading mass spectrometer data from " + mspLoader.getName());
updateProgress(-1); updateProgress(-1, 1);
for (DataPoint dp : mspLoader.asDataSet()) { for (DataPoint dp : mspLoader.asDataSet()) {
mspData.add(dp); mspData.add(dp);
last = dp; last = dp;
@ -177,28 +209,15 @@ public class MspViewController implements Initializable {
} }
} }
} }
// for (String shelfName : storage.shelves().keySet()) {
// mspData.addAll(getMspData(storage.getShelf(shelfName)));
// }
updateProgress("Loading msp data finished"); updateMessage("Loading msp data finished");
updateProgress(0); updateProgress(0, 1);
return mspData; return mspData;
} }
private void updateProgress(String progress) {
if (callback != null) {
callback.setProgressText(progress);
}
} }
private void updateProgress(double progress) { public void setCallback(FXTaskManager callback) {
if (callback != null) {
callback.setProgress(progress);
}
}
public void setCallback(ProgressUpdateCallback callback) {
this.callback = callback; this.callback = callback;
} }

View File

@ -26,6 +26,7 @@ import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.concurrent.Task;
import javafx.scene.control.TreeItem; import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn; import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView; import javafx.scene.control.TreeTableView;
@ -35,19 +36,23 @@ import javafx.scene.input.MouseEvent;
* *
* @author darksnake * @author darksnake
*/ */
public class NumassLoaderTreeBuilder implements ProgressUpdateCallback { public class NumassLoaderTreeBuilder extends Task<Void> {
ProgressUpdateCallback callback; private final TreeTableView<TreeItemValue> numassLoaderDataTree;
private final NumassStorage rootStorage;
private final Consumer<NumassData> numassViewBuilder;
public NumassLoaderTreeBuilder(ProgressUpdateCallback callback) { public NumassLoaderTreeBuilder(TreeTableView<TreeItemValue> numassLoaderDataTree, NumassStorage rootStorage, Consumer<NumassData> numassViewBuilder) {
this.callback = callback; this.numassLoaderDataTree = numassLoaderDataTree;
this.rootStorage = rootStorage;
this.numassViewBuilder = numassViewBuilder;
} }
public NumassLoaderTreeBuilder() {
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void fillTree(TreeTableView<TreeItemValue> numassLoaderDataTree, NumassStorage rootStorage, Consumer<NumassData> numassViewBuilder) throws StorageException { @Override
protected Void call() throws Exception {
updateTitle("Load numass data ("+rootStorage.getName()+")");
TreeItem<TreeItemValue> root = buildNode(rootStorage, numassViewBuilder); TreeItem<TreeItemValue> root = buildNode(rootStorage, numassViewBuilder);
root.setExpanded(true); root.setExpanded(true);
@ -81,6 +86,7 @@ public class NumassLoaderTreeBuilder implements ProgressUpdateCallback {
numassLoaderTimeColumn.setVisible(false); numassLoaderTimeColumn.setVisible(false);
nummassLoaderDescriptionColumn.setVisible(false); nummassLoaderDescriptionColumn.setVisible(false);
}); });
return null;
} }
private TreeItem<TreeItemValue> buildNode(NumassStorage storage, Consumer<NumassData> numassViewBuilder) throws StorageException { private TreeItem<TreeItemValue> buildNode(NumassStorage storage, Consumer<NumassData> numassViewBuilder) throws StorageException {
@ -99,12 +105,12 @@ public class NumassLoaderTreeBuilder implements ProgressUpdateCallback {
} }
} }
setProgressText("Building storage " + storage.getName()); updateMessage("Building storage " + storage.getName());
double counter = 0; double counter = 0;
for (Loader loader : storage.loaders().values()) { for (Loader loader : storage.loaders().values()) {
setProgressText("Building numass data loader " + loader.getName()); updateMessage("Building numass data loader " + loader.getName());
setProgress(counter / storage.loaders().size()); updateProgress(counter, storage.loaders().size());
if (loader instanceof NumassData) { if (loader instanceof NumassData) {
NumassData numassLoader = (NumassData) loader; NumassData numassLoader = (NumassData) loader;
@ -126,8 +132,8 @@ public class NumassLoaderTreeBuilder implements ProgressUpdateCallback {
//adding legacy data files //adding legacy data files
counter = 0; counter = 0;
for (NumassData legacyDat : storage.legacyFiles()) { for (NumassData legacyDat : storage.legacyFiles()) {
setProgressText("Loading numass DAT file " + legacyDat.getName()); updateMessage("Loading numass DAT file " + legacyDat.getName());
setProgress(counter / storage.loaders().size()); updateProgress(counter, storage.loaders().size());
TreeItem<TreeItemValue> numassLoaderTreeItem = new TreeItem<>(buildValue(legacyDat)); TreeItem<TreeItemValue> numassLoaderTreeItem = new TreeItem<>(buildValue(legacyDat));
list.add(numassLoaderTreeItem); list.add(numassLoaderTreeItem);
counter++; counter++;
@ -197,7 +203,7 @@ public class NumassLoaderTreeBuilder implements ProgressUpdateCallback {
@Override @Override
public String getTime() { public String getTime() {
Instant startTime = loader.startTime(); Instant startTime = loader.startTime();
if (startTime == null) { if (startTime == null || startTime.equals(Instant.EPOCH)) {
return ""; return "";
} else { } else {
return loader.startTime().toString(); return loader.startTime().toString();
@ -211,20 +217,6 @@ public class NumassLoaderTreeBuilder implements ProgressUpdateCallback {
}; };
} }
@Override
public void setProgress(double progress) {
if (callback != null) {
callback.setProgress(progress);
}
}
@Override
public void setProgressText(String text) {
if (callback != null) {
callback.setProgressText(text);
}
}
public interface TreeItemValue { public interface TreeItemValue {
public String getName(); public String getName();

View File

@ -22,6 +22,7 @@ package inr.numass.viewer;
*/ */
import hep.dataforge.data.DataPoint; import hep.dataforge.data.DataPoint;
import hep.dataforge.data.DataSet; import hep.dataforge.data.DataSet;
import hep.dataforge.data.ListDataSet;
import hep.dataforge.data.MapDataPoint; import hep.dataforge.data.MapDataPoint;
import hep.dataforge.io.ColumnedDataWriter; import hep.dataforge.io.ColumnedDataWriter;
import hep.dataforge.meta.Meta; import hep.dataforge.meta.Meta;
@ -41,11 +42,16 @@ import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.concurrent.ExecutionException;
import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.concurrent.Task;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
@ -63,6 +69,8 @@ import javafx.stage.FileChooser;
import javafx.util.converter.NumberStringConverter; import javafx.util.converter.NumberStringConverter;
import org.controlsfx.control.CheckListView; import org.controlsfx.control.CheckListView;
import org.controlsfx.control.RangeSlider; import org.controlsfx.control.RangeSlider;
import org.controlsfx.validation.ValidationSupport;
import org.controlsfx.validation.Validator;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -73,21 +81,7 @@ import org.slf4j.LoggerFactory;
*/ */
public class NumassLoaderViewComponent extends AnchorPane implements Initializable { public class NumassLoaderViewComponent extends AnchorPane implements Initializable {
public static NumassLoaderViewComponent build(NumassData numassLoader) { private FXTaskManager callback;
NumassLoaderViewComponent component = new NumassLoaderViewComponent();
FXMLLoader loader = new FXMLLoader(component.getClass().getResource("/fxml/NumassLoaderView.fxml"));
loader.setRoot(component);
loader.setController(component);
try {
loader.load();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
component.setData(numassLoader);
return component;
}
Logger logger = LoggerFactory.getLogger(NumassLoaderViewComponent.class); Logger logger = LoggerFactory.getLogger(NumassLoaderViewComponent.class);
private NumassData data; private NumassData data;
@ -120,15 +114,29 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
private CheckBox detectorNormalizeSwitch; private CheckBox detectorNormalizeSwitch;
@FXML @FXML
private Button detectorDataExportButton; private Button detectorDataExportButton;
@FXML @FXML
private TextField lowChannelField; private TextField lowChannelField;
@FXML @FXML
private TextField upChannelField; private TextField upChannelField;
@FXML @FXML
private RangeSlider channelSlider; private RangeSlider channelSlider;
@FXML
private Button spectrumExportButton;
@FXML
private TextField dTimeField;
public NumassLoaderViewComponent() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/NumassLoaderView.fxml"));
loader.setRoot(this);
loader.setController(this);
try {
loader.load();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
/** /**
* Initializes the controller class. * Initializes the controller class.
@ -138,9 +146,8 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
*/ */
@Override @Override
public void initialize(URL url, ResourceBundle rb) { public void initialize(URL url, ResourceBundle rb) {
// TODO detectorBinningSelector.setItems(FXCollections.observableArrayList(1, 2, 5, 10, 20, 50));
detectorBinningSelector.setItems(FXCollections.observableArrayList(1, 2, 5, 10, 20)); detectorBinningSelector.getSelectionModel().select(4);
detectorBinningSelector.getSelectionModel().selectLast();
detectorNormalizeSwitch.setSelected(true); detectorNormalizeSwitch.setSelected(true);
detectorPointListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); detectorPointListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
@ -148,36 +155,83 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
lowChannelField.textProperty().bindBidirectional(channelSlider.lowValueProperty(), new NumberStringConverter()); lowChannelField.textProperty().bindBidirectional(channelSlider.lowValueProperty(), new NumberStringConverter());
upChannelField.textProperty().bindBidirectional(channelSlider.highValueProperty(), new NumberStringConverter()); upChannelField.textProperty().bindBidirectional(channelSlider.highValueProperty(), new NumberStringConverter());
channelSlider.setLowValue(300); channelSlider.setHighValue(1900d);
channelSlider.setHighValue(1900); channelSlider.setLowValue(300d);
ChangeListener<? super Number> rangeChangeListener = (ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> { ChangeListener<? super Number> rangeChangeListener = (ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
updateSpectrumPane(); updateSpectrumPane(points);
}; };
dTimeField.textProperty().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
updateSpectrumPane(points);
});
channelSlider.lowValueProperty().addListener(rangeChangeListener); channelSlider.lowValueProperty().addListener(rangeChangeListener);
channelSlider.highValueProperty().addListener(rangeChangeListener); channelSlider.highValueProperty().addListener(rangeChangeListener);
ValidationSupport validationSupport = new ValidationSupport();
Predicate<String> isNumber = (String t) -> {
try {
Double.parseDouble(t);
return true;
} catch (NumberFormatException | NullPointerException ex) {
return false;
}
};
validationSupport.registerValidator(dTimeField, Validator.createPredicateValidator(isNumber, "Must be number"));
} }
public NumassData getData() { public NumassData getData() {
return data; return data;
} }
public void setData(NumassData data) { public void setCallback(FXTaskManager callback) {
this.callback = callback;
}
public void loadData(NumassData data) {
this.data = data; this.data = data;
if (data != null) { if (data != null) {
points = data.getNMPoints(); LoadPointsTask task = new LoadPointsTask(data);
//setup detector data if (callback != null) {
setupDetectorPane(points); callback.postTask(task);
//setup spectrum plot }
updateSpectrumPane(); Viewer.runTask(task);
try {
setupInfo(data); this.points = task.get();
} catch (InterruptedException |ExecutionException ex) {
detectorTab.getTabPane().getSelectionModel().select(detectorTab); logger.error("Can't load spectrum data points", ex);
}
} else { } else {
logger.error("The data model is null"); logger.error("The data model is null");
} }
detectorTab.getTabPane().getSelectionModel().select(detectorTab);
}
private class LoadPointsTask extends Task<List<NMPoint>> {
private final NumassData loader;
public LoadPointsTask(NumassData loader) {
this.loader = loader;
}
@Override
protected List<NMPoint> call() throws Exception {
updateTitle("Load numass data (" + loader.getName() + ")");
List<NMPoint> points = loader.getNMPoints();
Platform.runLater(() -> {
//setup detector data
setupDetectorPane(points);
//setup spectrum plot
updateSpectrumPane(points);
setupInfo(data);
});
return points;
}
} }
/** /**
@ -192,11 +246,11 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
detectorBinningSelector.getSelectionModel().selectedItemProperty() detectorBinningSelector.getSelectionModel().selectedItemProperty()
.addListener((ObservableValue<? extends Integer> observable, Integer oldValue, Integer newValue) -> { .addListener((ObservableValue<? extends Integer> observable, Integer oldValue, Integer newValue) -> {
boolean norm = detectorNormalizeSwitch.isSelected(); boolean norm = detectorNormalizeSwitch.isSelected();
updateDetectorPane(fillDetectorData(points, newValue, norm)); updateDetectorPane(fillDetectorData(NumassLoaderViewComponent.this.points, newValue, norm));
}); });
detectorNormalizeSwitch.selectedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> { detectorNormalizeSwitch.selectedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
int bin = detectorBinningSelector.getValue(); int bin = detectorBinningSelector.getValue();
updateDetectorPane(fillDetectorData(points, bin, newValue)); updateDetectorPane(fillDetectorData(NumassLoaderViewComponent.this.points, bin, newValue));
}); });
detectorDataExportButton.setDisable(false); detectorDataExportButton.setDisable(false);
} }
@ -204,10 +258,10 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
private void setupInfo(NumassData loader) { private void setupInfo(NumassData loader) {
Meta info = loader.getInfo(); Meta info = loader.getInfo();
infoTextBox.setText(new JSONMetaWriter().writeString(info, null). infoTextBox.setText(new JSONMetaWriter().writeString(info, null).
replace("\\r", "\r").replace("\\n", "\n")); replace("\\r", "\r\t").replace("\\n", "\n\t"));
} }
private void updateSpectrumPane() { private void updateSpectrumPane(List<NMPoint> points) {
if (spectrumPlotFrame == null) { if (spectrumPlotFrame == null) {
Meta plotMeta = new MetaBuilder("plot") Meta plotMeta = new MetaBuilder("plot")
.setValue("xAxis.axisTitle", "U") .setValue("xAxis.axisTitle", "U")
@ -230,39 +284,31 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
spectrumData.clear(); spectrumData.clear();
} else { } else {
spectrumData.fillData(points.stream() spectrumData.fillData(points.stream()
.<DataPoint>map((NMPoint point) -> getSpectrumPoint(point, lowChannel, highChannel)) .<DataPoint>map((NMPoint point) -> getSpectrumPoint(point, lowChannel, highChannel, getDTime()))
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
} }
private DataPoint getSpectrumPoint(NMPoint point, int lowChannel, int highChannel) { private double getDTime() {
double u = point.getUread(); try {
double count = point.getCountInWindow(lowChannel, highChannel); return Double.parseDouble(dTimeField.getText()) * 1e-6;
double time = point.getLength(); } catch (NumberFormatException ex) {
double err = Math.sqrt(count); return 0;
return new MapDataPoint(new String[]{"x", "y", "yErr"}, u, count / time, err / time); }
}
private DataPoint getSpectrumPoint(NMPoint point, int lowChannel, int upChannel, double dTime) {
double u = point.getUread();
return new MapDataPoint(new String[]{"x", "y", "yErr"}, u,
point.getCountRate(lowChannel, upChannel, dTime),
point.getCountRateErr(lowChannel, upChannel, dTime));
} }
// private void setupSpectrumPane(List<NMPoint> points, int lowChannel, int upChannel) {
// updateSpectrumData(fillSpectrumData(points, (point) -> point.getCountInWindow(lowChannel, upChannel)));
// }
//
// private void updateSpectrumData(XYIntervalSeriesCollection data) {
// spectrumPlotPane.getChildren().clear();
// NumberAxis xAxis = new NumberAxis("HV");
// NumberAxis yAxis = new NumberAxis("count rate");
//
// xAxis.setAutoRangeIncludesZero(false);
// yAxis.setAutoRangeIncludesZero(false);
//
// XYPlot plot = new XYPlot(data, xAxis, yAxis, new XYErrorRenderer());
// JFreeChart spectrumPlot = new JFreeChart("spectrum", plot);
// displayPlot(spectrumPlotPane, spectrumPlot);
// }
/** /**
* update detector pane with new data * update detector pane with new data
*/ */
private void updateDetectorPane(List<XYPlottable> detectorData) { private void updateDetectorPane(List<XYPlottable> detectorData) {
Platform.runLater(() -> {
if (detectorData == null) { if (detectorData == null) {
throw new IllegalArgumentException("Detector data not defined"); throw new IllegalArgumentException("Detector data not defined");
} }
@ -297,6 +343,7 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
detectorPlotFrame.get(plotName).getConfig().setValue("visible", newValue); detectorPlotFrame.get(plotName).getConfig().setValue("visible", newValue);
}); });
} }
});
} }
private List<XYPlottable> fillDetectorData(List<NMPoint> points, int binning, boolean normalize) { private List<XYPlottable> fillDetectorData(List<NMPoint> points, int binning, boolean normalize) {
@ -317,27 +364,6 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
return plottables; return plottables;
} }
// /**
// * Fill spectrum with custom window calculator
// *
// * @param points
// * @param lowerBoundCalculator
// * @param upperBoundCalculator
// * @return
// */
// private XYIntervalSeriesCollection fillSpectrumData(List<NMPoint> points, Function<NMPoint, Number> calculator) {
// XYIntervalSeriesCollection collection = new XYIntervalSeriesCollection();
// XYIntervalSeries ser = new XYIntervalSeries("spectrum");
// for (NMPoint point : points) {
// double u = point.getUread();
// double count = calculator.apply(point).doubleValue();
// double time = point.getLength();
// double err = Math.sqrt(count);
// ser.add(u, u, u, count / time, (count - err) / time, (count + err) / time);
// }
// collection.addSeries(ser);
// return collection;
// }
@FXML @FXML
private void checkAllAction(ActionEvent event) { private void checkAllAction(ActionEvent event) {
detectorPointListView.getCheckModel().checkAll(); detectorPointListView.getCheckModel().checkAll();
@ -362,6 +388,49 @@ public class NumassLoaderViewComponent extends AnchorPane implements Initializab
} }
} }
@FXML
private void onSpectrumExportClick(ActionEvent event) {
if (points != null && !points.isEmpty()) {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Choose text export destination");
fileChooser.setInitialFileName(data.getName() + "_spectrum.out");
File destination = fileChooser.showSaveDialog(spectrumPlotPane.getScene().getWindow());
if (destination != null) {
String[] names = new String[]{"Uset", "Uread", "Length", "Total", "Window", "CR", "CRerr", "Timestamp"};
int loChannel = (int) channelSlider.getLowValue();
int upChannel = (int) channelSlider.getHighValue();
double dTime = getDTime();
ListDataSet spectrumDataSet = new ListDataSet(names);
for (NMPoint point : points) {
spectrumDataSet.add(new MapDataPoint(names, new Object[]{
point.getUset(),
point.getUread(),
point.getLength(),
point.getEventsCount(),
point.getCountInWindow(loChannel, upChannel),
point.getCountRate(loChannel, upChannel, dTime),
point.getCountRateErr(loChannel, upChannel, dTime),
point.getStartTime()
}
));
}
try {
String comment = String.format("Numass data viewer spectrum data export for %s%n"
+ "Window: (%d, %d)%n"
+ "Dead time per event: %g%n",
data.getName(), loChannel, upChannel, dTime);
ColumnedDataWriter
.writeDataSet(destination, spectrumDataSet, comment, false);
} catch (IOException ex) {
LoggerFactory.getLogger(getClass()).error("Destination file not found", ex);
}
}
}
}
private void onExportButtonClick(ActionEvent event) { private void onExportButtonClick(ActionEvent event) {
FileChooser fileChooser = new FileChooser(); FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Choose text export destination"); fileChooser.setTitle("Choose text export destination");

View File

@ -36,7 +36,8 @@ public class TestDirectoryViewer extends Application {
NumassDataLoader reader = NumassDataLoader.fromLocalDir(null, new File("C:\\Users\\darksnake\\Dropbox\\PlayGround\\data-test\\20150703143643_1\\")); NumassDataLoader reader = NumassDataLoader.fromLocalDir(null, new File("C:\\Users\\darksnake\\Dropbox\\PlayGround\\data-test\\20150703143643_1\\"));
// NumassLoader reader = NumassLoader.fromZip(null, new File("C:\\Users\\darksnake\\Dropbox\\PlayGround\\data-test\\20150703143643_1.zip")); // NumassLoader reader = NumassLoader.fromZip(null, new File("C:\\Users\\darksnake\\Dropbox\\PlayGround\\data-test\\20150703143643_1.zip"));
NumassLoaderViewComponent comp = NumassLoaderViewComponent.build(reader); NumassLoaderViewComponent comp = new NumassLoaderViewComponent();
comp.loadData(reader);
// FXMLLoader fxml = new FXMLLoader(getClass().getResource("/fxml/DirectoryViewer.fxml")); // FXMLLoader fxml = new FXMLLoader(getClass().getResource("/fxml/DirectoryViewer.fxml"));
// //
// Parent parent = fxml.load(); // Parent parent = fxml.load();

View File

@ -19,6 +19,7 @@ import hep.dataforge.exceptions.StorageException;
import hep.dataforge.storage.commons.StoragePlugin; import hep.dataforge.storage.commons.StoragePlugin;
import java.io.IOException; import java.io.IOException;
import javafx.application.Application; import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
@ -34,7 +35,6 @@ public class Viewer extends Application {
public void start(Stage primaryStage) throws StorageException, IOException { public void start(Stage primaryStage) throws StorageException, IOException {
new StoragePlugin().startGlobal(); new StoragePlugin().startGlobal();
FXMLLoader fxml = new FXMLLoader(getClass().getResource("/fxml/MainView.fxml")); FXMLLoader fxml = new FXMLLoader(getClass().getResource("/fxml/MainView.fxml"));
Parent parent = fxml.load(); Parent parent = fxml.load();
@ -52,7 +52,11 @@ public class Viewer extends Application {
System.exit(0); System.exit(0);
} }
public static void runTask(Task task) {
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
}
/** /**
* @param args the command line arguments * @param args the command line arguments

View File

@ -16,6 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<?import org.controlsfx.control.textfield.*?>
<?import org.controlsfx.control.*?> <?import org.controlsfx.control.*?>
<?import javafx.geometry.*?> <?import javafx.geometry.*?>
<?import java.lang.*?> <?import java.lang.*?>
@ -24,9 +25,9 @@ limitations under the License.
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<fx:root id="AnchorPane" prefHeight="400.0" prefWidth="600.0" type="AnchorPane" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1"> <fx:root id="AnchorPane" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" type="AnchorPane" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children> <children>
<TabPane layoutX="200.0" layoutY="100.0" prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <TabPane layoutX="200.0" layoutY="100.0" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<tabs> <tabs>
<Tab text="Info"> <Tab text="Info">
<content> <content>
@ -41,15 +42,10 @@ limitations under the License.
<content> <content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0"> <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children> <children>
<BorderPane layoutX="200.0" layoutY="86.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <SplitPane dividerPositions="0.5" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<center> <items>
<AnchorPane fx:id="detectorPlotPane" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" /> <AnchorPane fx:id="detectorPlotPane" minHeight="300.0" minWidth="300.0" prefHeight="200.0" prefWidth="200.0" />
</center> <VBox fx:id="detectorOptionsPane" maxWidth="250.0" prefWidth="200.0" spacing="2.0" style="-fx-border-color: blue;">
<right>
<VBox fx:id="detectorOptionsPane" minWidth="-Infinity" prefWidth="200.0" spacing="2.0" style="-fx-border-color: blue;" BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets />
</BorderPane.margin>
<children> <children>
<Label text="Channels per bin"> <Label text="Channels per bin">
<VBox.margin> <VBox.margin>
@ -78,8 +74,8 @@ limitations under the License.
<padding> <padding>
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" /> <Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
</padding></VBox> </padding></VBox>
</right> </items>
</BorderPane> </SplitPane>
</children> </children>
</AnchorPane> </AnchorPane>
</content> </content>
@ -91,7 +87,7 @@ limitations under the License.
</Tab> </Tab>
<Tab fx:id="spectrumTab" text="Spectrum"> <Tab fx:id="spectrumTab" text="Spectrum">
<content> <content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0"> <AnchorPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0">
<children> <children>
<BorderPane prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <BorderPane prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<center> <center>
@ -100,9 +96,32 @@ limitations under the License.
<top> <top>
<ToolBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER"> <ToolBar prefHeight="40.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<items> <items>
<VBox>
<children>
<Label text="Lo channel" />
<TextField fx:id="lowChannelField" prefWidth="60.0" /> <TextField fx:id="lowChannelField" prefWidth="60.0" />
<RangeSlider fx:id="channelSlider" accessibleRole="SLIDER" highValue="1900.0" lowValue="300.0" majorTickUnit="500.0" max="4000.0" minorTickCount="5" prefHeight="38.0" prefWidth="336.0" showTickLabels="true" showTickMarks="true" /> </children>
</VBox>
<RangeSlider fx:id="channelSlider" accessibleRole="SLIDER" highValue="1900.0" lowValue="300.0" majorTickUnit="500.0" max="4000.0" minorTickCount="5" prefHeight="38.0" prefWidth="276.0" showTickLabels="true" showTickMarks="true">
<padding>
<Insets left="10.0" right="10.0" />
</padding></RangeSlider>
<VBox>
<children>
<Label text="Up channel" />
<TextField fx:id="upChannelField" prefWidth="60.0" /> <TextField fx:id="upChannelField" prefWidth="60.0" />
</children>
</VBox>
<Separator orientation="VERTICAL" />
<VBox>
<children>
<Label text="Dead time (us)" />
<TextField fx:id="dTimeField" prefHeight="25.0" prefWidth="0.0" text="7.2" />
</children>
</VBox>
<Separator orientation="VERTICAL" />
<Pane minWidth="0.0" HBox.hgrow="ALWAYS" />
<Button fx:id="spectrumExportButton" mnemonicParsing="false" onAction="#onSpectrumExportClick" text="Export" />
</items> </items>
</ToolBar> </ToolBar>
</top> </top>