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

@ -13,244 +13,248 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package inr.numass.data; 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;
/** /**
* *
* @author Darksnake * @author Darksnake
*/ */
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;
private long eventsCount; private long eventsCount;
private int overflow; private int overflow;
private double pointLength; private double pointLength;
// private final MeasurementPoint point; // private final MeasurementPoint point;
private final int[] spectrum; private final int[] spectrum;
private double uread; private double uread;
private double uset; private double uset;
public NMPoint(RawNMPoint point) { public NMPoint(RawNMPoint point) {
if (point == null) { if (point == null) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
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);
} }
// public PointSpectrum(RawPoint point, double deadTime) { // public PointSpectrum(RawPoint point, double deadTime) {
// this(point); // this(point);
// this.deadTime = deadTime; // this.deadTime = deadTime;
// } // }
private int[] calculateSpectrum(RawNMPoint point) { private int[] calculateSpectrum(RawNMPoint point) {
assert point.getEventsCount() > 0; assert point.getEventsCount() > 0;
int[] result = new int[RawNMPoint.MAX_CHANEL]; int[] result = new int[RawNMPoint.MAX_CHANEL];
Arrays.fill(result, 0); Arrays.fill(result, 0);
point.getEvents().stream().forEach((event) -> { point.getEvents().stream().forEach((event) -> {
if (event.getChanel() >= RawNMPoint.MAX_CHANEL) { if (event.getChanel() >= RawNMPoint.MAX_CHANEL) {
overflow++; overflow++;
} else { } else {
result[event.getChanel()]++; result[event.getChanel()]++;
} }
}); });
return result; return result;
} }
public DataPoint fastSlice(int... borders) { public DataPoint fastSlice(int... borders) {
assert borders.length > 0;//FIXME replace by condition check assert borders.length > 0;//FIXME replace by condition check
sort(borders); sort(borders);
assert borders[borders.length] < RawNMPoint.MAX_CHANEL;//FIXME replace by condition check assert borders[borders.length] < RawNMPoint.MAX_CHANEL;//FIXME replace by condition check
Integer[] slices = new Integer[borders.length + 2]; Integer[] slices = new Integer[borders.length + 2];
String[] names = new String[borders.length + 2]; String[] names = new String[borders.length + 2];
slices[0] = getCountInWindow(0, borders[0]); slices[0] = getCountInWindow(0, borders[0]);
names[0] = Integer.toString(borders[0]); names[0] = Integer.toString(borders[0]);
for (int i = 1; i < borders.length; i++) { for (int i = 1; i < borders.length; i++) {
slices[i] = getCountInWindow(borders[i - 1], borders[i]); slices[i] = getCountInWindow(borders[i - 1], borders[i]);
names[i] = Integer.toString(borders[i]); names[i] = Integer.toString(borders[i]);
} }
slices[borders.length + 1] = getCountInWindow(borders[borders.length], RawNMPoint.MAX_CHANEL); slices[borders.length + 1] = getCountInWindow(borders[borders.length], RawNMPoint.MAX_CHANEL);
names[borders.length + 1] = Integer.toString(RawNMPoint.MAX_CHANEL); names[borders.length + 1] = Integer.toString(RawNMPoint.MAX_CHANEL);
slices[borders.length + 2] = RawNMPoint.MAX_CHANEL; slices[borders.length + 2] = RawNMPoint.MAX_CHANEL;
names[borders.length + 2] = "TOTAL"; names[borders.length + 2] = "TOTAL";
//FIXME fix it! //FIXME fix it!
return new MapDataPoint(names, slices); return new MapDataPoint(names, slices);
} }
/** /**
* @return the absouteTime * @return the absouteTime
*/ */
public LocalDateTime getAbsouteTime() { public Instant getStartTime() {
return absouteTime; if (startTime == null) {
} return Instant.EPOCH;
} else {
public int getCountInChanel(int chanel) { return startTime;
return spectrum[chanel]; }
} }
public int getCountInWindow(int from, int to) { public int getCountInChanel(int chanel) {
int res = 0; return spectrum[chanel];
for (int i = from; i <= to; i++) { }
res += spectrum[i];
} public int getCountInWindow(int from, int to) {
if (res == Integer.MAX_VALUE) { int res = 0;
throw new RuntimeException("integer overflow in spectrum calculation"); for (int i = from; i <= to; i++) {
} res += spectrum[i];
return res; }
} if (res == Integer.MAX_VALUE) {
throw new RuntimeException("integer overflow in spectrum calculation");
public double getCountRate(int from, int to, double deadTime) { }
double wind = getCountInWindow(from, to) / getLength(); return res;
double res; }
if (deadTime > 0) {
double total = getEventsCount(); public double getCountRate(int from, int to, double deadTime) {
double time = getLength(); double wind = getCountInWindow(from, to) / getLength();
res = wind / (1 - total * deadTime / time); double res;
} else { if (deadTime > 0) {
res = wind; double total = getEventsCount();
} double time = getLength();
return res; res = wind / (1 - total * deadTime / time);
} } else {
res = wind;
public double getCountRateErr(int from, int to, double deadTime) { }
return Math.sqrt(getCountRate(from, to, deadTime) / getLength()); return res;
} }
public List<DataPoint> getData() { public double getCountRateErr(int from, int to, double deadTime) {
List<DataPoint> data = new ArrayList<>(); return Math.sqrt(getCountRate(from, to, deadTime) / getLength());
for (int i = 0; i < RawNMPoint.MAX_CHANEL; i++) { }
data.add(new MapDataPoint(dataNames, i, spectrum[i]));
public List<DataPoint> getData() {
} List<DataPoint> data = new ArrayList<>();
return data; for (int i = 0; i < RawNMPoint.MAX_CHANEL; i++) {
} data.add(new MapDataPoint(dataNames, i, spectrum[i]));
/** }
* Events count - overflow return data;
* }
* @return
*/ /**
public long getEventsCount() { * Events count - overflow
return eventsCount - getOverflow(); *
} * @return
*/
public List<DataPoint> getData(int binning, boolean normalize) { public long getEventsCount() {
List<DataPoint> data = new ArrayList<>(); return eventsCount - getOverflow();
}
double norm;
if (normalize) { public List<DataPoint> getData(int binning, boolean normalize) {
norm = getLength(); List<DataPoint> data = new ArrayList<>();
} else {
norm = 1d; double norm;
} if (normalize) {
norm = getLength();
int i = 0; } else {
norm = 1d;
while (i < RawNMPoint.MAX_CHANEL - binning) { }
int start = i;
double sum = spectrum[start] / norm; int i = 0;
while (i < start + binning) {
sum += spectrum[i] / norm; while (i < RawNMPoint.MAX_CHANEL - binning) {
i++; int start = i;
} double sum = spectrum[start] / norm;
data.add(new MapDataPoint(dataNames, start + binning / 2d, sum)); while (i < start + binning) {
i++; sum += spectrum[i] / norm;
} i++;
return data; }
} data.add(new MapDataPoint(dataNames, start + binning / 2d, sum));
i++;
public Map<Double, Double> getMapWithBinning(int binning, boolean normalize) { }
Map<Double, Double> res = new LinkedHashMap<>(); return data;
}
double norm;
if (normalize) { public Map<Double, Double> getMapWithBinning(int binning, boolean normalize) {
norm = getLength(); Map<Double, Double> res = new LinkedHashMap<>();
} else {
norm = 1d; double norm;
} if (normalize) {
norm = getLength();
int i = 0; } else {
norm = 1d;
while (i < RawNMPoint.MAX_CHANEL - binning) { }
int start = i;
double sum = spectrum[start] / norm; int i = 0;
while (i < start + binning) {
sum += spectrum[i] / norm; while (i < RawNMPoint.MAX_CHANEL - binning) {
i++; int start = i;
} double sum = spectrum[start] / norm;
res.put(start + binning / 2d, sum); while (i < start + binning) {
i++; sum += spectrum[i] / norm;
} i++;
return res; }
res.put(start + binning / 2d, sum);
} i++;
}
public Map<Double, Double> getMapWithBinning(NMPoint reference, int binning) { return res;
Map<Double, Double> sp = this.getMapWithBinning(binning, true);
Map<Double, Double> referenceSpectrum = reference.getMapWithBinning(binning, true); }
Map<Double, Double> res = new LinkedHashMap<>(); public Map<Double, Double> getMapWithBinning(NMPoint reference, int binning) {
Map<Double, Double> sp = this.getMapWithBinning(binning, true);
sp.entrySet().stream().map((entry) -> entry.getKey()).forEach((bin) -> { Map<Double, Double> referenceSpectrum = reference.getMapWithBinning(binning, true);
res.put(bin, Math.max(sp.get(bin) - referenceSpectrum.get(bin), 0));
}); Map<Double, Double> res = new LinkedHashMap<>();
return res; sp.entrySet().stream().map((entry) -> entry.getKey()).forEach((bin) -> {
res.put(bin, Math.max(sp.get(bin) - referenceSpectrum.get(bin), 0));
} });
/** return res;
* @return the overflow
*/ }
public int getOverflow() {
return overflow; /**
} * @return the overflow
*/
/** public int getOverflow() {
* @return the pointLength return overflow;
*/ }
public double getLength() {
return pointLength; /**
} * @return the pointLength
*/
/** public double getLength() {
* @return the uread return pointLength;
*/ }
public double getUread() {
return uread; /**
} * @return the uread
*/
/** public double getUread() {
* @return the uset return uread;
*/ }
public double getUset() {
return uset; /**
} * @return the uset
*/
} public double getUset() {
return uset;
}
}

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

@ -13,169 +13,170 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
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;
/** /**
* Хранит информацию о спектре точки, но не об отдельных событиях. * Хранит информацию о спектре точки, но не об отдельных событиях.
* *
* @author Darksnake * @author Darksnake
*/ */
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;
public RawNMPoint(double U, List<NMEvent> events, double t) { public RawNMPoint(double U, List<NMEvent> events, double t) {
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;
} }
RawNMPoint() { RawNMPoint() {
events = new ArrayList<>(); events = new ArrayList<>();
uset = 0; uset = 0;
uread = 0; uread = 0;
t = Double.NaN; length = Double.NaN;
} }
@Override @Override
public RawNMPoint clone() { public RawNMPoint clone() {
ArrayList<NMEvent> newevents = new ArrayList<>(); ArrayList<NMEvent> newevents = new ArrayList<>();
for (NMEvent event : this.getEvents()) { for (NMEvent event : this.getEvents()) {
newevents.add(event.clone()); newevents.add(event.clone());
} }
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() {
return getEventsCount() / getLength(); return getEventsCount() / getLength();
} }
public double getCRError() { public double getCRError() {
return Math.sqrt(getEventsCount()) / getLength(); return Math.sqrt(getEventsCount()) / getLength();
} }
/** /**
* @return the events * @return the events
*/ */
public List<NMEvent> getEvents() { public List<NMEvent> getEvents() {
return events; return events;
} }
public long getEventsCount() { public long getEventsCount() {
return events.size(); return events.size();
} }
/** /**
* Measurement time * Measurement time
* @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;
} }
/** /**
* @return the Uread * @return the Uread
*/ */
public double getUread() { public double getUread() {
if (uread <= 0) { if (uread <= 0) {
return getUset(); return getUset();
} else { } else {
return uread; return uread;
} }
} }
/** /**
* @return the Uset * @return the Uset
*/ */
public double getUset() { public double getUset() {
if (uset < 0) { if (uset < 0) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
return uset; return uset;
} }
public RawNMPoint merge(RawNMPoint point) { public RawNMPoint merge(RawNMPoint point) {
RawNMPoint res = this.clone(); RawNMPoint res = this.clone();
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;
} }
void putEvent(NMEvent event) { void putEvent(NMEvent event) {
events.add(event); events.add(event);
} }
public RawNMPoint selectChanels(int from, int to) { public RawNMPoint selectChanels(int from, int to) {
assert to > from; assert to > from;
List<NMEvent> res = new ArrayList<>(); List<NMEvent> res = new ArrayList<>();
for (NMEvent event : this.getEvents()) { for (NMEvent event : this.getEvents()) {
if ((event.getChanel() >= from) && (event.getChanel() <= to)) { if ((event.getChanel() >= from) && (event.getChanel() <= to)) {
res.add(event); res.add(event);
} }
} }
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;
} }
/** /**
* @param Uread the Uread to set * @param Uread the Uread to set
*/ */
void setUread(double Uread) { void setUread(double Uread) {
assert Uread >= 0; assert Uread >= 0;
this.uread = Uread; this.uread = Uread;
} }
/** /**
* @param Uset the Uset to set * @param Uset the Uset to set
*/ */
void setUset(double Uset) { void setUset(double Uset) {
this.uset = Uset; this.uset = Uset;
} }
}
}

View File

@ -13,100 +13,94 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package inr.numass.data; package inr.numass.data;
import hep.dataforge.meta.Meta; import hep.dataforge.data.DataAdapter;
import hep.dataforge.data.DataPoint; import hep.dataforge.meta.Meta;
import hep.dataforge.data.MapDataPoint; import hep.dataforge.data.DataPoint;
import hep.dataforge.data.XYDataAdapter; import hep.dataforge.data.MapDataPoint;
import hep.dataforge.exceptions.DataFormatException; import hep.dataforge.data.XYDataAdapter;
import hep.dataforge.exceptions.NameNotFoundException; import hep.dataforge.exceptions.DataFormatException;
import hep.dataforge.names.Names; import hep.dataforge.exceptions.NameNotFoundException;
import hep.dataforge.values.Value; import hep.dataforge.meta.MetaBuilder;
import hep.dataforge.values.Value;
/**
* /**
* @author Darksnake *
*/ * @author Darksnake
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 meta) {
public SpectrumDataAdapter(Meta aliasAnnotation) { super(meta);
super(aliasAnnotation); }
this.timeName = aliasAnnotation.getString(ANNOTATION_TIMENAME, "X");
} public SpectrumDataAdapter(String xName, String yName, String yErrName, String measurementTime) {
super(new MetaBuilder(DataAdapter.DATA_ADAPTER_ANNOTATION_NAME)
public SpectrumDataAdapter(String xName, String yName, String yErrName, String timeTime) { .setValue(X_NAME, xName)
super(xName, yName, yErrName); .setValue(Y_NAME, yName)
this.timeName = timeTime; .setValue(Y_ERR_NAME, yErrName)
} .setValue(POINT_LENGTH_NAME, measurementTime)
.build()
public SpectrumDataAdapter(String xName, String yName, String timeTime) { );
super(xName, yName); }
this.timeName = timeTime;
} public SpectrumDataAdapter(String xName, String yName, String measurementTime) {
super(new MetaBuilder(DataAdapter.DATA_ADAPTER_ANNOTATION_NAME)
public double getTime(DataPoint point) { .setValue(X_NAME, xName)
if (point.names().contains(timeName)) { .setValue(Y_NAME, yName)
return point.getDouble(timeName); .setValue(POINT_LENGTH_NAME, measurementTime)
} else { .build()
return 1d; );
} }
}
public double getTime(DataPoint point) {
public DataPoint buildSpectrumDataPoint(double x, long count, double t) { return this.getFrom(point, POINT_LENGTH_NAME, 1d).doubleValue();
return new MapDataPoint(new String[]{xName,yName,timeName}, x,count,t); }
}
public DataPoint buildSpectrumDataPoint(double x, long count, double t) {
public DataPoint buildSpectrumDataPoint(double x, long count, double countErr, double t) { return new MapDataPoint(new String[]{getValueName(X_NAME), getValueName(Y_NAME),
return new MapDataPoint(new String[]{xName,yName,yErrName,timeName}, x,count,countErr,t); getValueName(POINT_LENGTH_NAME)},
} x, count, t);
}
@Override
public Meta buildAnnotation() { public DataPoint buildSpectrumDataPoint(double x, long count, double countErr, double t) {
Meta res = super.buildAnnotation(); return new MapDataPoint(new String[]{getValueName(X_NAME), getValueName(Y_NAME),
res.getBuilder().putValue(ANNOTATION_TIMENAME, timeName); getValueName(Y_ERR_NAME), getValueName(POINT_LENGTH_NAME)},
return res; x, count, countErr, t);
} }
@Override @Override
public Names getNames() { public boolean providesYError(DataPoint point) {
return Names.of(xName,yName); return true;
} }
@Override @Override
public boolean providesYError(DataPoint point) { public Value getYerr(DataPoint point) throws NameNotFoundException {
return true; if (providesYError(point)) {
} return Value.of(super.getYerr(point).doubleValue() / getTime(point));
} else {
double y = super.getY(point).doubleValue();
if (y <= 0) {
@Override throw new DataFormatException();
public Value getYerr(DataPoint point) throws NameNotFoundException { } else {
if (point.names().contains(yErrName)) { return Value.of(Math.sqrt(y) / getTime(point));
return Value.of(super.getYerr(point).doubleValue()/getTime(point)); }
} else{ }
double y = super.getY(point).doubleValue(); }
if(y<=0) throw new DataFormatException();
else { public long getCount(DataPoint point) {
return Value.of(Math.sqrt(y)/getTime(point)); return super.getY(point).numberValue().longValue();
} }
}
} @Override
public Value getY(DataPoint point) {
public long getCount(DataPoint point){ return Value.of(super.getY(point).doubleValue() / getTime(point));
return point.getValue(yName).numberValue().longValue(); }
}
}
@Override
public Value getY(DataPoint point) {
return Value.of(super.getY(point).doubleValue() / getTime(point));
}
}

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

