![JAR search and dependency download from the Maven repository](/logo.png)
org.jcamp.spectrum.Spectrum1D Maven / Gradle / Ivy
package org.jcamp.spectrum;
import java.util.Arrays;
import org.jcamp.math.AxisMap;
import org.jcamp.math.LinearAxisMap;
import org.jcamp.math.Range1D;
import org.jcamp.math.Range2D;
/**
* 1D spectra.
*
* @author Thomas Weber
*/
public abstract class Spectrum1D
extends Spectrum implements Cloneable {
/** for serialization. */
private static final long serialVersionUID = 6979128235728631212L;
IOrderedDataArray1D xData;
IDataArray1D yData;
/**
* flag indicating a full spectrum
*/
protected boolean fullSpectrum;
/**
* axis mapping for x Axis
*/
protected AxisMap xAxisMap = null;
/**
* axis mapping for y Axis
*/
protected AxisMap yAxisMap = null;
/**
* peak table (array of peaks)
*/
protected Peak1D[] peakTable = null;
/**
* pattern table (array of peak patterns (singulets, doublets, multiplets))
*/
protected Pattern[] patternTable = null;
/**
* array of assignments (peak (range) to atom number)
*/
protected Assignment[] assignments = null;
/**
* Spectrum1D constructor comment.
*/
public Spectrum1D() {
super();
}
/**
* standard ctor.
*
* @param x com.creon.chem.spectrum.IOrderedDataArray1D
* @param y com.creon.chem.spectrum.IDataArray1D
*/
public Spectrum1D(IOrderedDataArray1D x, IDataArray1D y) {
this(x, y, !(x instanceof EquidistantData));
}
/**
* standard ctor.
*
* @param x com.creon.chem.spectrum.IOrderedDataArray1D
* @param y com.creon.chem.spectrum.IDataArray1D
* @param fullSpectrum boolean indicates a full spectrum vs. peak spectrum
*/
public Spectrum1D(IOrderedDataArray1D x, IDataArray1D y, boolean fullSpectrum) {
this.xData = x;
this.yData = y;
this.fullSpectrum = fullSpectrum;
this.xAxisMap = new LinearAxisMap(x);
this.yAxisMap = new LinearAxisMap(y);
}
/**
* adjusts full view to a pretty range.
*/
protected void adjustFullViewRange() {
double w;
if (isFullSpectrum()) {
Range1D.Double xrange = xData.getRange1D();
w = xrange.getXWidth();
xrange.set(xrange.getXMin() - .05 * w, xrange.getXMax() + .05 * w);
setXFullViewRange(xrange);
Range1D.Double yrange = yData.getRange1D();
w = yrange.getXWidth();
yrange.set(yrange.getXMin() - .05 * w, yrange.getXMax() + .05 * w);
setYFullViewRange(yrange);
} else {
/* include 0.0 in y-range and add 5% on to all borders */
int n = xData.getLength();
if (n > 1) {
Range1D.Double xrange = xData.getRange1D();
w = xrange.getXWidth();
xrange.set(xrange.getXMin() - .05 * w, xrange.getXMax() + .05 * w);
setXFullViewRange(xrange);
} else if (n == 1) {
double x = xData.pointAt(0);
setXFullViewRange(new Range1D.Double(x - 50, x + 50));
} else {
setXFullViewRange(new Range1D.Double(0., 300.));
}
if (n > 1) {
Range1D.Double yrange = yData.getRange1D();
yrange.set(Math.min(yrange.getXMin(), 0.0), Math.max(yrange.getXMax(), 0.0));
w = yrange.getXWidth();
if (yrange.getXMin() == 0.0) {
yrange.set(yrange.getXMin(), yrange.getXMax() + .05 * w);
} else {
yrange.set(yrange.getXMin() - .05 * w, yrange.getXMax());
}
setYFullViewRange(yrange);
} else {
setYFullViewRange(new Range1D.Double(0., 100.));
}
}
}
/**
* cloning.
*
* @return java.lang.Object
*/
@Override
public Object clone() {
Spectrum1D spectrum = null;
spectrum = (Spectrum1D) super.clone();
spectrum.setData((IOrderedDataArray1D) xData.clone(), (IDataArray1D) yData.clone());
spectrum.copyPeakTable(this.peakTable);
spectrum.copyPatternTable(this.patternTable);
spectrum.copyAssignments(this.assignments);
return spectrum;
}
/**
* deep copy of assignment table.
* @param assignments com.labcontrol.spectrum.Assignment[]
*/
protected void copyAssignments(Assignment[] assignments) {
if (assignments == null) {
this.assignments = null;
return;
}
this.assignments = new Assignment[assignments.length];
for (int i = 0; i < this.assignments.length; i++) {
this.assignments[i] = (Assignment) assignments[i].clone();
this.assignments[i].setSpectrum(this);
}
}
/**
* deep copy of pattern table.
* @param patternTable Pattern[]
*/
protected void copyPatternTable(Pattern[] patternTable) {
if (patternTable == null) {
this.patternTable = null;
return;
}
this.patternTable = new Pattern[patternTable.length];
for (int i = 0; i < patternTable.length; i++) {
this.patternTable[i] = (Pattern) patternTable[i].clone();
this.patternTable[i].setSpectrum(this);
}
}
/**
* deep copy of peak table.
* @param peakTable Peak1D[]
*/
protected void copyPeakTable(Peak1D[] peakTable) {
if (peakTable == null) {
this.peakTable = null;
return;
}
this.peakTable = new Peak1D[peakTable.length];
for (int i = 0; i < peakTable.length; i++) {
this.peakTable[i] = (Peak1D) peakTable[i].clone();
this.peakTable[i].setSpectrum(this);
}
}
/**
* find index of label nearest to position.
* @return ISpectrumLabel
* @param ISpectrumLabel[]
* @param pos double
*/
private static int findLabelIndexNearestTo(ISpectrumLabel[] array, double pos) {
class SearchKey implements ISpectrumLabel {
double[] position = new double[1];
SearchKey(double pos) {
position[0] = pos;
}
public double[] getPosition() {
return position;
}
public String getLabel() {
return null;
}
public int compareTo(Object o) {
double p0 = position[0];
double p1 = ((ISpectrumLabel) o).getPosition()[0];
if (p0 < p1)
return -1;
if (p1 > p0)
return 1;
return 0;
}
public void translate(double[] a) {
}
}
SearchKey key = new SearchKey(pos);
int index = Arrays.binarySearch(array, key);
if (index < 0)
index = -index - 1;
if (index >= array.length)
return array.length - 1;
else {
if (index <= 0) {
return 0;
} else {
if (pos - array[index - 1].getPosition()[0] < array[index].getPosition()[0] - pos)
return index - 1;
else
return index;
}
}
}
/**
* find spectrum label (peak, pattern, assignment) nearest to
* position pos
.
* @return ISpectrumLabel
* @param array ISpectrumLabel[]
* @param pos double
*/
public ISpectrumLabel findNearestLabel(ISpectrumLabel[] array, double pos) {
int index = findLabelIndexNearestTo(array, pos);
return array[index];
}
/**
* return assignment nearest to position pos
.
* @return Assignment
* @param pos double
*/
public Assignment getAssignmentNearestTo(double pos) {
if (assignments == null)
return null;
return (Assignment) findNearestLabel(assignments, pos);
}
/**
* return assignment table.
* @return Assignment[]
*/
public Assignment[] getAssignments() {
return assignments;
}
/**
* gets data range.
* @return Range2D.Double
*/
public Range2D.Double getDataRange() {
return new Range2D.Double(xAxisMap.getDataRange(), yAxisMap.getDataRange());
}
/**
* return range of mapped xy-data in full view
* @return Range2D.Double
*/
public Range2D.Double getFullViewRange() {
return new Range2D.Double(getXFullViewRange(), getYFullViewRange());
}
/**
* returns pattern nearest to postion pos
.
* @return Assignment
* @param pos double
*/
public Pattern getPatternNearestTo(double pos) {
if (patternTable == null)
return null;
return (Pattern) findNearestLabel(patternTable, pos);
}
/**
*@return com.labcontrol.spectrum.Pattern[]
*/
public Pattern[] getPatternTable() {
return patternTable;
}
/**
* return peak nearest to position pos
.
* @return Assignment
* @param pos double
*/
public Peak1D getPeakNearestTo(double pos) {
if (peakTable == null)
return null;
return (Peak1D) findNearestLabel(peakTable, pos);
}
/**
* return peak table.
* @return Peak1D[]
*/
public Peak1D[] getPeakTable() {
return peakTable;
}
/**
* gets label on x-axis.
*
* @return java.lang.String
*/
@Override
public String getXAxisLabel() {
if (xData != null)
return xData.getLabel();
else
return "";
}
/**
* @return AxisMap
* @see com.creon.chem.spectrum.Spectrum
*/
@Override
public AxisMap getXAxisMap() {
return xAxisMap;
}
/**
* Insert the method's description here.
*
* @return com.creon.chem.spectrum.IOrderedDataArray1D
*/
public IOrderedDataArray1D getXData() {
return xData;
}
/**
* gets x range in full view
* @see com.creon.chem.spectrum.Spectrum1D
*/
public Range1D.Double getXFullViewRange() {
return new Range1D.Double(xAxisMap.getFullViewRange());
}
/**
* gets label on y-axis.
*
* @return java.lang.String
*/
@Override
public String getYAxisLabel() {
if (yData != null)
return yData.getLabel();
else
return "";
}
/**
* @return AxisMap
* @see com.creon.chem.spectrum.Spectrum
*/
@Override
public org.jcamp.math.AxisMap getYAxisMap() {
return yAxisMap;
}
/**
* Insert the method's description here.
*
* @return com.creon.chem.spectrum.IDataArray1D
*/
public IDataArray1D getYData() {
return yData;
}
/**
* return an integer array of the y data (intensities) e.g. for writing to JCAMP
*
* @param int[] integer array
* @return double y factor
*/
public double getYDataAs16BitIntArray(int[] y) {
int n = yData.getLength();
Range1D.Double yRange = yData.getRange1D();
double yWidth = Math.max(yRange.getXMax(), -yRange.getXMin());
double shortIntWidth = (double) (2 << 14); // JCAMP requires 16bit signed int precision?
double yf = shortIntWidth / yWidth;
for (int i = 0; i < n; i++) {
y[i] = (int) (yData.pointAt(i) * yf + .5);
}
return yf;
}
/**
* return an integer array of the y data (intensities) e.g. for writing to JCAMP (using non-std. 32 bit precision)
*
* @param int[] integer array
* @return double y factor
*/
public double getYDataAs32BitIntArray(int[] y) {
int n = yData.getLength();
Range1D.Double yRange = yData.getRange1D();
double yWidth = Math.max(yRange.getXMax(), -yRange.getXMin());
double shortIntWidth = (double) (2 << 30);
double yf = shortIntWidth / yWidth;
for (int i = 0; i < n; i++) {
y[i] = (int) (yData.pointAt(i) * yf + .5);
}
return yf;
}
/**
* @see com.creon.chem.spectrum.Spectrum1D
*/
public Range1D.Double getYFullViewRange() {
return new Range1D.Double(yAxisMap.getFullViewRange());
}
/**
* flag indicating assignments.
* @return boolean
*/
public boolean hasAssignments() {
return assignments != null;
}
/**
* flag indictating a pattern table.
* @return boolean
*/
public boolean hasPatternTable() {
return patternTable != null;
}
/**
* flag indicating a peak table.
* @return boolean
*/
public boolean hasPeakTable() {
return peakTable != null;
}
/**
* flag indicating a full spectrum.
* @return boolean
*/
@Override
public boolean isFullSpectrum() {
return fullSpectrum;
}
/**
* remove assignment nearest to position pos
.
* @param pos double
*/
public void removeAssignmentAt(double pos) {
if (this.assignments != null && this.assignments.length > 0) {
int index = findLabelIndexNearestTo(this.assignments, pos);
Assignment[] newTable = new Assignment[this.assignments.length - 1];
System.arraycopy(this.assignments, 0, newTable, 0, index);
System.arraycopy(this.assignments, index + 1, newTable, index, this.assignments.length - index - 1);
setAssignments(newTable);
}
}
/**
* remove pattern nearest to position pos
.
* @param pos double
*/
public void removePatternAt(double pos) {
if (this.patternTable != null && this.patternTable.length > 0) {
int index = findLabelIndexNearestTo(this.patternTable, pos);
Pattern[] newTable = new Pattern[this.patternTable.length - 1];
System.arraycopy(this.patternTable, 0, newTable, 0, index);
System.arraycopy(this.patternTable, index + 1, newTable, index, this.patternTable.length - index - 1);
setPatternTable(newTable);
}
}
/**
* remove peak nearest to position pos
.
* @param pos double
*/
public void removePeakAt(double pos) {
if (this.peakTable != null && this.peakTable.length > 0) {
int index = findLabelIndexNearestTo(this.peakTable, pos);
Peak1D[] newTable = new Peak1D[this.peakTable.length - 1];
System.arraycopy(this.peakTable, 0, newTable, 0, index);
System.arraycopy(this.peakTable, index + 1, newTable, index, this.peakTable.length - index - 1);
setPeakTable(newTable);
}
}
/**
* sets assignment array.
* @param newAssignments Assignment[]
*/
public void setAssignments(Assignment[] newAssignments) {
if (assignments != newAssignments) {
assignments = newAssignments;
if (assignments != null) {
for (int i = 0; i < assignments.length; i++)
assignments[i].setSpectrum(this);
Arrays.sort(newAssignments);
}
}
}
/**
* sets data arrays.
*
* @param x com.creon.math.IOrderedDataArray1D
* @param y com.creon.math.IDataArray1D
*/
public void setData(IOrderedDataArray1D x, IDataArray1D y) {
this.xData = x;
this.yData = y;
}
/**
* set full spectrum flag
* @param newFullSpectrum boolean
*/
protected void setFullSpectrum(boolean newFullSpectrum) {
fullSpectrum = newFullSpectrum;
}
/**
* set full view data range in mapping
* should be overloaded
* @param range Range2D.Double
*/
public void setFullViewRange(Range2D.Double range) {
setXFullViewRange(range.getXRange());
setYFullViewRange(range.getYRange());
}
/**
* sets a new pattern table.
* @param newPatternTable Pattern[]
*/
public void setPatternTable(Pattern[] newPatternTable) {
if (newPatternTable != patternTable) {
patternTable = newPatternTable;
if (patternTable != null)
for (int i = 0; i < patternTable.length; i++)
patternTable[i].setSpectrum(this);
}
}
/**
* sets a new peak table.
* @param newPeakTable Peak1D[]
*/
public void setPeakTable(Peak1D[] newPeakTable) {
if (newPeakTable != peakTable) {
peakTable = newPeakTable;
if (peakTable != null)
for (int i = 0; i < peakTable.length; i++)
peakTable[i].setSpectrum(this);
}
}
/**
* set xy-mapping with a data range of dataRange
.
* mappings are linear mapping in dataRange
bounds.
* mapping:
* x := indepData
* @param dataRange Range1D.Double
*/
public void setXFullViewRange(Range1D.Double dataRange) {
this.xAxisMap = new LinearAxisMap(xData, dataRange);
}
/**
* sets full view range on y axis.
*/
public void setYFullViewRange(Range1D.Double dataRange) {
this.yAxisMap = new LinearAxisMap(yData, dataRange);
}
/**
* insertion sort for peak tables (assuming most peak tables are already sorted)
* sort by first dimension
* @param array double[][]
*/
static void sort(double[][] array) {
int i, j, n;
double x, y;
n = array[0].length;
for (i = 1; i < n; i++) {
x = array[0][i];
y = array[1][i];
j = i;
while (j > 0 && array[0][j - 1] > x) {
array[0][j] = array[0][j - 1];
array[1][j] = array[1][j - 1];
j--;
}
array[0][j] = x;
array[1][j] = y;
}
}
/**
* translate x values by amount
together with all associated data e.g. for calibration
* @param amount double
*/
public void translate(double amount) {
double[] tvec = new double[2];
tvec[0] = amount;
tvec[1] = 0.0;
xData.translate(amount);
if (peakTable != null) {
for (int i = 0; i < peakTable.length; i++) {
peakTable[i].translate(tvec);
}
}
if (patternTable != null) {
for (int i = 0; i < patternTable.length; i++) {
patternTable[i].translate(tvec);
}
}
if (assignments != null) {
for (int i = 0; i < assignments.length; i++) {
assignments[i].translate(tvec);
}
}
adjustFullViewRange();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy