TfsResultDataSet.java
// @formatter:off
/*******************************************************************************
*
* This file is part of JMad.
*
* Copyright (c) 2008-2011, CERN. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
// @formatter:on
package cern.accsoft.steering.jmad.gui.data;
import java.util.ArrayList;
import java.util.List;
import cern.accsoft.steering.jmad.domain.result.tfs.TfsResult;
import cern.accsoft.steering.jmad.domain.var.MadxVariable;
import cern.accsoft.steering.jmad.domain.var.TwissVariable;
import cern.accsoft.steering.jmad.domain.var.enums.MadxTwissVariable;
import cern.accsoft.steering.jmad.gui.mark.MarkerXProvider;
import cern.jdve.data.AbstractDataSet;
import cern.jdve.event.DataSetEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TfsResultDataSet extends AbstractDataSet implements
MarkerXProvider {
private final static Logger logger = LoggerFactory.getLogger(TfsResultDataSet.class);
public final static MadxTwissVariable LABEL_VAR = MadxTwissVariable.NAME;
/** the limit for zero-definition */
private final static double LIMIT_ZERO = 1e-20;
/** maximum value for aperture */
private double maxAperture = 0.0;
/** the actual tfsResult to display */
private TfsResult tfsResult = null;
/** the reference tfsResult (if available) */
private TfsResult referenceTfsResult = null;
/** an additional factor to apply to the values */
private double factor = 1;
/**
* how to display the data set
*/
private TfsResultDataSetType type = TfsResultDataSetType.ABSOLUTE;
/** the cached x-values */
private List<Double> xValues = new ArrayList<Double>();
/** the cached y-values */
private List<Double> yValues = new ArrayList<Double>();
private MadxVariable xVar = null;
private TwissVariable yVar = null;
public enum TfsResultDataSetType {
ABSOLUTE, DIFFERENCE, RELATIVE, BEATING;
}
public TfsResultDataSet(String name, MadxVariable xVar, TwissVariable yVar,
TfsResultDataSetType type, TfsResult tfsResult,
TfsResult referenceTfsResult) {
super(name);
this.xVar = xVar;
this.yVar = yVar;
this.type = type;
this.tfsResult = tfsResult;
this.referenceTfsResult = referenceTfsResult;
calculate();
}
@Override
public void add(int arg0, double arg1, double arg2) {
throw new UnsupportedOperationException("not implemented.");
}
@Override
public int getDataCount() {
if (tfsResult == null) {
return 0;
}
List<String> stringData = tfsResult.getStringData(xVar);
if (stringData != null) {
return stringData.size();
}
return 0;
}
@Override
public double getX(int index) {
return this.xValues.get(index);
}
@Override
public double getY(int index) {
return this.yValues.get(index);
}
@Override
public void remove(int arg0, int arg1) {
throw new UnsupportedOperationException("not implemented.");
}
@Override
public String getDataLabel(int index) {
if (tfsResult == null) {
return null;
}
List<String> stringData = tfsResult.getStringData(LABEL_VAR);
if (stringData != null) {
return stringData.get(index);
} else {
logger.error("No data in TfsResult for variable '" + LABEL_VAR
+ "'.");
}
return null;
}
/**
* (re) calculates all the cached values
*/
private void calculate() {
if (this.tfsResult == null) {
logger.error("No tfs result set.");
return;
}
List<Double> xVals = tfsResult.getDoubleData(this.xVar);
List<Double> yVals = tfsResult.getDoubleData(this.yVar);
if ((xVals == null) || (yVals == null)) {
logger.error("No x- or no y- values found in tfs result.");
return;
}
this.xValues = new ArrayList<Double>(xVals);
this.yValues = new ArrayList<Double>(yVals);
if (isApertureDataSet()) {
calcMaxAperture(yVals);
this.yValues = new ArrayList<Double>(yVals.size());
for (int i = 0; i < yVals.size(); i++) {
Double value = yVals.get(i);
double absValue = Math.abs(value);
if (absValue > getMaxAperture()) {
value = Math.signum(value) * getMaxAperture();
} else if (absValue < LIMIT_ZERO) {
value = getMaxAperture();
}
this.yValues.add(value);
}
} else if (isRelative()) {
boolean refOk = true;
List<Double> yRefValues = null;
if (this.referenceTfsResult == null) {
logger.warn("Should be relative dataset, but no reference set. Data will be absolute.");
refOk = false;
}
if (refOk) {
yRefValues = this.referenceTfsResult.getDoubleData(this.yVar);
if (yRefValues == null) {
logger.warn("No reference values for variable '"
+ this.yVar + "'. Data will be absolute.");
refOk = false;
}
}
if (refOk) {
if (yVals.size() != yRefValues.size()) {
logger.warn("y-values and ref values are of different size. Data will be absolute.");
refOk = false;
}
}
if (refOk) {
this.yValues = new ArrayList<Double>(yVals.size());
for (int i = 0; i < yVals.size(); i++) {
Double value = yVals.get(i);
Double refValue = yRefValues.get(i);
if (refValue != null) {
if (TfsResultDataSetType.DIFFERENCE.equals(this.type)) {
value -= refValue;
} else if (TfsResultDataSetType.RELATIVE
.equals(this.type)) {
value /= refValue;
} else if (TfsResultDataSetType.BEATING
.equals(this.type)) {
value = (value - refValue) / refValue;
}
}
this.yValues.add(value);
}
}
}
for (int i = 0; i < this.yValues.size(); i++) {
this.yValues.set(i, this.yValues.get(i) * getFactor());
}
}
/**
* @return the calculated maximum aperture
*/
private double getMaxAperture() {
return this.maxAperture;
}
/**
* sets the actual dataset
*
* @param tfsResult
* the Result to set
*/
public void setTfsResult(TfsResult tfsResult) {
this.tfsResult = tfsResult;
fireFullChange();
}
/**
* sets a new TfsResult as reference
*
* @param referenceTfsResult
* the TfsResult to set as Reference
*/
public void setReferenceTfsResult(TfsResult referenceTfsResult) {
this.referenceTfsResult = referenceTfsResult;
if (isRelative()) {
fireFullChange();
}
}
/**
* @return true, if this dataset is any kind of relative dataset
*/
private boolean isRelative() {
return (!TfsResultDataSetType.ABSOLUTE.equals(this.type));
}
/**
* enforces the recalc of the ranges and fires a fullChange - Event.
*/
private void fireFullChange() {
calculate();
initRanges();
fireDataSetChanged(new DataSetEvent(this, DataSetEvent.FULL_CHANGE));
}
private void calcMaxAperture(List<Double> values) {
double maxAbsValue = 0;
for (int i = 0; i < values.size(); i++) {
double value = Math.abs(values.get(i));
if (value > maxAbsValue) {
maxAbsValue = value;
}
}
this.maxAperture = maxAbsValue;
}
@Override
public List<Double> getXPositions(String elementName) {
List<Double> xPositions = new ArrayList<Double>();
if (tfsResult == null) {
return xPositions;
}
/* get the actual value */
/*
* TODO: maybe extend to more values
*/
Integer index = tfsResult.getElementIndex(elementName);
if (index != null) {
xPositions.add(xValues.get(index));
}
return xPositions;
}
/**
* @param factor
* the factor to set
*/
public void setFactor(double factor) {
this.factor = factor;
}
/**
* @return the factor
*/
public double getFactor() {
return factor;
}
/**
* @return true, if this represents an aperture-dataset.
*/
public boolean isApertureDataSet() {
return this.yVar.isApertureVariable();
}
}