@ -13,71 +13,71 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package inr.numass.debunch; package inr.numass.debunch;
import inr.numass.data.NMEvent; import inr.numass.data.NMEvent;
import inr.numass.data.RawNMPoint; import inr.numass.data.RawNMPoint;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* *
* @author Darksnake * @author Darksnake
*/ */
public class DebunchReportImpl implements DebunchReport { public class DebunchReportImpl implements DebunchReport {
private final List<Frame> bunches; private final List<Frame> bunches;
private final RawNMPoint pointAfter; private final RawNMPoint pointAfter;
private final RawNMPoint pointBefore; private final RawNMPoint pointBefore;
public DebunchReportImpl(RawNMPoint pointBefore, RawNMPoint pointAfter, List<Frame> bunches) { public DebunchReportImpl(RawNMPoint pointBefore, RawNMPoint pointAfter, List<Frame> bunches) {
this.pointBefore = pointBefore; this.pointBefore = pointBefore;
this.pointAfter = pointAfter; this.pointAfter = pointAfter;
this.bunches = bunches; this.bunches = bunches;
} }
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();
} }
@Override @Override
public double eventsFiltred() { public double eventsFiltred() {
return 1-(double)getPoint().getEventsCount()/getInitialPoint().getEventsCount(); return 1-(double)getPoint().getEventsCount()/getInitialPoint().getEventsCount();
} }
@Override @Override
public List<NMEvent> getBunchEvents() { public List<NMEvent> getBunchEvents() {
List<NMEvent> res = new ArrayList<>(); List<NMEvent> res = new ArrayList<>();
for (Frame interval : getBunches()) { for (Frame interval : getBunches()) {
res.addAll(interval.getEvents()); res.addAll(interval.getEvents());
} }
return res; return res;
} }
@Override @Override
public List<Frame> getBunches() { public List<Frame> getBunches() {
return bunches; return bunches;
} }
@Override @Override
public RawNMPoint getInitialPoint() { public RawNMPoint getInitialPoint() {
return pointBefore; return pointBefore;
} }
@Override @Override
public RawNMPoint getPoint() { public RawNMPoint getPoint() {
return pointAfter; return pointAfter;
} }
@Override @Override
public double timeFiltred() { public double timeFiltred() {
return 1-getPoint().getLength()/getInitialPoint().getLength(); return 1-getPoint().getLength()/getInitialPoint().getLength();
} }
} }

View File

@ -13,171 +13,174 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package inr.numass.generators; package inr.numass.generators;
import inr.numass.data.NMEvent; import inr.numass.data.NMEvent;
import inr.numass.data.RawNMPoint; import inr.numass.data.RawNMPoint;
import static java.lang.Math.max; 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;
* @author Darksnake
*/ /**
public final class EventChainGenerator { *
* @author Darksnake
private final static double us = 1e-6; */
public final class EventChainGenerator {
private double blockStartTime = 0;
private final static double us = 1e-6;
private final List<NMEvent> generatedChain = new ArrayList<>();
private final EventGenerator generator; private double blockStartTime = 0;
private final double length;
private final List<NMEvent> pileupChain = new ArrayList<>(); private final List<NMEvent> generatedChain = new ArrayList<>();
private final EventGenerator generator;
private final List<NMEvent> registredChain = new ArrayList<>(); private final double length;
private final List<NMEvent> pileupChain = new ArrayList<>();
public EventChainGenerator(double cr, double length) {
generator = new EventGenerator(cr); private final List<NMEvent> registredChain = new ArrayList<>();
this.length = length;
public EventChainGenerator(double cr, double length) {
run(); generator = new EventGenerator(cr);
} this.length = length;
public EventChainGenerator(double cr, double length, RawNMPoint source, int minChanel, int maxChanel) { run();
generator = new EventGenerator(cr); }
this.generator.loadFromPoint(source, minChanel, maxChanel);
this.length = length; public EventChainGenerator(double cr, double length, RawNMPoint source, int minChanel, int maxChanel) {
generator = new EventGenerator(cr);
run(); this.generator.loadFromPoint(source, minChanel, maxChanel);
} this.length = length;
public EventChainGenerator(double cr, double length, Map<Double,Double> spectrum, int minChanel, int maxChanel) { run();
generator = new EventGenerator(cr); }
this.generator.loadFromSpectrum(spectrum, minChanel, maxChanel);
this.length = length; public EventChainGenerator(double cr, double length, Map<Double,Double> spectrum, int minChanel, int maxChanel) {
generator = new EventGenerator(cr);
run(); this.generator.loadFromSpectrum(spectrum, minChanel, maxChanel);
} this.length = length;
/** run();
* Амлпитуда второго сигнала в зависимости от амплитуд наложенных сигналов и }
* задержки
* /**
* @param delay * Амлпитуда второго сигнала в зависимости от амплитуд наложенных сигналов и
* @return * задержки
*/ *
private short getNewChanel(double delay, short prevChanel, short newChanel) { * @param delay
assert delay > 0; * @return
//эмпирическая формула для канала */
double x = delay / us; private short getNewChanel(double delay, short prevChanel, short newChanel) {
double coef = max(0, 0.99078 + 0.05098 * x - 0.45775 * x * x + 0.10962 * x * x * x); assert delay > 0;
//эмпирическая формула для канала
return (short) (prevChanel + coef * newChanel); double x = delay / us;
} double coef = max(0, 0.99078 + 0.05098 * x - 0.45775 * x * x + 0.10962 * x * x * x);
public RawNMPoint getPileUp() { return (short) (prevChanel + coef * newChanel);
return new RawNMPoint(2, pileupChain, length); }
}
public RawNMPoint getPileUp() {
public RawNMPoint getPointAsGenerated() { return new RawNMPoint(2, pileupChain, length);
return new RawNMPoint(0, generatedChain, length); }
}
public RawNMPoint getPointAsGenerated() {
public RawNMPoint getPointAsRegistred() { return new RawNMPoint(0, generatedChain, length);
return new RawNMPoint(1, registredChain, length); }
}
public RawNMPoint getPointAsRegistred() {
/** return new RawNMPoint(1, registredChain, length);
* Имеется второй сигнал }
*
* @param delay /**
* @return * Имеется второй сигнал
*/ *
private boolean hasNew(double delay) { * @param delay
if (delay > 2.65 * us) { * @return
return false; */
} else if (delay < 2.35 * us) { private boolean hasNew(double delay) {
return true; if (delay > 2.65 * us) {
} else { return false;
return heads((2.65 * us - delay) / 0.3 / us); } else if (delay < 2.35 * us) {
} return true;
} } else {
return heads((2.65 * us - delay) / 0.3 / us);
private boolean heads(double prob) { }
double r = generator.nextUniform(); }
return r < prob;
} private boolean heads(double prob) {
double r = generator.nextUniform();
NMEvent nextEvent(NMEvent prev) { return r < prob;
if (prev == null) { }
return generator.nextEvent(new NMEvent((short)0, 0));
} NMEvent nextEvent(NMEvent prev) {
if (prev == null) {
NMEvent event = generator.nextEvent(prev); return generator.nextEvent(new NMEvent((short)0, 0));
generatedChain.add(event); }
double delay = event.getTime() - blockStartTime;
if (notDT(delay)) { NMEvent event = generator.nextEvent(prev);
//Если система сбора данных успела переварить предыдущие события generatedChain.add(event);
registredChain.add(event); double delay = event.getTime() - blockStartTime;
blockStartTime = event.getTime(); if (notDT(delay)) {
return event; //Если система сбора данных успела переварить предыдущие события
} else { registredChain.add(event);
if ((!prevSurvived(delay)) && (!registredChain.isEmpty())) { blockStartTime = event.getTime();
//если первое событие не выжило, а ушло в наложения return event;
registredChain.remove(registredChain.size() - 1); } else {
} if ((!prevSurvived(delay)) && (!registredChain.isEmpty())) {
if (hasNew(delay)) { //если первое событие не выжило, а ушло в наложения
// Если есть событие с увеличенной амлитудой registredChain.remove(registredChain.size() - 1);
NMEvent pileup = new NMEvent(getNewChanel(delay, prev.getChanel(), event.getChanel()), event.getTime()); }
registredChain.add(pileup); if (hasNew(delay)) {
pileupChain.add(pileup); // Если есть событие с увеличенной амлитудой
} NMEvent pileup = new NMEvent(getNewChanel(delay, prev.getChanel(), event.getChanel()), event.getTime());
//возвращаем предыдущее событие, чтобы отсчитывать мертвое время от него registredChain.add(pileup);
return prev; pileupChain.add(pileup);
} }
} //возвращаем предыдущее событие, чтобы отсчитывать мертвое время от него
return prev;
/** }
* Не попал в мертвое время и наложения }
*
* @param delay /**
* @return * Не попал в мертвое время и наложения
*/ *
private boolean notDT(double delay) { * @param delay
if (delay > 7.0 * us) { * @return
return true; */
} else if (delay < 6.5 * us) { private boolean notDT(double delay) {
return false; if (delay > 7.0 * us) {
} else { return true;
return heads((delay - 6.5 * us) / 0.5 / us); } else if (delay < 6.5 * us) {
} return false;
} } else {
return heads((delay - 6.5 * us) / 0.5 / us);
/** }
* Выжило предыдушее событие }
*
* @param delay /**
* @return * Выжило предыдушее событие
*/ *
private boolean prevSurvived(double delay) { * @param delay
if (delay > 2.65 * us) { * @return
return true; */
} else if (delay < 2.35 * us) { private boolean prevSurvived(double delay) {
return false; if (delay > 2.65 * us) {
} else { return true;
return heads((delay - 2.35 * us) / 0.3 / us); } else if (delay < 2.35 * us) {
} return false;
} } else {
return heads((delay - 2.35 * us) / 0.3 / us);
private void run() { }
NMEvent next = null; }
do { private void run() {
next = nextEvent(next); NMEvent next = null;
} while (next.getTime() < length);
} do {
next = nextEvent(next);
} } while (next.getTime() < length);
}
}

View File

@ -13,174 +13,174 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package inr.numass.utils; package inr.numass.utils;
import hep.dataforge.context.GlobalContext; import hep.dataforge.context.GlobalContext;
import hep.dataforge.data.DataPoint; import hep.dataforge.data.DataPoint;
import hep.dataforge.data.ListDataSet; import hep.dataforge.data.ListDataSet;
import hep.dataforge.data.MapDataPoint; import hep.dataforge.data.MapDataPoint;
import inr.numass.data.SpectrumDataAdapter; 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;
/** /**
* *
* @author Darksnake * @author Darksnake
*/ */
public class OldDataReader { public class OldDataReader {
public static ListDataSet readConfig(String path) throws FileNotFoundException { public static ListDataSet readConfig(String path) throws FileNotFoundException {
String[] list = {"X","time","ushift"}; String[] list = {"X","time","ushift"};
ListDataSet res = new ListDataSet(list); ListDataSet res = new ListDataSet(list);
File file = GlobalContext.instance().io().getFile(path); File file = GlobalContext.instance().io().getFile(path);
Scanner sc = new Scanner(file); Scanner sc = new Scanner(file);
sc.nextLine(); sc.nextLine();
while(sc.hasNextLine()){ while(sc.hasNextLine()){
String line = sc.nextLine(); String line = sc.nextLine();
Scanner lineScan = new Scanner(line); Scanner lineScan = new Scanner(line);
int time = lineScan.nextInt(); int time = lineScan.nextInt();
double u = lineScan.nextDouble(); double u = lineScan.nextDouble();
double ushift = 0; double ushift = 0;
if(lineScan.hasNextDouble()){ if(lineScan.hasNextDouble()){
ushift = lineScan.nextDouble(); ushift = lineScan.nextDouble();
} }
DataPoint point = new MapDataPoint(list, u,time,ushift); DataPoint point = new MapDataPoint(list, u,time,ushift);
res.add(point); res.add(point);
} }
return res; return res;
} }
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;
int time; int time;
setDefault(Locale.ENGLISH); setDefault(Locale.ENGLISH);
Scanner sc; Scanner sc;
try { try {
sc = new Scanner(file); sc = new Scanner(file);
} catch (FileNotFoundException ex) { } catch (FileNotFoundException ex) {
throw new RuntimeException(ex.getMessage()); throw new RuntimeException(ex.getMessage());
} }
double dummy; double dummy;
// sc.skip("\\D*"); // sc.skip("\\D*");
while (!sc.hasNextDouble()) { while (!sc.hasNextDouble()) {
sc.nextLine(); sc.nextLine();
} }
while (sc.hasNextDouble() | sc.hasNextInt()) { while (sc.hasNextDouble() | sc.hasNextInt()) {
/*Надо сделать, чтобы считывало весь файл*/ /*Надо сделать, чтобы считывало весь файл*/
x = sc.nextDouble(); x = sc.nextDouble();
dummy = sc.nextInt(); dummy = sc.nextInt();
time = sc.nextInt(); time = sc.nextInt();
dummy = sc.nextInt(); dummy = sc.nextInt();
dummy = sc.nextInt(); dummy = sc.nextInt();
dummy = sc.nextInt(); dummy = sc.nextInt();
dummy = sc.nextInt(); dummy = sc.nextInt();
dummy = sc.nextInt(); dummy = sc.nextInt();
dummy = sc.nextInt(); dummy = sc.nextInt();
count = sc.nextInt(); count = sc.nextInt();
// count = (int) (count / (1 - 2.8E-6 / time * count)); // count = (int) (count / (1 - 2.8E-6 / time * count));
dummy = sc.nextInt(); dummy = sc.nextInt();
dummy = sc.nextDouble(); dummy = sc.nextDouble();
dummy = sc.nextDouble(); dummy = sc.nextDouble();
dummy = sc.nextDouble(); dummy = sc.nextDouble();
DataPoint point = factory.buildSpectrumDataPoint(x, count, time); DataPoint point = factory.buildSpectrumDataPoint(x, count, time);
if (x >= Elow) { if (x >= Elow) {
res.add(point); res.add(point);
} }
} }
return res; return res;
} }
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;
int time; int time;
setDefault(Locale.ENGLISH); setDefault(Locale.ENGLISH);
Scanner sc; Scanner sc;
try { try {
sc = new Scanner(file); sc = new Scanner(file);
} catch (FileNotFoundException ex) { } catch (FileNotFoundException ex) {
throw new RuntimeException(ex.getMessage()); throw new RuntimeException(ex.getMessage());
} }
double dummy; double dummy;
sc.nextLine(); sc.nextLine();
while (sc.hasNext()) { while (sc.hasNext()) {
x = sc.nextDouble(); x = sc.nextDouble();
time = sc.nextInt(); time = sc.nextInt();
dummy = sc.nextInt(); dummy = sc.nextInt();
count = sc.nextLong(); count = sc.nextLong();
dummy = sc.nextDouble(); dummy = sc.nextDouble();
dummy = sc.nextDouble(); dummy = sc.nextDouble();
DataPoint point = factory.buildSpectrumDataPoint(x, count, time); DataPoint point = factory.buildSpectrumDataPoint(x, count, time);
if (x > Elow) { if (x > Elow) {
res.add(point); res.add(point);
} }
} }
return res; return res;
} }
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;
double time; double time;
double cr; double cr;
double crErr; double crErr;
setDefault(Locale.ENGLISH); setDefault(Locale.ENGLISH);
Scanner sc; Scanner sc;
try { try {
sc = new Scanner(file); sc = new Scanner(file);
} catch (FileNotFoundException ex) { } catch (FileNotFoundException ex) {
throw new RuntimeException(ex.getMessage()); throw new RuntimeException(ex.getMessage());
} }
while (sc.hasNext()) { while (sc.hasNext()) {
String line = sc.nextLine(); String line = sc.nextLine();
if (!line.startsWith("*")) { if (!line.startsWith("*")) {
Scanner lsc = new Scanner(line); Scanner lsc = new Scanner(line);
if (lsc.hasNextDouble() || lsc.hasNextInt()) { if (lsc.hasNextDouble() || lsc.hasNextInt()) {
x = lsc.nextDouble(); x = lsc.nextDouble();
lsc.next(); lsc.next();
time = lsc.nextDouble(); time = lsc.nextDouble();
lsc.next(); lsc.next();
lsc.next(); lsc.next();
count = lsc.nextDouble(); count = lsc.nextDouble();
cr = lsc.nextDouble(); cr = lsc.nextDouble();
crErr = lsc.nextDouble(); crErr = lsc.nextDouble();
DataPoint point = factory.buildSpectrumDataPoint(x, (long)(cr*time), crErr*time, time); DataPoint point = factory.buildSpectrumDataPoint(x, (long)(cr*time), crErr*time, time);
// SpectrumDataPoint point = new SpectrumDataPoint(x, (long) count, time); // SpectrumDataPoint point = new SpectrumDataPoint(x, (long) count, time);
res.add(point); res.add(point);
} }
} }
} }
return res; return res;
} }
} }

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);
}); consoleButton.setSelected(false);
slider.setAimContentVisible(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(() -> { }
try {
NumassStorage root = NumassStorage.buildLocalNumassRoot(rootDir, true); }
setRootStorage(root);
} catch (StorageException ex) { private class DirectoryLoadTask extends Task<Void> {
setProgress(0);
setProgressText("Failed to load local storage"); private final String uri;
Logger.getLogger(MainViewerController.class.getName()).log(Level.SEVERE, null, ex);
} public DirectoryLoadTask(String uri) {
}, "loader thread").start(); this.uri = uri;
}
@Override
protected Void call() throws Exception {
updateTitle("Load storage ("+uri+")");
updateProgress(-1, 1);
updateMessage("Building numass storage tree...");
try {
NumassStorage root = NumassStorage.buildNumassRoot(uri, true, false);
setRootStorage(root);
Platform.runLater(() -> storagePathLabel.setText("Storage: " + uri));
} catch (StorageException ex) {
updateProgress(0, 1);
updateMessage("Failed to load storage " + uri);
Logger.getLogger(MainViewerController.class.getName()).log(Level.SEVERE, null, ex);
}
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());
});
task.messageProperty().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
statusBar.setText(task.getTitle() + ": " +newValue);
});
task.progressProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
statusBar.setProgress(newValue.doubleValue());
});
@Override task.setOnSucceeded((e) -> {
public void setProgressText(String text) { statusBar.setText(task.getTitle() + ": Complete");
Platform.runLater(() -> statusBar.setText(text)); statusBar.setProgress(0);
//statusBar.setText(text); });
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,28 +213,46 @@ 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...");
private final NumassStorage root;
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().add(component);
AnchorPane.setTopAnchor(component, 0.0);
AnchorPane.setRightAnchor(component, 0.0);
AnchorPane.setLeftAnchor(component, 0.0);
AnchorPane.setBottomAnchor(component, 0.0);
numassLoaderViewContainer.requestLayout();
});
postTask(treeBuilderTask);
Viewer.runTask(treeBuilderTask);
try { try {
new NumassLoaderTreeBuilder(MainViewerController.this).fillTree(numassLoaderDataTree, rootStorage, (NumassData loader) -> { treeBuilderTask.get();
NumassLoaderViewComponent component = NumassLoaderViewComponent.build(loader); this.updateProgress(0, 1);
numassLoaderViewContainer.getChildren().clear(); this.updateMessage("Numass storage tree loaded.");
numassLoaderViewContainer.getChildren().add(component); this.succeeded();
AnchorPane.setTopAnchor(component, 0.0); } catch (InterruptedException | ExecutionException ex) {
AnchorPane.setRightAnchor(component, 0.0); this.failed();
AnchorPane.setLeftAnchor(component, 0.0);
AnchorPane.setBottomAnchor(component, 0.0);
numassLoaderViewContainer.requestLayout();
});
setProgress(0);
setProgressText("Loaded");
} catch (StorageException ex) {
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,86 +119,105 @@ 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){
Map<String, XYSeries> series = new HashMap<>(); callback.postTask(fillTask);
}
Viewer.runTask(fillTask);
}
}
for (DataPoint point : mspData) { private class MspDataFillTask extends Task<Void> {
for (String name : point.names()) {
if (!name.equals("timestamp")) { private final Storage storage;
if (!series.containsKey(name)) {
series.put(name, new XYSeries(name)); public MspDataFillTask(Storage storage) {
} this.storage = storage;
long time = point.getValue("timestamp").timeValue().toEpochMilli(); }
double value = point.getDouble(name);
if (value > 0) { @Override
series.get(name).add(time, value); 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<>();
for (DataPoint point : mspData) {
for (String name : point.names()) {
if (!name.equals("timestamp")) {
if (!series.containsKey(name)) {
series.put(name, new XYSeries(name));
}
long time = point.getValue("timestamp").timeValue().toEpochMilli();
double value = point.getDouble(name);
if (value > 0) {
series.get(name).add(time, value);
} }
} }
} }
XYSeriesCollection mspSeriesCollection = new XYSeriesCollection();
List<String> names = new ArrayList<>(series.keySet());
names.sort((String o1, String o2) -> {
try {
return Integer.valueOf(o1).compareTo(Integer.valueOf(o2));
} catch (Exception ex) {
return 0;
}
});
for (String name : names) {
mspSeriesCollection.addSeries(series.get(name));
}
updateMspPane(mspSeriesCollection);
} catch (StorageException ex) {
throw new RuntimeException(ex);
} }
} XYSeriesCollection mspSeriesCollection = new XYSeriesCollection();
} List<String> names = new ArrayList<>(series.keySet());
names.sort((String o1, String o2) -> {
private List<DataPoint> getMspData(Storage storage) throws StorageException { try {
List<DataPoint> mspData = new ArrayList<>(); return Integer.valueOf(o1).compareTo(Integer.valueOf(o2));
DataPoint last = null;
for (String loaderName : storage.loaders().keySet()) {
if (loaderName.startsWith("msp")) {
try (PointLoader mspLoader = (PointLoader) storage.getLoader(loaderName)) {
mspLoader.open();
updateProgress("Loading mass spectrometer data from " + mspLoader.getName());
updateProgress(-1);
for (DataPoint dp : mspLoader.asDataSet()) {
mspData.add(dp);
last = dp;
}
if (last != null) {
mspData.add(terminatorPoint(last));
}
} catch (Exception ex) { } catch (Exception ex) {
LoggerFactory.getLogger(getClass()).error("Can't read msp loader data", ex); return 0;
}
});
for (String name : names) {
mspSeriesCollection.addSeries(series.get(name));
}
updateMspPane(mspSeriesCollection);
return null;
}
}
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<>();
DataPoint last = null;
for (String loaderName : storage.loaders().keySet()) {
if (loaderName.startsWith("msp")) {
try (PointLoader mspLoader = (PointLoader) storage.getLoader(loaderName)) {
mspLoader.open();
updateMessage("Loading mass spectrometer data from " + mspLoader.getName());
updateProgress(-1, 1);
for (DataPoint dp : mspLoader.asDataSet()) {
mspData.add(dp);
last = dp;
}
if (last != null) {
mspData.add(terminatorPoint(last));
}
} catch (Exception ex) {
LoggerFactory.getLogger(getClass()).error("Can't read msp loader data", ex);
}
} }
} }
}
// 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) { public void setCallback(FXTaskManager callback) {
if (callback != null) {
callback.setProgressText(progress);
}
}
private void updateProgress(double progress) {
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,73 +284,66 @@ 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) {
if (detectorData == null) { Platform.runLater(() -> {
throw new IllegalArgumentException("Detector data not defined"); if (detectorData == null) {
} throw new IllegalArgumentException("Detector data not defined");
}
detectorPointListView.getItems().clear();//removing all checkboxes detectorPointListView.getItems().clear();//removing all checkboxes
detectorPlotPane.getChildren().clear();//removing plot detectorPlotPane.getChildren().clear();//removing plot
Meta frameMeta = new MetaBuilder("frame") Meta frameMeta = new MetaBuilder("frame")
.setValue("frameTitle", "Detector response plot") .setValue("frameTitle", "Detector response plot")
.setNode(new MetaBuilder("xAxis") .setNode(new MetaBuilder("xAxis")
.setValue("axisTitle", "ADC") .setValue("axisTitle", "ADC")
.setValue("axisUnits", "channels") .setValue("axisUnits", "channels")
.build()) .build())
.setNode(new MetaBuilder("yAxis") .setNode(new MetaBuilder("yAxis")
.setValue("axisTitle", "count rate") .setValue("axisTitle", "count rate")
.setValue("axisUnits", "Hz") .setValue("axisUnits", "Hz")
.build()) .build())
.build(); .build();
detectorPlotFrame = new JFreeChartFrame("detectorSignal", frameMeta, detectorPlotPane); detectorPlotFrame = new JFreeChartFrame("detectorSignal", frameMeta, detectorPlotPane);
for (XYPlottable pl : detectorData) { for (XYPlottable pl : detectorData) {
detectorPlotFrame.add(pl); detectorPlotFrame.add(pl);
detectorPointListView.getItems().add(pl.getName()); detectorPointListView.getItems().add(pl.getName());
} }
for (String plotName : detectorPointListView.getItems()) { for (String plotName : detectorPointListView.getItems()) {
BooleanProperty checked = detectorPointListView.getItemBooleanProperty(plotName); BooleanProperty checked = detectorPointListView.getItemBooleanProperty(plotName);
checked.set(true); checked.set(true);
checked.addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> { checked.addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
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

@ -13,54 +13,55 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package inr.numass.viewer; package inr.numass.viewer;
import hep.dataforge.storage.commons.StoragePlugin; import hep.dataforge.storage.commons.StoragePlugin;
import inr.numass.storage.NumassDataLoader; import inr.numass.storage.NumassDataLoader;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import javafx.application.Application; import javafx.application.Application;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.stage.Stage; import javafx.stage.Stage;
/** /**
* *
* @author darksnake * @author darksnake
*/ */
public class TestDirectoryViewer extends Application { public class TestDirectoryViewer extends Application {
@Override @Override
public void start(Stage primaryStage) throws IOException { public void start(Stage primaryStage) throws IOException {
new StoragePlugin().startGlobal(); new StoragePlugin().startGlobal();
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();
// FXMLLoader fxml = new FXMLLoader(getClass().getResource("/fxml/DirectoryViewer.fxml")); comp.loadData(reader);
// // FXMLLoader fxml = new FXMLLoader(getClass().getResource("/fxml/DirectoryViewer.fxml"));
// Parent parent = fxml.load(); //
// // Parent parent = fxml.load();
// NumassLoaderViewController controller = fxml.getController(); //
// // NumassLoaderViewController controller = fxml.getController();
// controller.setModel(reader); //
// controller.setModel(reader);
Scene scene = new Scene(comp, 800, 600);
Scene scene = new Scene(comp, 800, 600);
primaryStage.setTitle("Detector Visualisation test");
primaryStage.setScene(scene); primaryStage.setTitle("Detector Visualisation test");
primaryStage.setMinHeight(600); primaryStage.setScene(scene);
primaryStage.setMinWidth(800); primaryStage.setMinHeight(600);
// primaryStage.setResizable(false); primaryStage.setMinWidth(800);
// primaryStage.setResizable(false);
primaryStage.show();
} primaryStage.show();
}
/**
* @param args the command line arguments /**
*/ * @param args the command line arguments
public static void main(String[] args) { */
launch(args); public static void main(String[] args) {
} launch(args);
}
}
}

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,8 +52,12 @@ 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>
<TextField fx:id="lowChannelField" prefWidth="60.0" /> <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="336.0" showTickLabels="true" showTickMarks="true" /> <children>
<TextField fx:id="upChannelField" prefWidth="60.0" /> <Label text="Lo channel" />
<TextField fx:id="lowChannelField" prefWidth="60.0" />
</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" />
</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>