Java tutorial
/** * Copyright (C) DataMelt project. The jHPLot package by S.Chekanov and Work.ORG * All rights reserved. * * This program is free software; you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Foundation; either * version 3 of the License, or any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, see <http://www.gnu.org/licenses>. * * Additional permission under GNU GPL version 3 section 7: * If you have received this program as a library with written permission from the DataMelt team, * you can link or combine this library with your non-GPL project to convey the resulting work. * In this case, this library should be considered as released under the terms of * GNU Lesser public license (see <https://www.gnu.org/licenses/lgpl.html>), * provided you include this license notice and a URL through which recipients can access the * Corresponding Source. **/ package jhplot; import jminhep.cluster.DataHolder; import jminhep.cluster.DataPoint; import jplot.*; import jhplot.gui.HelpBrowser; import jhplot.io.PReader; import jhplot.math.*; import jhplot.utils.SHisto; import java.text.DecimalFormat; import java.util.StringTokenizer; import java.awt.Color; import java.io.*; import java.net.URL; import java.util.*; import hep.aida.*; import hep.aida.ref.histogram.*; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import cern.colt.list.DoubleArrayList; import cern.jet.stat.Descriptive; /** * A container to hold data points with 1st and 2nd level errors. The first * errors are usually statistical, the second error are systematic. P1D can be * used for drawing, manipulation with data etc. * * <p> * * This is a vast high-performance low-memory footprint data container. * * @author S.Chekanov * */ public class P1D extends DrawOptions implements Serializable { /** * */ private static final long serialVersionUID = 1L; private DoubleArrayList X; // X value private DoubleArrayList Y; // Y value private DoubleArrayList XE1left; // 1st level, X left error private DoubleArrayList XE1right; // 1st level, X right error private DoubleArrayList XE2left; // 2nd level, X left error private DoubleArrayList XE2right; // 2nd level, X right error private DoubleArrayList YE1upper; // 1st level. on Y private DoubleArrayList YE1down; private DoubleArrayList YE2upper; // 2nd level on Y private DoubleArrayList YE2down; private int dimen; // dimension of this holder /** * Construct an empty container **/ public P1D() { this("No title"); } /** * Construct an empty container with a title. It is assumed that on X and Y values will be stored (dimension 2). * * @param title * New title */ public P1D(String title) { X = new DoubleArrayList(); Y = new DoubleArrayList(); this.title = title; lpp.setColor(Color.black); lpp.setPenWidth(2.0f); lpp.setType(LinePars.P1D); lpp.setGraphStyle(0); lpp.setDrawLegend(true); lpp.setColorErrorsY(Color.black); lpp.setColorErrorsX(Color.black); lpp.errorsY(true); lpp.errorsX(true); lpp.setGraphStyle(0); lpp.setSymbol(4); lpp.setDrawSymbol(true); lpp.setDrawLine(false); dimen = 2; } /** * Construct an empty container with a title. It is assumed that on X and Y values will be stored (dimension 2). * * @param title * New title */ public P1D(String title, DoubleArrayList Xval, DoubleArrayList Yval) { this.X = Xval; this.Y = Yval; this.title = title; lpp.setColor(Color.black); lpp.setPenWidth(2.0f); lpp.setType(LinePars.P1D); lpp.setGraphStyle(0); lpp.setDrawLegend(true); lpp.setColorErrorsY(Color.black); lpp.setColorErrorsX(Color.black); lpp.errorsY(true); lpp.errorsX(true); lpp.setGraphStyle(0); lpp.setSymbol(4); lpp.setDrawSymbol(true); lpp.setDrawLine(false); dimen = 2; } /** * Construct an empty container with a title * * @param title * New title * @param dimension * dimension (2,4,6,10) */ public P1D(String title, int dimension) { this(title); setDimension(dimension); } /** * Construct an empty container with a title and color for points * * @param title * New title * @param color * for points */ public P1D(String title, Color color) { this(title); lpp.setColor(color); } /** * Construct an empty container with a title and color and symbol style for * points * * @param title * New title * @param color * for points * * @param style * used to draw symbols (1,2,3,4..) */ public P1D(String title, Color color, int symbolstyle) { this(title); lpp.setColor(color); lpp.setSymbol(symbolstyle); } /** * Construct a container from pairs of P0D (one for X, second for Y) * * @param p1 * P1D representing X * @param p2 * P1D representing Y **/ public P1D(P0D p1, P0D p2) { this(p1.getTitle() + "+" + p2.getTitle()); fill(p1, p2); } /** * Construct a container from pairs of P0D (one for X, second for Y) * * @param title * new title * @param p1 * P1D representing X * @param p2 * P1D representing Y ***/ public P1D(String title, P0D p1, P0D p2) { this(title); fill(p1, p2); } /** * Construct P1D from a Cloud2D * * @param c2d * input cloud2d **/ public P1D(Cloud2D c2d) { this(c2d.title()); fill(c2d); } /** * Construct a container from pairs X and Y * * @param title * new title * @param p1 * array representing X * @param p2 * array representing Y **/ public P1D(String title, double[] p1, double[] p2) { this(title); fill(p1, p2); } /** * Construct a container from pairs X and Y * * @param title * new title * @param p1 * array representing X * @param p2 * array representing Y **/ public P1D(String title, int[] p1, int[] p2) { this(title); fill(p1, p2); } /** * Construct a new copy of the data container. * * @param title * New title * @param p1d * input P1D object */ public P1D(String title, P1D p1d) { LinePars lnew = copyLinePars(p1d.getLineParm()); setDrawOption(lnew); this.title = title; dimen = p1d.dimension(); X = p1d.getXval(); Y = p1d.getYval(); if (dimen == 2) { return; } if (dimen == 3) { YE1upper = p1d.getYE1upper(); return; } if (dimen == 4) { YE1upper = p1d.getYE1upper(); YE1down = p1d.getYE1down(); return; } if (dimen == 6) { YE1upper = p1d.getYE1upper(); XE1left = p1d.getXE1left(); XE1right = p1d.getXE1right(); YE1down = p1d.getYE1down(); return; } if (dimen == 10) { YE1upper = p1d.getYE1upper(); XE1left = p1d.getXE1left(); XE1right = p1d.getXE1right(); YE1down = p1d.getYE1down(); YE2upper = p1d.getYE2upper(); XE2left = p1d.getXE2left(); XE2right = p1d.getXE2right(); YE2down = p1d.getYE2down(); return; } } /** * Set the dimension for the container. Can be: * 2: for X,Y <br> * 3: for X,Y and error on Y <br> * 4: for X,Y and error on Y (up) and Y (down)<br> * 6: for X,Y and error on Y (up) and Y (down) and X(left) and X(right)<br> * 10: same as before but 2nd level errors (usually systematics) * * @param dimension * dimension used. * */ public void setDimension(int dimension) { if (dimension < 0 || dimension > 10) { dimen = 2; } YE1upper = null; YE1down = null; XE1left = null; XE2left = null; XE1right = null; XE2right = null; YE2upper = null; YE2down = null; if (dimension == 2) { return; } if (dimension == 3) { YE1upper = new DoubleArrayList(); return; } if (dimension == 4) { YE1upper = new DoubleArrayList(); YE1down = new DoubleArrayList(); return; } if (dimension == 6) { YE1upper = new DoubleArrayList(); YE1down = new DoubleArrayList(); XE1left = new DoubleArrayList(); XE1right = new DoubleArrayList(); return; } if (dimension == 8) { YE1upper = new DoubleArrayList(); YE1down = new DoubleArrayList(); XE1left = new DoubleArrayList(); XE1right = new DoubleArrayList(); YE2upper = new DoubleArrayList(); YE2down = new DoubleArrayList(); return; } if (dimension == 10) { YE1upper = new DoubleArrayList(); YE1down = new DoubleArrayList(); XE1left = new DoubleArrayList(); XE1right = new DoubleArrayList(); XE2left = new DoubleArrayList(); XE2right = new DoubleArrayList(); YE2upper = new DoubleArrayList(); YE2down = new DoubleArrayList(); return; } } /** * get LinePars class which holds graphical attributes * * @return Graphic attributes */ public LinePars getLinePars() { return lpp; } /** * Sets LinePars class for graphical attributes * * @param pnew * Graphic attributes */ public void setLinePars(LinePars pnew) { lpp = pnew; } /** * Create P1D data holder from multidimensional data holder. You should * specify a slice which you want to export (X,Y) pair of P1D * * @param dh * Input data container * @param title * New title * @param i1 * Index of the first column * @param i2 * Index of the second column */ public P1D(DataHolder dh, String title, int i1, int i2) { this(title); int dim = dh.getDimention(); if (i1 > dim || i2 > dim) { ErrorMessage("index is larger than dimension " + Integer.toString(dim)); return; } setDimension(2); for (int i = 0; i < dh.getSize(); i++) { DataPoint dp = dh.getRow(i); double x = dp.getAttribute(i1); double y = dp.getAttribute(i2); X.add(x); Y.add(y); } } // end /** * Create P1D data holder from multidimensional data holder. You should * specify a slice which you want to export (X,Y) pair of P1D. The title is * default * * @param dh * Input data container * @param i1 * Index of the first column * @param i2 * Index of the second column */ public P1D(DataHolder dh, int i1, int i2) { this(dh, dh.getRelation(), i1, i2); } /** * Construct a P1D from a file. * <p> * The file should contain 2, or 4, or 6, or 10 columns: 1) x,y: data * without any errors 2) x,y, y(upper), y(lower) - data with 1st level * errors on Y 3) x,y, x(left), x(right), y(upper), y(lower) - data with 1st * level errors on X and Y 4) x,y, x(left), x(right), y(upper), y(lower), * x(leftSys), x(rightSys), y(upperSys), y(lowerSys) - data with X and Y and * 1st and 2nd level errors. Comments lines starting with "#" and "*" are * ignored. * * @param title * Title of the container * @param sfile * File name with input. input file name. It can be either a file * on a file system or URL location (must start from http or ftp) */ public P1D(String title, String sfile) { this(title); read(sfile); } /** * Write a File in form of LaTeX table from values in the container P1D * * @param name * Name of the file * @param dx * Format of x values * @param dy * Format of y values */ public void toFileAsLatex(String name, DecimalFormat dx, DecimalFormat dy) { Date dat = new Date(); String today = String.valueOf(dat); try { FileOutputStream f1 = new FileOutputStream(new File(name)); PrintStream tx = new PrintStream(f1); tx.println("% DataMelt: output from P1D " + this.title); tx.println("% DataMelt: created at " + today); // create vectors VHolder vh = new VHolder(this); String[] names = vh.getNames(); Double[][] data = vh.getData(); // only x and y if (names.length == 3) tx.println("\\begin{tabular}{|c|c|} \\hline"); // x, y and errors on y if (names.length == 4) tx.println("\\begin{tabular}{|c|c|c|} \\hline"); // x, y, and error on x and y if (names.length == 5) tx.println("\\begin{tabular}{|c|c|c|c|c|} \\hline"); // x,y, full errors on y and 1st level error on x if (names.length == 7) tx.println("\\begin{tabular}{|c|c|c|c|c|c|c|} \\hline"); // all errors if (names.length == 11) tx.println("\\begin{tabular}{|c|c|c|c|c|c|c|c|c|} \\hline"); // get data for (int i = 0; i < vh.size(); i++) { double[] dd = new double[vh.dimen()]; for (int k = 0; k < vh.dimen(); k++) dd[k] = data[i][k]; if (names.length == 3) { double xx = dd[1]; double yy = dd[2]; String x = dx.format(xx); String y = dy.format(yy); tx.println(x + " & " + y + " \\\\ \\hline"); } if (names.length == 4) { double xx = dd[1]; double yy = dd[2]; double ey = dd[3]; String x = dx.format(xx); String y = dy.format(yy); String e = dy.format(ey); tx.println(x + " & " + y + " & " + e + " \\\\ \\hline"); } if (names.length == 5) { double xx = dd[1]; double yy = dd[2]; double yy1 = dd[3]; double yy2 = dd[4]; String x = dx.format(xx); String y = dy.format(yy); String y1 = dy.format(yy1); String y2 = dy.format(yy2); tx.println("$" + x + "$ & $" + y + "^{" + y1 + "}_{" + y2 + "}$ \\\\ \\hline"); } if (names.length == 7) { double xx = dd[1]; double yy = dd[2]; double xx1 = dd[3]; double xx2 = dd[4]; double yy1 = dd[5]; double yy2 = dd[6]; String x = dx.format(xx); String x1 = dx.format(xx1); String x2 = dx.format(xx2); String y = dy.format(yy); String y1 = dy.format(yy1); String y2 = dy.format(yy2); tx.println("$" + x + "^{" + x1 + "}_{" + x2 + "}$ & " + "$" + y + "^{" + y1 + "}_{" + y2 + "}$ \\\\ \\hline"); } if (names.length == 9) { double xx = (Double) dd[1]; double yy = (Double) dd[2]; double xx1 = (Double) dd[3]; double xx2 = (Double) dd[4]; double yy1 = (Double) dd[5]; double yy2 = (Double) dd[6]; double ys1 = (Double) dd[7]; double ys2 = (Double) dd[8]; String x = dx.format(xx); String x1 = dx.format(xx1); String x2 = dx.format(xx2); String y = dy.format(yy); String y1 = dy.format(yy1); String y2 = dy.format(yy2); String y1s = dy.format(ys1); String y2s = dy.format(ys2); tx.println("$" + x + "^{" + x1 + "}_{" + x2 + "}$ & " + "$" + y + "^{" + y1 + "}_{" + y2 + "}$ (stat.) " + "$^{" + y1s + "}_{" + y2s + "}$ (syst.) \\\\ \\hline"); } if (names.length == 11) { double xx = (Double) dd[1]; double yy = (Double) dd[2]; double xx1 = (Double) dd[3]; double xx2 = (Double) dd[4]; double ex1 = (Double) dd[5]; double ex2 = (Double) dd[6]; double yy1 = (Double) dd[7]; double yy2 = (Double) dd[8]; double ys1 = (Double) dd[9]; double ys2 = (Double) dd[10]; String x = dx.format(xx); String x1 = dx.format(xx1); String x2 = dx.format(xx2); String sx1 = dx.format(ex1); String sx2 = dx.format(ex2); String y = dy.format(yy); String y1 = dy.format(yy1); String y2 = dy.format(yy2); String y1s = dy.format(ys1); String y2s = dy.format(ys2); tx.println("$" + x + "^{" + x1 + "}_{" + x2 + "}$ (stat.) " + "$^{" + sx1 + "}_{" + sx2 + "}$ (syst.) & " + "$" + y + "^{" + y1 + "}_{" + y2 + "}$ (stat.) " + "$^{" + y1s + "}_{" + y2s + "}$ (syst.) \\\\ \\hline"); } } tx.println("\\end{tabular}"); } catch (IOException e) { ErrorMessage("Error in the output file"); e.printStackTrace(); } } /** * Write a P1D to an external file. If errors on data points are not given, * they are set to 0 * * @param name * File name with output */ public void toFile(String name) { DecimalFormat dfb = new DecimalFormat("##.#####E00"); Date dat = new Date(); String today = String.valueOf(dat); try { FileOutputStream f1 = new FileOutputStream(new File(name)); PrintStream tx = new PrintStream(f1); tx.println("# DataMelt: output from P1D " + this.title); tx.println("# DataMelt: created at " + today); tx.println("# x,y,x(left),x(right),y(upper),y(lower),x(leftSys),x(rightSys),y(upperSys),y(lowerSys)"); tx.println("#"); for (int i = 0; i < size(); i++) { String x = dfb.format(X.getQuick(i)); String y = dfb.format(Y.getQuick(i)); if (dimen == 2) { tx.println(x + " " + y); continue; } String y1 = dfb.format(YE1upper.getQuick(i)); String y2 = dfb.format(YE1down.getQuick(i)); if (dimen == 3) { tx.println(x + " " + y + " " + y1); continue; } if (dimen == 4) { tx.println(x + " " + y + " " + y1 + " " + y2); continue; } String x1 = dfb.format(XE1left.getQuick(i)); String x2 = dfb.format(XE1right.getQuick(i)); if (dimen == 6) { tx.println(x + " " + y + " " + x1 + " " + x2 + " " + y1 + " " + y2); continue; } String x3 = dfb.format(getXleftSys(i)); String x4 = dfb.format(getXrightSys(i)); String y3 = dfb.format(getYupperSys(i)); String y4 = dfb.format(getYlowerSys(i)); tx.println(x + " " + y + " " + x1 + " " + x2 + " " + y1 + " " + y2 + " " + x3 + " " + x4 + " " + y3 + " " + y4); } f1.close(); } catch (IOException e) { ErrorMessage("Error in the output file"); e.printStackTrace(); } } /** * Print a P1D container on the screen * */ public void print() { System.out.println(toString()); } /** * Convert to a string * * @return String representing P1D */ public String toString() { String tmp = "# title=" + getTitle() + " dimension=" + Integer.toString(dimension()) + "\n"; if (dimen == 2) { tmp = tmp + "# X Y \n"; for (int i = 0; i < size(); i++) { tmp = tmp + Double.toString(X.getQuick(i)) + " " + Double.toString(Y.getQuick(i)) + "\n"; } return tmp; } if (dimen == 3) { tmp = tmp + "# X Y ErrorY (symmetric)\n"; for (int i = 0; i < size(); i++) { tmp = tmp + Double.toString(X.getQuick(i)) + " " + Double.toString(Y.getQuick(i)) + " " + Double.toString(YE1upper.getQuick(i)) + "\n"; } return tmp; } if (dimen == 4) { tmp = tmp + "# X Y ErrorY- ErrorY+ \n"; for (int i = 0; i < size(); i++) { tmp = tmp + Double.toString(X.getQuick(i)) + " " + Double.toString(Y.getQuick(i)) + " " + Double.toString(YE1down.getQuick(i)) + " " + Double.toString(YE1upper.getQuick(i)) + "\n"; } return tmp; } if (dimen == 6) { tmp = tmp + "# X Y ErrorX- ErrorY+ ErrorY- ErrorY+ \n"; for (int i = 0; i < size(); i++) { tmp = tmp + Double.toString(X.getQuick(i)) + " " + Double.toString(Y.getQuick(i)) + " " + Double.toString(XE1left.getQuick(i)) + " " + Double.toString(XE1right.getQuick(i)) + " " + Double.toString(YE1down.getQuick(i)) + " " + Double.toString(YE1upper.getQuick(i)) + "\n"; } return tmp; } if (dimen == 10) { tmp = tmp + "# X Y ErrorX- ErrorY+ ErrorY+ ErrorY- ErrorSysX- ErrorSysY+ ErrorSysY- ErrorSysY+\n"; for (int i = 0; i < size(); i++) { tmp = tmp + Double.toString(X.getQuick(i)) + " " + Double.toString(Y.getQuick(i)) + " " + Double.toString(XE1left.getQuick(i)) + " " + Double.toString(XE1right.getQuick(i)) + " " + Double.toString(YE1down.getQuick(i)) + " " + Double.toString(YE1upper.getQuick(i)) + " " + Double.toString(XE2left.getQuick(i)) + " " + Double.toString(XE2right.getQuick(i)) + " " + Double.toString(YE2down.getQuick(i)) + " " + Double.toString(YE2upper.getQuick(i)) + "\n"; } return tmp; } return tmp; } /** * Create a P1D container from IDataPointSet. * * * @param pd * Imported IDataPointSet. * * */ public P1D(IDataPointSet pd) { this(pd.title()); setDimension(6); for (int i = 0; i < pd.size(); i++) { IDataPoint p = pd.point(i); double x = p.coordinate(0).value(); double y = p.coordinate(1).value(); double x1 = p.coordinate(0).errorPlus(); double x2 = p.coordinate(0).errorMinus(); double y1 = p.coordinate(1).errorPlus(); double y2 = p.coordinate(1).errorMinus(); addQuick(x, y, x2, x1, y2, y1); } } /** * Create a P1D container from a histogram * * @param title * New title * * @param histo * Imported histogram * * @param binMean * If true, Y values are put to the mean values in each bin. If * false, is just a height in the histogram bin * * @param fillXerrors * If true, errors are set to X values (half of the bin width) If * false, errors on X are set to zero * */ public P1D(String title, H1D histo, boolean binMean, boolean fillXerrors) { this(title); Histogram1D h1 = histo.get(); IAxis axis = h1.axis(); int bins = axis.bins(); clear(); setDimension(6); for (int i = 0; i < bins; i++) { double x = axis.binCenter(i); // bin center double y = h1.binHeight(i); if (binMean) y = h1.binMean(i); // The weighted mean of a bin double y1 = h1.binError(i); double w = 0; if (fillXerrors) w = axis.binWidth(i); add(x, y, 0.5 * w, 0.5 * w, y1, y1); } } /** * Create a P1D container from a histogram. The title is set to the * histogram title. * * @param histo * Imported histogram * * @param binMean * If true, Y values are put to the mean values in each bin. If * false, Y corresponds to height of the histogram bin * * @param fillXerrors * If true, errors are set to X values (half of the bin width) If * false, errors on X are set to zero */ public P1D(H1D histo, boolean binMean, boolean fillXerrors) { this(histo.getTitle(), histo, binMean, fillXerrors); dimen = 4; } /** * Create a P1D container from a histogram. The title is set to the * histogram title. Show errors on X as bin width x 0.5 * * * @param title * New title * * @param histo * Imported histogram * * @param binMean * If true, Y values are put to the mean values in each bin. If * false, Y is just a center of the histogram bin * */ public P1D(String title, H1D histo, boolean binMean) { this(title, histo, binMean, true); dimen = 4; } /** * Create a P1D container from a histogram. The title is set to the * histogram title. Show errors on X as bin width x 0.5 * * @param histo * Imported histogram * * @param binMean * If true, Y values are put to the mean values in each bin. If * false, Y is just a height of the histogram bin * */ public P1D(H1D histo, boolean binMean) { this(histo.getTitle(), histo, binMean, true); } /** * Create a P1D container from a histogram. The title is set to the * histogram title. Show errors on X as bin width x 0.5. The Y points are * set to the high values in each bin. * * @param histo * Imported histogram * * */ public P1D(H1D histo) { this(histo.getTitle(), histo, false, true); } /** * Create a P1D container from a histogram. The title is set to the * histogram title. Show errors on X as bin width x 0.5 The Y points are set * to the mean values in each bin. * * * @param title * New title * * @param histo * Imported histogram * * */ public P1D(String title, H1D histo) { this(title, histo, true, true); } /** * Merge two P1D containers. * * @param p1d * Container to be added * @return modified P1D container */ public P1D merge(P1D p1d) { X.addAllOf(p1d.getXval()); Y.addAllOf(p1d.getYval()); if (dimen == 2) return this; if (dimen == 3) { YE1upper.addAllOf(p1d.getYE1upper()); return this; } if (dimen == 4) { YE1upper.addAllOf(p1d.getYE1upper()); YE1down.addAllOf(p1d.getYE1down()); return this; } if (dimen == 6) { YE1upper.addAllOf(p1d.getYE1upper()); YE1down.addAllOf(p1d.getYE1down()); XE1left.addAllOf(p1d.getXE1left()); XE1right.addAllOf(p1d.getXE1right()); return this; } if (dimen == 10) { YE1upper.addAllOf(p1d.getYE1upper()); YE1down.addAllOf(p1d.getYE1down()); XE1left.addAllOf(p1d.getXE1left()); XE1right.addAllOf(p1d.getXE1right()); YE2upper.addAllOf(p1d.getYE2upper()); YE2down.addAllOf(p1d.getYE2down()); XE2left.addAllOf(p1d.getXE2left()); XE2right.addAllOf(p1d.getXE2right()); return this; } return this; } /** * Removes at the position * @param position * @return */ public P1D remove(int position) { X.remove(position); Y.remove(position); if (dimen == 2) return this; if (dimen == 3) { YE1upper.remove(position); return this; } if (dimen == 4) { YE1upper.remove(position); YE1down.remove(position); return this; } if (dimen == 6) { YE1upper.remove(position); YE1down.remove(position); XE1left.remove(position); XE1right.remove(position); return this; } if (dimen == 10) { YE1upper.remove(position); YE1down.remove(position); XE1left.remove(position); XE1right.remove(position); YE2upper.remove(position); YE2down.remove(position); XE2left.remove(position); XE2right.remove(position); return this; } return this; } /** * Returns the hash code value for this collection (onoy X,Y values) */ public int hashCode() { return X.hashCode() + Y.hashCode(); } /** * Searches the list front to back for the index of value, starting at offset. * Here we search for (X,Y) value. The search is done for pairs only. * @param valueX X value * @param valueY Y value * @return index of X with found pair value. If not pair found, return -1. */ public int indexOf(double valueX, double valueY) { int i1 = X.indexOf(valueX); int i2 = Y.indexOf(valueY); if (i1 > -1 && i2 > -1 && i1 == i2) return i1; return -1; } /** * Searches for the index of value, starting at offset, but backwards * Here we search for (X,Y) pairs only. * @param valueX X value * @param valueY Y value * @return index with the found pair value (or -1 if not found) */ public int lastIndexOf(double valueX, double valueY) { int i1 = X.lastIndexOf(valueX); int i2 = Y.lastIndexOf(valueY); if (i1 > -1 && i2 > -1 && i1 == i2) return i1; return -1; } /** * Searches the list front to back for the index of value, starting at offset. * @param valueX X value * @return index of found value */ public int indexOfX(double valueX) { return X.indexOf(valueX); } /** * Searches for value in X backwards. * @param valueX X value * @return index of found value */ public int lastIndexOfX(double valueX) { return X.lastIndexOf(valueX); } /** * Searches for a Y value starting at offset. * Here we serch for (Y) value. * @param valueY Y value * @return index of found value */ public int indexOfY(double valueY) { return Y.indexOf(valueY); } /** * Searches for a Y value backewards. * * @param valueY Y value * @return index of found value */ public int lastIndexOfY(double valueY) { return Y.indexOf(valueY); } /** * Set data in a form of DataArray * * @param data * input data * */ public void setDataArray(DataArray data) { setDimension(10); for (int i = 0; i < data.size(); i++) { X.add(data.getX(i)); Y.add(data.getY(i)); XE1left.add(data.getX(i)); XE1right.add(data.getY(i)); XE2left.add(data.getXleft(i)); XE2right.add(data.getXright(i)); YE1upper.add(data.getYupper(i)); YE1down.add(data.getYlower(i)); YE2upper.add(data.getYupperSys(i)); YE2down.add(data.getYlowerSys(i)); } } /** * Scale X-values (axis=0) or Y values (axis=1) and their errors with a * scale factor. The object to be returned is the same, only X or Y are * scaled. * * @param axis * axis for which scaling is applied. set to 0 for X and set to 1 * for Y. * * @param scale * Scale factor * */ public void operScale(int axis, double scale) { if (axis != 0 && axis != 1) { ErrorMessage("Axis variable should be 0 or 1!"); return; } // scale X if (axis == 0) { for (int i = 0; i < size(); i++) { X.setQuick(i, getQuickX(i) * scale); } if (dimen == 6) { for (int i = 0; i < size(); i++) { XE1left.setQuick(i, getXleft(i) * scale); XE1right.setQuick(i, getXright(i) * scale); } } if (dimen == 10) { for (int i = 0; i < size(); i++) { XE1left.setQuick(i, getXleft(i) * scale); XE1right.setQuick(i, getXright(i) * scale); XE2left.setQuick(i, getXleftSys(i) * scale); XE2right.setQuick(i, getXrightSys(i) * scale); } } } // scale Y if (axis == 1) { for (int i = 0; i < size(); i++) { Y.setQuick(i, getQuickY(i) * scale); } if (dimen == 3) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, getYupper(i) * scale); } } if (dimen == 6 || dimen == 4) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, getYupper(i) * scale); YE1down.setQuick(i, getYlower(i) * scale); } } if (dimen == 10) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, getYupper(i) * scale); YE1down.setQuick(i, getYlower(i) * scale); YE2upper.setQuick(i, getYupperSys(i) * scale); YE2down.setQuick(i, getYlowerSys(i) * scale); } } } } /** * Set 1st level errors to zero. All other errors are the same as before. * * @param axis * axis = 0 for X, axis =1 for Y */ public void setErrToZero(int axis) { if (axis != 0 && axis != 1) { ErrorMessage("Axis variable should be 0 or 1!"); return; } if (axis == 0) { if (dimen == 6) { for (int i = 0; i < size(); i++) { XE1left.setQuick(i, 0); XE1right.setQuick(i, 0); } } if (dimen == 10) { for (int i = 0; i < size(); i++) { XE1left.setQuick(i, 0); XE1right.setQuick(i, 0); } } } // scale Y if (axis == 1) { if (dimen == 3) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, 0); } } if (dimen == 6 || dimen == 4) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, 0); YE1down.setQuick(i, 0); } } if (dimen == 10) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, 0); YE1down.setQuick(i, 0); } } } } /** * Set all (1st and 2nd) level errors to zero. If axis=0, for X values if * axis=1, for Y values * * @param axis * axis = 0 for X, axis =1 for Y */ public void setErrAllToZero(String title, int axis) { if (axis != 0 && axis != 1) { ErrorMessage("Axis variable should be 0 or 1!"); return; } if (axis == 0) { if (dimen == 6) { for (int i = 0; i < size(); i++) { XE1left.setQuick(i, 0); XE1right.setQuick(i, 0); } } if (dimen == 10) { for (int i = 0; i < size(); i++) { XE1left.setQuick(i, 0); XE1right.setQuick(i, 0); XE2left.setQuick(i, 0); XE2right.setQuick(i, 0); } } } // scale Y if (axis == 1) { if (dimen == 3) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, 0); } } if (dimen == 6 || dimen == 4) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, 0); YE1down.setQuick(i, 0); } } if (dimen == 10) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, 0); YE1down.setQuick(i, 0); YE2upper.setQuick(i, 0); YE2down.setQuick(i, 0); } } } } /** * Set 2nd level errors to zero. * * @param axis * axis = 0 for X, axis =1 for Y */ public void setErrSysToZero(int axis) { if (axis != 0 && axis != 1) { ErrorMessage("Axis variable should be 0 or 1!"); return; } if (axis == 0) { if (dimen == 10) { for (int i = 0; i < size(); i++) { XE2left.setQuick(i, 0); XE2right.setQuick(i, 0); } } } if (axis == 1) { if (dimen == 10) { for (int i = 0; i < size(); i++) { YE2upper.setQuick(i, 0); YE2down.setQuick(i, 0); } } } } /** * Set 1st level error to sqrt of X or Y values. If axis=0, left and right * errors will be set on X as sqrt(X). If axis=1, upper and lower errors * will be set on Y as sqrt(Y). * * @param axis * axis (=0 for X, 1 for Y). */ public void setErrSqrt(int axis) { if (axis != 0 && axis != 1) { ErrorMessage("Axis variable should be 0 or 1!"); return; } if (axis == 0) { if (dimen > 5) { for (int i = 0; i < size(); i++) { XE1left.setQuick(i, Math.sqrt(X.getQuick(i))); XE1right.setQuick(i, Math.sqrt(X.getQuick(i))); } } } if (axis == 1) { if (dimen == 3) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, Math.sqrt(Y.getQuick(i))); } } if (dimen > 3) { for (int i = 0; i < size(); i++) { double e = Math.sqrt(Y.getQuick(i)); YE1upper.setQuick(i, e); YE1down.setQuick(i, e); } } } } /** * Scale 2nd level errors with a scale factor. If axis=0, the scaling is * applied to errors on X, if axis=1, the scale factor is applied for errors * on Y. * * @param axis * axis to a which a scale factor is applied (=0 for X, =1 for * Y). * @param scale * Scale factor to be applied to 2nd level errors defined by axis * */ public void operScaleErrSys(int axis, double scale) { if (axis != 0 && axis != 1) { ErrorMessage("Axis variable should be 0 or 1!"); return; } // scale X if (axis == 0) { if (dimen > 6) { for (int i = 0; i < size(); i++) { XE2left.setQuick(i, getXleftSys(i) * scale); XE2right.setQuick(i, getXrightSys(i) * scale); } } } // scale Y if (axis == 1) { if (dimen > 6) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, getYupper(i) * scale); YE1down.setQuick(i, getYlower(i) * scale); YE2upper.setQuick(i, getYupperSys(i) * scale); YE2down.setQuick(i, getYlowerSys(i) * scale); } } } } /** * Add all Y-values from another P1D. X-values will be unchanged. 1st and 2nd errors on Y are added * in quadrature assuming uncorrelated Y-values. Dimensions are assumed to be the same. * @param p1d * P1D to be added to the original. Only Y-values are added, x-values are unchanged. **/ public void operPlusY(P1D p1) { if (dimen != p1.getDimension()) { ErrorMessage("Different dimensions for operPlusY() operation!"); return; } if (size() != p1.size()) { ErrorMessage("Different object sizes for operPlusY() operation!"); return; } for (int i = 0; i < size(); i++) { Y.setQuick(i, getY(i) + p1.getY(i)); if (dimen == 3) { double yup = getYupper(i) * getYupper(i) + p1.getYupper(i) * p1.getYupper(i); YE1upper.setQuick(i, Math.sqrt(yup)); } if (dimen == 4 || dimen == 6) { double yup = getYupper(i) * getYupper(i) + p1.getYupper(i) * p1.getYupper(i); double ylow = getYlower(i) * getYlower(i) + p1.getYlower(i) * p1.getYlower(i); YE1upper.setQuick(i, Math.sqrt(yup)); YE1down.setQuick(i, Math.sqrt(ylow)); } if (dimen > 6) { double yup = getYupper(i) * getYupper(i) + p1.getYupper(i) * p1.getYupper(i); double ylow = getYlower(i) * getYlower(i) + p1.getYlower(i) * p1.getYlower(i); double yupS = getYupperSys(i) * getYupperSys(i) + p1.getYupperSys(i) * p1.getYupperSys(i); double ylowS = getYlowerSys(i) * getYlowerSys(i) + p1.getYlowerSys(i) * p1.getYlowerSys(i); YE1upper.setQuick(i, Math.sqrt(yup)); YE1down.setQuick(i, Math.sqrt(ylow)); YE2upper.setQuick(i, Math.sqrt(yupS)); YE2down.setQuick(i, Math.sqrt(ylowS)); } } } /** * Scale 1st level errors with a scale factor. If axis=0, the scaling is * applied to errors on X, if axis=1, the scale factor to errors on Y. * * @param axis * axis to which a scale factor is applied (=0 for X, 1 for Y). * @param scale * Scale factor to be applied to 1st level errors defined by axis * */ public void operScaleErr(int axis, double scale) { if (axis != 0 && axis != 1) { ErrorMessage("Axis variable should be 0 or 1!"); return; } if (axis == 0) { if (dimen == 6) { for (int i = 0; i < size(); i++) { XE1left.setQuick(i, getXleft(i) * scale); XE1right.setQuick(i, getXright(i) * scale); } } if (dimen == 10) { for (int i = 0; i < size(); i++) { XE1left.setQuick(i, getXleft(i) * scale); XE1right.setQuick(i, getXright(i) * scale); XE2left.setQuick(i, getXleftSys(i) * scale); XE2right.setQuick(i, getXrightSys(i) * scale); } } } // scale Y if (axis == 1) { if (dimen == 3) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, getYupper(i) * scale); } } if (dimen == 4 || dimen == 6) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, getYupper(i) * scale); YE1down.setQuick(i, getYlower(i) * scale); } } if (dimen == 10) { for (int i = 0; i < size(); i++) { YE1upper.setQuick(i, getYupper(i) * scale); YE1down.setQuick(i, getYlower(i) * scale); YE2upper.setQuick(i, getYupperSys(i) * scale); YE2down.setQuick(i, getYlowerSys(i) * scale); } } } } /** * Obtain a new P1D with 2nd-level errors on X or Y obtained from two P1D * objects, one represents left on X (or lower on Y) error and the other * represents the right on X (or upper on Y) error. To define X or Y axis, * use "axis" variable. If axis=0, this method will be applied for X, if * axis=1, this will be applied for Y. This means the central X,Y values are * given by the original P1D, while 2nd level errors on X or Y of the * original P1D are given by the differences: central-left and right-central * for X or upper-central and central-lower for Y. The statistical errors * (1st-level errors) are the same as for the original P1D. In case if it * happen that the upper P1D is lower than the central value, it takes * absolute value. This method is useful if you need to plot uncertainties * associated with a measurement. Note: the method does create new object. * * @param title * New Title * @param axis * axis=0, errors will be set to X (left and right). If axis=1, * errors will be set as lower and upper error. * @param left * P1D used to build left errors on the central values (in X, * when axis=0) or lower error on Y (when axis=1) * @param right * P1D used to build right errors on the central values (in X, * when axis=0) or upper error on Y (when axis=1) * * @return Same P1D container with the 2nd-level errors on X or Y given by * the differences between the original P1D and left (or right) P1Ds * (if axis=0), or upper and lower P1Ds (if axis=1) */ public P1D operErrSys(String title, int axis, P1D left, P1D right) { this.title = title; if (size() != left.size() || size() != right.size()) { ErrorMessage("Wrong size!"); return this; } /* for (int i = 0; i < data.size(); i++) { if (axis == 0) { data.setQuickPoint(i, data.getX(i), data.getY(i), data.getXleft(i), data.getXright(i), data.getYupper(i), data.getYlower(i), Math.abs(data.getX(i) - left.getX(i)), Math.abs(right.getX(i) - data.getX(i)), data.getYupperSys(i), data.getYlowerSys(i)); } if (axis == 1) { data.setQuickPoint(i, data.getX(i), data.getY(i), data.getXleft(i), data.getXright(i), data.getYupper(i), data.getYlower(i), data.getXleftSys(i), data.getXrightSys(i), Math.abs(right.getY(i) - data.getY(i)), Math.abs(data.getY(i) - left.getY(i))); } } ; data.allUpdate(); */ return this; } /** * Operations on P1D container: add, subtract, multiply, divide. Keep the * same graphical attributes and the title as for the original container. * Note, no new object is created. * * @param a * Input P1D container * * @param what * the operation type (+,-,*,/) * @return 0 if no problems. */ public int oper(P1D a, String what) { return oper(a, getTitle(), what); } /** * Operations on P1D containers: add, subtract, multiply, divide. Keep the * same graphical attributes, They are all applied for "Y", rather than for X. * Errors on Y (1st and 2nd) will be propogared assuming independence of the the containers. * Only 1st level error (statisticals) are propogared, the second-level errors are the same. * * @param a * Input P1D container for operation (may contain errors on Y). * @param title * New title * @param what * String representing the operation: <br>"+" add a P1D container to * the original; <br>"-" subtract a P1D from the original; <br>"*" * multiply; <br>"/" divide by P1D * @return error code: * 0 means OK<br> * 1: means divistion by zero <br> * 2: error during error evalutaion */ public int oper(P1D a, String title, String what) { what = what.trim(); // first check them if (size() != a.size()) { ErrorMessage("Sizes of the P1Ds are different!"); return 1; } if (what.equals("+") == false && what.equals("-") == false && what.equals("/") == false && what.equals("/")) { ErrorMessage("Operation \"" + what + "\" is not implemented"); return 1; } if (dimen == 2) { if (what.equals("+")) { for (int i = 0; i < size(); i++) Y.setQuick(i, Y.getQuick(i) + a.getY(i)); return 0; } if (what.equals("-")) { for (int i = 0; i < size(); i++) Y.setQuick(i, Y.getQuick(i) - a.getY(i)); return 0; } if (what.equals("*")) { for (int i = 0; i < size(); i++) Y.setQuick(i, Y.getQuick(i) * a.getY(i)); return 0; } if (what.equals("/")) { for (int i = 0; i < size(); i++) { if (a.getY(i) == 0) return 1; Y.setQuick(i, Y.getQuick(i) / a.getY(i)); } return 0; } } // end 2-D if (dimen == 3) { if (what.equals("+")) { for (int i = 0; i < size(); i++) { Y.setQuick(i, Y.getQuick(i) + a.getY(i)); double y = Math.sqrt(a.getYupper(i) * a.getYupper(i) + a.getYupper(i) * a.getYupper(i)); YE1upper.setQuick(i, y); } return 0; } if (what.equals("-")) { for (int i = 0; i < size(); i++) { Y.setQuick(i, Y.getQuick(i) - a.getY(i)); double y = Math.sqrt(a.getYupper(i) * a.getYupper(i) + a.getYupper(i) * a.getYupper(i)); YE1upper.setQuick(i, y); } return 0; } if (what.equals("*")) { for (int i = 0; i < size(); i++) { double y = Y.getQuick(i) * a.getY(i); Y.setQuick(i, y); double ad1 = a.getY(i); double d1 = getY(i); double ax1; double x1; if (ad1 != 0) ax1 = a.getYupper(i) / ad1; else ax1 = 0; if (d1 != 0) x1 = getYupper(i) / d1; else x1 = 0; double e = y * Math.sqrt(ax1 * ax1 + x1 * x1); YE1upper.setQuick(i, e); } return 0; } if (what.equals("/")) { for (int i = 0; i < size(); i++) { double y = Y.getQuick(i) / a.getY(i); Y.setQuick(i, y); double ad1 = a.getY(i); double d1 = getY(i); double ax1; double x1; if (ad1 != 0) ax1 = a.getYupper(i) / ad1; else ax1 = 0; if (d1 != 0) x1 = getYupper(i) / d1; else x1 = 0; double e = y * Math.sqrt(ax1 * ax1 + x1 * x1); YE1upper.setQuick(i, e); } return 0; } } // end 3D // if (dimen > 3) { if (what.equals("+")) { for (int i = 0; i < size(); i++) { Y.setQuick(i, Y.getQuick(i) + a.getY(i)); double yU = Math.sqrt(a.getYupper(i) * a.getYupper(i) + a.getYupper(i) * a.getYupper(i)); double yD = Math.sqrt(a.getYlower(i) * a.getYlower(i) + a.getYlower(i) * a.getYlower(i)); YE1upper.setQuick(i, yU); YE1down.setQuick(i, yD); } return 0; } if (what.equals("-")) { for (int i = 0; i < size(); i++) { Y.setQuick(i, Y.getQuick(i) - a.getY(i)); double yU = Math.sqrt(a.getYupper(i) * a.getYupper(i) + a.getYupper(i) * a.getYupper(i)); double yD = Math.sqrt(a.getYlower(i) * a.getYlower(i) + a.getYlower(i) * a.getYlower(i)); YE1upper.setQuick(i, yU); YE1down.setQuick(i, yD); } return 0; } if (what.equals("*")) { for (int i = 0; i < size(); i++) { double y = Y.getQuick(i) * a.getY(i); Y.setQuick(i, y); double ad1 = a.getY(i); double d1 = getY(i); double ax1; double x1; if (ad1 != 0) ax1 = a.getYupper(i) / ad1; else ax1 = 0; if (d1 != 0) x1 = getYupper(i) / d1; else x1 = 0; double e1 = y * Math.sqrt(ax1 * ax1 + x1 * x1); YE1upper.setQuick(i, e1); double ad2 = a.getY(i); double d2 = getY(i); double ax2; double x2; if (ad2 != 0) ax2 = a.getYlower(i) / ad2; else ax2 = 0; if (d2 != 0) x2 = getYlower(i) / d2; else x2 = 0; double e2 = y * Math.sqrt(ax2 * ax2 + x2 * x2); YE1down.setQuick(i, e2); } return 0; } if (what.equals("/")) { for (int i = 0; i < size(); i++) { double y = Y.getQuick(i) / a.getY(i); Y.setQuick(i, y); double ad1 = a.getY(i); double d1 = getY(i); double ax1; double x1; if (ad1 != 0) ax1 = a.getYupper(i) / ad1; else ax1 = 0; if (d1 != 0) x1 = getYupper(i) / d1; else x1 = 0; double e1 = y * Math.sqrt(ax1 * ax1 + x1 * x1); YE1upper.setQuick(i, e1); double ad2 = a.getY(i); double d2 = getY(i); double ax2 = 0; double x2; if (ad2 != 0) ax2 = a.getYlower(i) / ad2; else ax1 = 0; if (d2 != 0) x2 = getYlower(i) / d2; else x2 = 0; double e2 = y * Math.sqrt(ax2 * ax2 + x2 * x2); YE1down.setQuick(i, e2); } // end loop return 0; } // and } ; // end dimen>3 return 1; } /** * Operations on P1D containers: add, subtract, multiply, divide. Keep the * same graphical attributes. Correlated errors are taken into account via * additional P1D data holder which keeps correlation coefficients. The size * of this P1D holder should be equal to the original size of P1D. * <p> * This container assumes the dimension 10 (2 X,Y values and 6 errors) * * @param a * Input P1D container for the operation * @param title * New title * @param what * String representing the operation: "+" add a P1D to the * original; "-" subtract a P1D from the original "*"; multiply * "/" divide * @param how * how the operation should be performed: "X" - for X values; "Y" * - do it for Y values; XY - do for X and Y values. Normally, * however, you should do this for the Y option. * * @param corr * P1D container which keeps correlation coefficients for each * point. In most general case, this container should be filled * as: add(0,0,x1,x2,x3,x4,y1,y2,y3,y4), where x1 (left), * x2(right), x3(leftSys), x4(rightSys) - coefficients on X y1 * (up), y2(down), y3(upSys), x4(downSys) - coefficients on Y. * For example, in a simplest case when Y has 1st level * (symmetrical statistical) errors and X does not have any, you * need just define "corr" by filling it with: * add(0,0,0,0,0,0,c,c,0,0), where c is a correlation * coefficient. If "Y" values have both statistical and * systematic errors, use the correlation P1D holder of the form * add(0,0,0,0,0,0,c,c,c1,c2), * * * @return Output P1D container */ public P1D oper(P1D a, String title, String what, String how, P1D corr) { what = what.trim(); if (size() != a.size()) { ErrorMessage("Sizes of the P1Ds are different!"); return this; } if (size() != corr.size()) { ErrorMessage("Sizes of the P1D and P1D with correlations are different!"); return this; } // check if (!what.equals("+") && !what.equals("-") && !what.equals("*") && !what.equals("*")) { ErrorMessage("Operation \"" + what + "\" is not implemented"); return this; } if (dimension() == 3) { ValueErr tmp = new ValueErr(); final int NT = 8; ValueErr erros1[] = new ValueErr[NT]; ValueErr erros2[] = new ValueErr[NT]; double cc[] = new double[NT]; for (int i = 0; i < size(); i++) { erros1[0] = new ValueErr(getX(i), 0); erros1[1] = new ValueErr(getX(i), 0); erros1[2] = new ValueErr(getX(i), 0); erros1[3] = new ValueErr(getX(i), 0); erros1[4] = new ValueErr(getY(i), getYupper(i)); erros1[5] = new ValueErr(getY(i), 0); erros1[6] = new ValueErr(getY(i), 0); erros1[7] = new ValueErr(getY(i), 0); erros2[0] = new ValueErr(a.getX(i), 0); erros2[1] = new ValueErr(a.getX(i), 0); erros2[2] = new ValueErr(a.getX(i), 0); erros2[3] = new ValueErr(a.getX(i), 0); erros2[4] = new ValueErr(a.getY(i), a.getYupper(i)); erros2[5] = new ValueErr(a.getY(i), 0); erros2[6] = new ValueErr(a.getY(i), 0); erros2[7] = new ValueErr(a.getY(i), 0); cc[0] = 0; cc[1] = 0; cc[2] = 0; cc[3] = 0; cc[4] = corr.getYupper(i); cc[5] = 0; cc[6] = 0; cc[7] = 0; if (what.equals("+")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.plus(erros1[j], erros2[j], cc[j]); } if (what.equals("-")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.minus(erros1[j], erros2[j], cc[j]); } if (what.equals("*")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.times(erros1[j], erros2[j], cc[j]); } if (what.equals("/")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.divide(erros1[j], erros2[j], cc[j]); } if (how.equalsIgnoreCase("XY") || how.equalsIgnoreCase("YX")) { double x = erros1[0].getVal(); double y = erros1[4].getVal(); double yu = erros1[4].getErr(); setQuick(i, x, y, yu); } if (how.equalsIgnoreCase("Y")) { double y = erros1[4].getVal(); double yu = erros1[4].getErr(); setQuick(i, getX(i), y, yu); } } } // end dimesion 3 if (dimension() == 4) { final int NT = 8; ValueErr erros1[] = new ValueErr[NT]; ValueErr erros2[] = new ValueErr[NT]; double cc[] = new double[NT]; for (int i = 0; i < size(); i++) { erros1[0] = new ValueErr(getX(i), 0); erros1[1] = new ValueErr(getX(i), 0); erros1[2] = new ValueErr(getX(i), 0); erros1[3] = new ValueErr(getX(i), 0); erros1[4] = new ValueErr(getY(i), getYupper(i)); erros1[5] = new ValueErr(getY(i), getYlower(i)); erros1[6] = new ValueErr(getY(i), 0); erros1[7] = new ValueErr(getY(i), 0); erros2[0] = new ValueErr(a.getX(i), 0); erros2[1] = new ValueErr(a.getX(i), 0); erros2[2] = new ValueErr(a.getX(i), 0); erros2[3] = new ValueErr(a.getX(i), 0); erros2[4] = new ValueErr(a.getY(i), a.getYupper(i)); erros2[5] = new ValueErr(a.getY(i), a.getYlower(i)); erros2[6] = new ValueErr(a.getY(i), 0); erros2[7] = new ValueErr(a.getY(i), 0); cc[0] = 0; cc[1] = 0; cc[2] = 0; cc[3] = 0; cc[4] = corr.getYupper(i); cc[5] = corr.getYlower(i); cc[6] = 0; cc[7] = 0; ValueErr tmp = new ValueErr(); if (what.equals("+")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.plus(erros1[j], erros2[j], cc[j]); } if (what.equals("-")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.minus(erros1[j], erros2[j], cc[j]); } if (what.equals("*")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.times(erros1[j], erros2[j], cc[j]); } if (what.equals("/")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.divide(erros1[j], erros2[j], cc[j]); } if (how.equalsIgnoreCase("XY") || how.equalsIgnoreCase("YX")) { double x = erros1[0].getVal(); double y = erros1[4].getVal(); double yu = erros1[4].getErr(); double yl = erros1[5].getErr(); setQuick(i, x, y, yu, yl); } if (how.equalsIgnoreCase("Y")) { double y = erros1[4].getVal(); double yu = erros1[4].getErr(); double yl = erros1[5].getErr(); setQuick(i, getX(i), y, yu, yl); } } } // end dimesion 10 if (dimension() == 6) { final int NT = 8; ValueErr erros1[] = new ValueErr[NT]; ValueErr erros2[] = new ValueErr[NT]; double cc[] = new double[NT]; for (int i = 0; i < size(); i++) { erros1[0] = new ValueErr(getX(i), getXleft(i)); erros1[1] = new ValueErr(getX(i), getXright(i)); erros1[2] = new ValueErr(getX(i), 0); erros1[3] = new ValueErr(getX(i), 0); erros1[4] = new ValueErr(getY(i), getYupper(i)); erros1[5] = new ValueErr(getY(i), getYlower(i)); erros1[6] = new ValueErr(getY(i), 0); erros1[7] = new ValueErr(getY(i), 0); erros2[0] = new ValueErr(a.getX(i), a.getXleft(i)); erros2[1] = new ValueErr(a.getX(i), a.getXright(i)); erros2[2] = new ValueErr(a.getX(i), 0); erros2[3] = new ValueErr(a.getX(i), 0); erros2[4] = new ValueErr(a.getY(i), a.getYupper(i)); erros2[5] = new ValueErr(a.getY(i), a.getYlower(i)); erros2[6] = new ValueErr(a.getY(i), 0); erros2[7] = new ValueErr(a.getY(i), 0); cc[0] = corr.getXleft(i); cc[1] = corr.getXright(i); cc[2] = 0; cc[3] = 0; cc[4] = corr.getYupper(i); cc[5] = corr.getYlower(i); cc[6] = 0; cc[7] = 0; ValueErr tmp = new ValueErr(); if (what.equals("+")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.plus(erros1[j], erros2[j], cc[j]); } if (what.equals("-")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.minus(erros1[j], erros2[j], cc[j]); } if (what.equals("*")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.times(erros1[j], erros2[j], cc[j]); } if (what.equals("/")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.divide(erros1[j], erros2[j], cc[j]); } if (how.equalsIgnoreCase("XY") || how.equalsIgnoreCase("YX")) { double x = erros1[0].getVal(); double xl = erros1[0].getErr(); double xr = erros1[1].getErr(); double xls = erros1[2].getErr(); double xrs = erros1[3].getErr(); double y = erros1[4].getVal(); double yu = erros1[4].getErr(); double yl = erros1[5].getErr(); double yus = erros1[6].getErr(); double yls = erros1[7].getErr(); setQuick(i, x, y, xl, xr, yu, yl); } if (how.equalsIgnoreCase("X")) { double x = erros1[0].getVal(); double xl = erros1[0].getErr(); double xr = erros1[1].getErr(); double xls = erros1[2].getErr(); double xrs = erros1[3].getErr(); setQuick(i, x, getY(i), xl, xr, getYupper(i), getYlower(i), xls, xrs, getYupperSys(i), getYlowerSys(i)); } if (how.equalsIgnoreCase("Y")) { double y = erros1[4].getVal(); double yu = erros1[4].getErr(); double yl = erros1[5].getErr(); double yus = erros1[6].getErr(); double yls = erros1[7].getErr(); setQuick(i, getX(i), y, getXleft(i), getXright(i), yu, yl); } } } // end dimesion 6 if (dimension() == 10) { ValueErr tmp = new ValueErr(); final int NT = 8; ValueErr erros1[] = new ValueErr[NT]; ValueErr erros2[] = new ValueErr[NT]; double cc[] = new double[NT]; for (int i = 0; i < size(); i++) { erros1[0] = new ValueErr(getX(i), getXleft(i)); erros1[1] = new ValueErr(getX(i), getXright(i)); erros1[2] = new ValueErr(getX(i), getXleftSys(i)); erros1[3] = new ValueErr(getX(i), getXrightSys(i)); erros1[4] = new ValueErr(getY(i), getYupper(i)); erros1[5] = new ValueErr(getY(i), getYlower(i)); erros1[6] = new ValueErr(getY(i), getYupperSys(i)); erros1[7] = new ValueErr(getY(i), getYlowerSys(i)); erros2[0] = new ValueErr(a.getX(i), a.getXleft(i)); erros2[1] = new ValueErr(a.getX(i), a.getXright(i)); erros2[2] = new ValueErr(a.getX(i), a.getXleftSys(i)); erros2[3] = new ValueErr(a.getX(i), a.getXrightSys(i)); erros2[4] = new ValueErr(a.getY(i), a.getYupper(i)); erros2[5] = new ValueErr(a.getY(i), a.getYlower(i)); erros2[6] = new ValueErr(a.getY(i), a.getYupperSys(i)); erros2[7] = new ValueErr(a.getY(i), a.getYlowerSys(i)); cc[0] = corr.getXleft(i); cc[1] = corr.getXright(i); cc[2] = corr.getXleftSys(i); cc[3] = corr.getXrightSys(i); cc[4] = corr.getYupper(i); cc[5] = corr.getYlower(i); cc[6] = corr.getYupperSys(i); cc[7] = corr.getYlowerSys(i); if (what.equals("+")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.plus(erros1[j], erros2[j], cc[j]); } if (what.equals("-")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.minus(erros1[j], erros2[j], cc[j]); } if (what.equals("*")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.times(erros1[j], erros2[j], cc[j]); } if (what.equals("/")) { for (int j = 0; j < NT; j++) erros1[j] = tmp.divide(erros1[j], erros2[j], cc[j]); } if (how.equalsIgnoreCase("XY") || how.equalsIgnoreCase("YX")) { double x = erros1[0].getVal(); double xl = erros1[0].getErr(); double xr = erros1[1].getErr(); double xls = erros1[2].getErr(); double xrs = erros1[3].getErr(); double y = erros1[4].getVal(); double yu = erros1[4].getErr(); double yl = erros1[5].getErr(); double yus = erros1[6].getErr(); double yls = erros1[7].getErr(); setQuick(i, x, y, xl, xr, yu, yl, xls, xrs, yus, yls); } if (how.equalsIgnoreCase("X")) { double x = erros1[0].getVal(); double xl = erros1[0].getErr(); double xr = erros1[1].getErr(); double xls = erros1[2].getErr(); double xrs = erros1[3].getErr(); setQuick(i, x, getY(i), xl, xr, getYupper(i), getYlower(i), xls, xrs, getYupperSys(i), getYlowerSys(i)); } if (how.equalsIgnoreCase("Y")) { double y = erros1[4].getVal(); double yu = erros1[4].getErr(); double yl = erros1[5].getErr(); double yus = erros1[6].getErr(); double yls = erros1[7].getErr(); setQuick(i, getX(i), y, getXleft(i), getXright(i), yu, yl, getXleftSys(i), getXrightSys(i), yus, yls); } } } // end dimesion 10 return this; } /** * Transform a P1D data holder to some function with error propagation (for * both levels) * * @param what * what operation should be performed: "inverse" - inverse to * (1/a); "sqrt" - sqrt(a); "exp" - exp(a); "log" - log10(a); * "cos" - cos(a) ;"sin" - sin(a); "tan" - tan(a); "acos" - * acos(a); "asin" - asin(a); "atan" - atan(a); "cosh" - cosh(a); * "sinh" - sinh(a); "tanh" - tanh(a); "square" - a**2 * * @param how * how the operation should be performed: "X" - for X values; "Y" * - do it for Y values; XY - do for X and Y * * @return transformed P1D object */ // http://www.ee.ucl.ac.uk/~mflanaga/java/tmp.html public P1D move(String what, String how) { //if ( dimen != 10) { // ErrorMessage(" You should initialize the container with dimension 10 for this operation."); // // } final int NT = 8; ValueErr erros[] = new ValueErr[NT]; if (dimension() == 2) { ValueErr tmp = new ValueErr(); for (int i = 0; i < size(); i++) { erros[0] = new ValueErr(X.getQuick(i), 0); erros[1] = new ValueErr(X.getQuick(i), 0); erros[2] = new ValueErr(X.getQuick(i), 0); erros[3] = new ValueErr(X.getQuick(i), 0); erros[4] = new ValueErr(Y.getQuick(i), 0); erros[5] = new ValueErr(Y.getQuick(i), 0); erros[6] = new ValueErr(Y.getQuick(i), 0); erros[7] = new ValueErr(Y.getQuick(i), 0); if (what.equalsIgnoreCase("inverse")) { for (int j = 0; j < NT; j++) erros[j] = tmp.inverse(erros[j]); } if (what.equalsIgnoreCase("exp")) { for (int j = 0; j < NT; j++) erros[j] = tmp.exp(erros[j]); } if (what.equalsIgnoreCase("log")) { for (int j = 0; j < NT; j++) erros[j] = tmp.log(erros[j]); } if (what.equalsIgnoreCase("sqrt")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sqrt(erros[j]); } if (what.equalsIgnoreCase("square")) { for (int j = 0; j < NT; j++) erros[j] = tmp.square(erros[j]); } if (what.equalsIgnoreCase("sin")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sin(erros[j]); } if (what.equalsIgnoreCase("cos")) { for (int j = 0; j < NT; j++) erros[j] = tmp.cos(erros[j]); } if (what.equalsIgnoreCase("tan")) { for (int j = 0; j < NT; j++) erros[j] = tmp.tan(erros[j]); } if (what.equalsIgnoreCase("sinh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sinh(erros[j]); } if (what.equalsIgnoreCase("cosh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.cosh(erros[j]); } if (what.equalsIgnoreCase("tanh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.tanh(erros[j]); } if (what.equalsIgnoreCase("asin")) { for (int j = 0; j < NT; j++) erros[j] = tmp.asin(erros[j]); } if (what.equalsIgnoreCase("acos")) { for (int j = 0; j < NT; j++) erros[j] = tmp.acos(erros[j]); } if (what.equalsIgnoreCase("atan")) { for (int j = 0; j < NT; j++) erros[j] = tmp.atan(erros[j]); } if (how.equalsIgnoreCase("XY") || how.equalsIgnoreCase("YX")) { double x = erros[0].getVal(); double y = erros[4].getVal(); X.setQuick(i, x); Y.setQuick(i, y); } if (how.equalsIgnoreCase("X")) { double x = erros[0].getVal(); X.setQuick(i, x); } if (how.equalsIgnoreCase("Y")) { double y = erros[4].getVal(); Y.setQuick(i, y); } } } // end dimesion 2 if (dimension() == 3) { ValueErr tmp = new ValueErr(); for (int i = 0; i < size(); i++) { erros[0] = new ValueErr(X.getQuick(i), 0); erros[1] = new ValueErr(X.getQuick(i), 0); erros[2] = new ValueErr(X.getQuick(i), 0); erros[3] = new ValueErr(X.getQuick(i), 0); erros[4] = new ValueErr(Y.getQuick(i), YE1upper.getQuick(i)); erros[5] = new ValueErr(Y.getQuick(i), 0); erros[6] = new ValueErr(Y.getQuick(i), 0); erros[7] = new ValueErr(Y.getQuick(i), 0); if (what.equalsIgnoreCase("inverse")) { for (int j = 0; j < NT; j++) erros[j] = tmp.inverse(erros[j]); } if (what.equalsIgnoreCase("exp")) { for (int j = 0; j < NT; j++) erros[j] = tmp.exp(erros[j]); } if (what.equalsIgnoreCase("log")) { for (int j = 0; j < NT; j++) erros[j] = tmp.log(erros[j]); } if (what.equalsIgnoreCase("sqrt")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sqrt(erros[j]); } if (what.equalsIgnoreCase("square")) { for (int j = 0; j < NT; j++) erros[j] = tmp.square(erros[j]); } if (what.equalsIgnoreCase("sin")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sin(erros[j]); } if (what.equalsIgnoreCase("cos")) { for (int j = 0; j < NT; j++) erros[j] = tmp.cos(erros[j]); } if (what.equalsIgnoreCase("tan")) { for (int j = 0; j < NT; j++) erros[j] = tmp.tan(erros[j]); } if (what.equalsIgnoreCase("sinh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sinh(erros[j]); } if (what.equalsIgnoreCase("cosh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.cosh(erros[j]); } if (what.equalsIgnoreCase("tanh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.tanh(erros[j]); } if (what.equalsIgnoreCase("asin")) { for (int j = 0; j < NT; j++) erros[j] = tmp.asin(erros[j]); } if (what.equalsIgnoreCase("acos")) { for (int j = 0; j < NT; j++) erros[j] = tmp.acos(erros[j]); } if (what.equalsIgnoreCase("atan")) { for (int j = 0; j < NT; j++) erros[j] = tmp.atan(erros[j]); } if (how.equalsIgnoreCase("XY") || how.equalsIgnoreCase("YX")) { double x = erros[0].getVal(); double y = erros[4].getVal(); double yu = erros[4].getErr(); X.setQuick(i, x); Y.setQuick(i, y); YE1upper.setQuick(i, yu); } if (how.equalsIgnoreCase("Y")) { double y = erros[4].getVal(); double yu = erros[4].getErr(); Y.set(i, y); YE1upper.setQuick(i, yu); } } } // end dimesion 10 if (dimension() == 4) { ValueErr tmp = new ValueErr(); for (int i = 0; i < size(); i++) { erros[0] = new ValueErr(X.getQuick(i), 0); erros[1] = new ValueErr(X.getQuick(i), 0); erros[2] = new ValueErr(X.getQuick(i), 0); erros[3] = new ValueErr(X.getQuick(i), 0); erros[4] = new ValueErr(Y.getQuick(i), YE1upper.getQuick(i)); erros[5] = new ValueErr(Y.getQuick(i), YE1down.getQuick(i)); erros[6] = new ValueErr(Y.getQuick(i), 0); erros[7] = new ValueErr(Y.getQuick(i), 0); if (what.equalsIgnoreCase("inverse")) { for (int j = 0; j < NT; j++) erros[j] = tmp.inverse(erros[j]); } if (what.equalsIgnoreCase("exp")) { for (int j = 0; j < NT; j++) erros[j] = tmp.exp(erros[j]); } if (what.equalsIgnoreCase("log")) { for (int j = 0; j < NT; j++) erros[j] = tmp.log(erros[j]); } if (what.equalsIgnoreCase("sqrt")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sqrt(erros[j]); } if (what.equalsIgnoreCase("square")) { for (int j = 0; j < NT; j++) erros[j] = tmp.square(erros[j]); } if (what.equalsIgnoreCase("sin")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sin(erros[j]); } if (what.equalsIgnoreCase("cos")) { for (int j = 0; j < NT; j++) erros[j] = tmp.cos(erros[j]); } if (what.equalsIgnoreCase("tan")) { for (int j = 0; j < NT; j++) erros[j] = tmp.tan(erros[j]); } if (what.equalsIgnoreCase("sinh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sinh(erros[j]); } if (what.equalsIgnoreCase("cosh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.cosh(erros[j]); } if (what.equalsIgnoreCase("tanh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.tanh(erros[j]); } if (what.equalsIgnoreCase("asin")) { for (int j = 0; j < NT; j++) erros[j] = tmp.asin(erros[j]); } if (what.equalsIgnoreCase("acos")) { for (int j = 0; j < NT; j++) erros[j] = tmp.acos(erros[j]); } if (what.equalsIgnoreCase("atan")) { for (int j = 0; j < NT; j++) erros[j] = tmp.atan(erros[j]); } if (how.equalsIgnoreCase("XY") || how.equalsIgnoreCase("YX")) { double x = erros[0].getVal(); double y = erros[4].getVal(); double yu = erros[4].getErr(); double yl = erros[5].getErr(); X.setQuick(i, x); Y.setQuick(i, y); YE1upper.setQuick(i, yu); YE1down.setQuick(i, yl); } if (how.equalsIgnoreCase("Y")) { double y = erros[4].getVal(); double yu = erros[4].getErr(); double yl = erros[5].getErr(); Y.set(i, y); YE1upper.setQuick(i, yu); YE1down.setQuick(i, yl); } } } // end dimesion 4 if (dimension() == 6) { ValueErr tmp = new ValueErr(); for (int i = 0; i < size(); i++) { erros[0] = new ValueErr(X.getQuick(i), XE1left.getQuick(i)); erros[1] = new ValueErr(X.getQuick(i), XE1right.getQuick(i)); erros[2] = new ValueErr(X.getQuick(i), 0); erros[3] = new ValueErr(X.getQuick(i), 0); erros[4] = new ValueErr(Y.getQuick(i), YE1upper.getQuick(i)); erros[5] = new ValueErr(Y.getQuick(i), YE1down.getQuick(i)); erros[6] = new ValueErr(Y.getQuick(i), 0); erros[7] = new ValueErr(Y.getQuick(i), 0); if (what.equalsIgnoreCase("inverse")) { for (int j = 0; j < NT; j++) erros[j] = tmp.inverse(erros[j]); } if (what.equalsIgnoreCase("exp")) { for (int j = 0; j < NT; j++) erros[j] = tmp.exp(erros[j]); } if (what.equalsIgnoreCase("log")) { for (int j = 0; j < NT; j++) erros[j] = tmp.log(erros[j]); } if (what.equalsIgnoreCase("sqrt")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sqrt(erros[j]); } if (what.equalsIgnoreCase("square")) { for (int j = 0; j < NT; j++) erros[j] = tmp.square(erros[j]); } if (what.equalsIgnoreCase("sin")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sin(erros[j]); } if (what.equalsIgnoreCase("cos")) { for (int j = 0; j < NT; j++) erros[j] = tmp.cos(erros[j]); } if (what.equalsIgnoreCase("tan")) { for (int j = 0; j < NT; j++) erros[j] = tmp.tan(erros[j]); } if (what.equalsIgnoreCase("sinh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sinh(erros[j]); } if (what.equalsIgnoreCase("cosh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.cosh(erros[j]); } if (what.equalsIgnoreCase("tanh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.tanh(erros[j]); } if (what.equalsIgnoreCase("asin")) { for (int j = 0; j < NT; j++) erros[j] = tmp.asin(erros[j]); } if (what.equalsIgnoreCase("acos")) { for (int j = 0; j < NT; j++) erros[j] = tmp.acos(erros[j]); } if (what.equalsIgnoreCase("atan")) { for (int j = 0; j < NT; j++) erros[j] = tmp.atan(erros[j]); } if (how.equalsIgnoreCase("XY") || how.equalsIgnoreCase("YX")) { double x = erros[0].getVal(); double xl = erros[0].getErr(); double xr = erros[1].getErr(); double y = erros[4].getVal(); double yu = erros[4].getErr(); double yl = erros[5].getErr(); X.set(i, x); Y.set(i, y); XE1left.set(i, xl); XE1right.set(i, xr); YE1upper.set(i, yu); YE1down.set(i, yl); } if (how.equalsIgnoreCase("X")) { double x = erros[0].getVal(); double xl = erros[0].getErr(); double xr = erros[1].getErr(); X.setQuick(i, x); XE1left.setQuick(i, xl); XE1right.setQuick(i, xr); } if (how.equalsIgnoreCase("Y")) { double y = erros[4].getVal(); double yu = erros[4].getErr(); double yl = erros[5].getErr(); Y.set(i, y); YE1upper.setQuick(i, yu); YE1down.setQuick(i, yl); } } } // end dimesion 6 if (dimension() == 10) { ValueErr tmp = new ValueErr(); for (int i = 0; i < size(); i++) { erros[0] = new ValueErr(X.getQuick(i), XE1left.getQuick(i)); erros[1] = new ValueErr(X.getQuick(i), XE1right.getQuick(i)); erros[2] = new ValueErr(X.getQuick(i), XE2left.getQuick(i)); erros[3] = new ValueErr(X.getQuick(i), XE2right.getQuick(i)); erros[4] = new ValueErr(Y.getQuick(i), YE1upper.getQuick(i)); erros[5] = new ValueErr(Y.getQuick(i), YE1down.getQuick(i)); erros[6] = new ValueErr(Y.getQuick(i), YE2upper.getQuick(i)); erros[7] = new ValueErr(Y.getQuick(i), YE2down.getQuick(i)); if (what.equalsIgnoreCase("inverse")) { for (int j = 0; j < NT; j++) erros[j] = tmp.inverse(erros[j]); } if (what.equalsIgnoreCase("exp")) { for (int j = 0; j < NT; j++) erros[j] = tmp.exp(erros[j]); } if (what.equalsIgnoreCase("log")) { for (int j = 0; j < NT; j++) erros[j] = tmp.log(erros[j]); } if (what.equalsIgnoreCase("sqrt")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sqrt(erros[j]); } if (what.equalsIgnoreCase("square")) { for (int j = 0; j < NT; j++) erros[j] = tmp.square(erros[j]); } if (what.equalsIgnoreCase("sin")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sin(erros[j]); } if (what.equalsIgnoreCase("cos")) { for (int j = 0; j < NT; j++) erros[j] = tmp.cos(erros[j]); } if (what.equalsIgnoreCase("tan")) { for (int j = 0; j < NT; j++) erros[j] = tmp.tan(erros[j]); } if (what.equalsIgnoreCase("sinh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.sinh(erros[j]); } if (what.equalsIgnoreCase("cosh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.cosh(erros[j]); } if (what.equalsIgnoreCase("tanh")) { for (int j = 0; j < NT; j++) erros[j] = tmp.tanh(erros[j]); } if (what.equalsIgnoreCase("asin")) { for (int j = 0; j < NT; j++) erros[j] = tmp.asin(erros[j]); } if (what.equalsIgnoreCase("acos")) { for (int j = 0; j < NT; j++) erros[j] = tmp.acos(erros[j]); } if (what.equalsIgnoreCase("atan")) { for (int j = 0; j < NT; j++) erros[j] = tmp.atan(erros[j]); } if (how.equalsIgnoreCase("XY") || how.equalsIgnoreCase("YX")) { double x = erros[0].getVal(); double xl = erros[0].getErr(); double xr = erros[1].getErr(); double xls = erros[2].getErr(); double xrs = erros[3].getErr(); double y = erros[4].getVal(); double yu = erros[4].getErr(); double yl = erros[5].getErr(); double yus = erros[6].getErr(); double yls = erros[7].getErr(); X.set(i, x); Y.set(i, y); XE1left.set(i, xl); XE1right.set(i, xr); XE2left.set(i, xls); XE2right.set(i, xrs); YE1upper.set(i, yu); YE1down.set(i, yl); YE2upper.set(i, yus); YE2down.set(i, yls); } if (how.equalsIgnoreCase("X")) { double x = erros[0].getVal(); double xl = erros[0].getErr(); double xr = erros[1].getErr(); double xls = erros[2].getErr(); double xrs = erros[3].getErr(); X.setQuick(i, x); XE1left.setQuick(i, xl); XE1right.setQuick(i, xr); XE2left.setQuick(i, xls); XE2right.setQuick(i, xrs); } if (how.equalsIgnoreCase("Y")) { double y = erros[4].getVal(); double yu = erros[4].getErr(); double yl = erros[5].getErr(); double yus = erros[6].getErr(); double yls = erros[7].getErr(); Y.set(i, y); YE1upper.setQuick(i, yu); YE1down.setQuick(i, yl); YE2upper.setQuick(i, yus); YE2down.setQuick(i, yls); } } } // end dimesion 10 return this; } /** * Return a DataArray container from JPlot * * @return Container of type DataArray */ public DataArray getDataArray() { DataArray data = new DataArray(); data.allocate(X.size()); if (dimen == 2) for (int i = 0; i < X.size(); i++) data.addPoint(X.getQuick(i), Y.getQuick(i), 0, 0, 0, 0, 0, 0, 0, 0); else if (dimen == 3) for (int i = 0; i < X.size(); i++) data.addPoint(X.getQuick(i), Y.getQuick(i), 0, 0, YE1upper.getQuick(i), YE1upper.getQuick(i), 0, 0, 0, 0); else if (dimen == 4) for (int i = 0; i < X.size(); i++) data.addPoint(X.getQuick(i), Y.getQuick(i), 0, 0, YE1upper.getQuick(i), YE1down.getQuick(i), 0, 0, 0, 0); else if (dimen == 6) for (int i = 0; i < X.size(); i++) data.addPoint(X.getQuick(i), Y.getQuick(i), XE1left.getQuick(i), XE1right.getQuick(i), YE1upper.getQuick(i), YE1down.getQuick(i), 0, 0, 0, 0); else if (dimen == 10) for (int i = 0; i < X.size(); i++) data.addPoint(X.getQuick(i), Y.getQuick(i), XE1left.getQuick(i), XE1right.getQuick(i), YE1upper.getQuick(i), YE1down.getQuick(i), XE2left.getQuick(i), XE2right.getQuick(i), YE2upper.getQuick(i), YE2down.getQuick(i)); return data; } /** * Adds values of a plot-point pair (X,Y). All 1st and 2nd level errors on X * and Y are assumed to be 0. The dimension of this container is 2 by default. * * @param x * X-value of the plot-point * @param y * Y-value of the plot-point */ public void add(double x, double y) { X.add(x); Y.add(y); } /** * Adds the values of a plot-point pair (X,Y). It is assumed that Y-values * have 1st level symmetrical errors (i.e. statistical errors). All other * errors are set to 0 This point is added at the end of the array. * <p> * This is a fast implementation. Not check of the dimension is done. * The dimension of this container should be set to 3 before you use this method. * * @param x * X-value of the plot-point * @param y * Y-value of the plot-point * @param err * an error on Y (assume symmetrical) */ public void addQuick(double x, double y, double err) { X.add(x); Y.add(y); YE1upper.add(err); } /** * Adds the values of a plot-point pair (X,Y). It is assumed that Y-values * have 1st level symmetrical errors (i.e. statistical errors). All other * errors are set to 0 This point is added at the end of the array. * <p> * This is a slower implementation than addQuick(), since if the dimension * is set wrong, it will be adjusted to 3. * * @param x * X-value of the plot-point * @param y * Y-value of the plot-point * @param err * an error on Y (assume symmetrical) */ public void add(double x, double y, double err) { if (X.size() == 0 && YE1upper == null) { YE1upper = new DoubleArrayList(); dimen = 3; } X.add(x); Y.add(y); YE1upper.add(err); } /** * Add values of a plot-point pair (X,Y). The points include upper and lower * errors on Y. All other errors are set to 0. This point is added at the * end of the array. * * <p> * The container should be initialized with dimenstion 4 before using this method. * This is a fast implementation without dimension check. * * @param x * X-value of the plot-point * @param y * Y-value of the plot-point * @param upper * - upper error on Y * @param lower * - lower error on Y */ public void addQuick(double x, double y, double upper, double lower) { X.add(x); Y.add(y); YE1upper.add(upper); YE1down.add(lower); // dimen = 4; } /** * Add values of a plot-point pair (X,Y). The points include upper and lower * errors on Y. All other errors are set to 0. This point is added at the * end of the array. * * <p> * This is a slower implementation than addQuick(), since if the dimension * is set wrong, it will be adjusted to 4. * @param x * X-value of the plot-point * @param y * Y-value of the plot-point * @param upper * - upper error on Y * @param lower * - lower error on Y */ public void add(double x, double y, double upper, double lower) { if (X.size() == 0) { YE1upper = new DoubleArrayList(); YE1down = new DoubleArrayList(); dimen = 4; } X.add(x); Y.add(y); YE1upper.add(upper); YE1down.add(lower); } /** * Adds the values of a plot-point pair (X,Y). It includes upper and lower * errors on Y and left and right error on X. 2nd level errors are assumed * to be 0. This point is added at the end of the array. * * <p> * This is a slower implementation than addQuick(), since if the dimension * is set wrong, it will be adjusted to 6. * * @param x * X-value of the plot-point * @param y * Y-value of the plot-point * @param left * - left error on X * @param right * - right error on X * @param upper * - upper error on Y * @param lower * - lower error on Y */ public void add(double x, double y, double left, double right, double upper, double lower) { if (X.size() == 0) { YE1upper = new DoubleArrayList(); YE1down = new DoubleArrayList(); XE1left = new DoubleArrayList(); XE1right = new DoubleArrayList(); dimen = 6; } X.add(x); Y.add(y); YE1upper.add(upper); YE1down.add(lower); XE1left.add(left); XE1right.add(right); } /** * Adds the values of a plot-point pair (X,Y). It includes upper and lower * errors on Y and left and right error on X. 2nd level errors are assumed * to be 0. This point is added at the end of the array. * * <p> * The container should be initialized with dimenstion 6 before using this method. * This is a fast implementation without dimension check. * * * @param x * X-value of the plot-point * @param y * Y-value of the plot-point * @param left * - left error on X * @param right * - right error on X * @param upper * - upper error on Y * @param lower * - lower error on Y */ public void addQuick(double x, double y, double left, double right, double upper, double lower) { X.add(x); Y.add(y); YE1upper.add(upper); YE1down.add(lower); XE1left.add(left); XE1right.add(right); // dimen = 6; } /** * Adds the values of a plot-point pair (x,y). It includes upper and lower * errors on X and Y, including 1st and 2nd level errors (i.e. statistical * and systematic). This point is added at the end of the array. * * <p> * * This is a slower implementation than addQuick(), since if the dimension * is set wrong, it will be adjusted to 10. * * * @param x * x-value of the plot-point * @param y * y-value of the plot-point * @param left * - error on x (left) * @param right * - error on x (right) * @param upper * - error on y (upper) * @param lower * - error on y (lower) * @param left_sys * - error on x (left) - second level, used for systematics * @param right_sys * - error on x (right) * @param upper_sys * - error on y (upper) * @param lower_sys * - error on y (lower) */ public void add(double x, double y, double left, double right, double upper, double lower, double left_sys, double right_sys, double upper_sys, double lower_sys) { if (X.size() == 0) { YE1upper = new DoubleArrayList(); YE1down = new DoubleArrayList(); XE1left = new DoubleArrayList(); XE1right = new DoubleArrayList(); YE2upper = new DoubleArrayList(); YE2down = new DoubleArrayList(); XE2left = new DoubleArrayList(); XE2right = new DoubleArrayList(); dimen = 10; } X.add(x); Y.add(y); YE1upper.add(upper); YE1down.add(lower); XE1left.add(left); XE1right.add(right); YE2upper.add(upper_sys); YE2down.add(lower_sys); XE2left.add(left_sys); XE2right.add(right_sys); // dimen = 10; } /** * Adds the values of a plot-point pair (x,y). It includes upper and lower * errors on X and Y, including 1st and 2nd level errors (i.e. statistical * and systematic). This point is added at the end of the array. * * <p> * The container should be initialized with dimenstion 6 before using this method. * This is a fast implementation without dimension check. * * @param x * x-value of the plot-point * @param y * y-value of the plot-point * @param left * - error on x (left) * @param right * - error on x (right) * @param upper * - error on y (upper) * @param lower * - error on y (lower) * @param left_sys * - error on x (left) - second level, used for systematics * @param right_sys * - error on x (right) * @param upper_sys * - error on y (upper) * @param lower_sys * - error on y (lower) */ public void addQuick(double x, double y, double left, double right, double upper, double lower, double left_sys, double right_sys, double upper_sys, double lower_sys) { X.add(x); Y.add(y); YE1upper.add(upper); YE1down.add(lower); XE1left.add(left); XE1right.add(right); YE2upper.add(upper_sys); YE2down.add(lower_sys); XE2left.add(left_sys); XE2right.add(right_sys); // dimen = 10; } /** * Sets the values of a plot-point pair (X,Y). All errors are assumed to be * 0 * * @param i * index of the plot-point * @param x * x-value of the plot-point * @param y * y-value of the plot-point */ public void set(int i, double x, double y) { X.set(i, x); Y.set(i, y); } /** * Sets the values of a plot-point pair (x,y). * The dimension of the container should be 4. * * @param i * index of the plot-point * @param x * x-value of the plot-point * @param y * y-value of the plot-point * @param upper * upper error on y * @param lower * lower error on y */ public void set(int i, double x, double y, double upper, double lower) { X.set(i, x); Y.set(i, y); YE1upper.set(i, upper); YE1down.set(i, lower); // dimen = 4 } /** * Sets the values of a plot-point pair (x,y). * The dimension of the container should be 3. * * <p> * If dimension is wrong, extend it to 3. * * @param i * index of the plot-point * @param x * x-value of the plot-point * @param err * error on Y (symmetric) */ public void set(int i, double x, double y, double err) { if (X.size() == 0 && dimen == 2) { ErrorMessage("The dimension is nor 3!"); return; } X.set(i, x); Y.set(i, y); YE1upper.set(i, err); // dimen = 3 } /** * Sets the values of a plot-point pair (x,y). * The dimension must be 6. * * * @param i * index of the plot-point * @param x * x-value of the plot-point * @param y * y-value of the plot-point * @param left * - error on x (left) * @param right * - error on x (right) * @param upper * - error on y (upper) * @param lower * - error on y (lower) */ public void set(int i, double x, double y, double left, double right, double upper, double lower) { X.set(i, x); Y.set(i, y); YE1upper.set(i, upper); YE1down.set(i, lower); XE1left.set(i, left); XE1right.set(i, right); } /** * Sets the values of a plot-point pair (x,y). * * The dimension must be 10. * * @param i * index of the plot-point * @param x * x-value of the plot-point * @param y * y-value of the plot-point * @param left * - error on x (left) * @param right * - error on x (right) * @param upper * - error on y (upper) * @param lower * - error on y (lower) * @param left_sys * - error on x (left) - second level, used for systematics * @param right_sys * - error on x (right) * @param upper_sys * - error on y (upper) * @param lower_sys * - error on y (lower) * */ public void set(int i, double x, double y, double left, double right, double upper, double lower, double left_sys, double right_sys, double upper_sys, double lower_sys) { X.set(i, x); Y.set(i, y); YE1upper.set(i, upper); YE1down.set(i, lower); XE1left.set(i, left); XE1right.set(i, right); YE2upper.set(i, upper_sys); YE2down.set(i, lower_sys); XE2left.set(i, left_sys); XE2right.set(i, right_sys); } /** * Update summary of the data. This is necessary after using "setQuick" * method, since a single setQuickment of a data point does not trigger * update of min and max for the data ranges. You do not need to do this if * you use "add" or "set" methods. * * @deprecated Debricated! */ public void updateSummary() { ErrorMessage("updateSummary is Debricarted "); } /** * setQuicks the ith value of a plot-point pair (x,y). After all setQuickments * are done, call updateSummary method to get autorange axis values. * The dimension must be 10. * * @param i * index of the plot-point * @param x * x-value of the plot-point * @param y * y-value of the plot-point * @param left * - error on x (left) * @param right * - error on x (right) * @param upper * - error on y (upper) * @param lower * - error on y (lower) * @param left_sys * - error on x (left) - second level, used for systematics * @param right_sys * - error on x (right) * @param upper_sys * - error on y (upper) * @param lower_sys * - error on y (lower) * */ public void setQuick(int i, double x, double y, double left, double right, double upper, double lower, double left_sys, double right_sys, double upper_sys, double lower_sys) { X.setQuick(i, x); Y.setQuick(i, y); YE1upper.setQuick(i, upper); YE1down.setQuick(i, lower); XE1left.setQuick(i, left); XE1right.setQuick(i, right); YE2upper.setQuick(i, upper_sys); YE2down.setQuick(i, lower_sys); XE2left.setQuick(i, left_sys); XE2right.setQuick(i, right_sys); } /** * setQuicks the ith value of a plot-point pair (x,y). After all setQuickments * are done, call updateSummary method to get autorange axis values. * * <p> * The dimension must be 6. * * @param i * index of the plot-point * @param x * x-value of the plot-point * @param y * y-value of the plot-point * @param left * - error on x (left) * @param right * - error on x (right) * @param upper * - error on y (upper) * @param lower * - error on y (lower) * */ public void setQuick(int i, double x, double y, double left, double right, double upper, double lower) { X.setQuick(i, x); Y.setQuick(i, y); YE1upper.setQuick(i, upper); YE1down.setQuick(i, lower); XE1left.setQuick(i, left); XE1right.setQuick(i, right); } /** * setQuicks the ith value of a plot-point pair (x,y). After all setQuickments * are done, call updateSummary method to get autorange axis values. * * <p> * The dimension must be 4. * * @param i * index of the plot-point * @param x * x-value of the plot-point * @param y * y-value of the plot-point * @param upper * - error on y (upper) * @param lower * - error on y (lower) * */ public void setQuick(int i, double x, double y, double upper, double lower) { X.setQuick(i, x); Y.setQuick(i, y); YE1upper.setQuick(i, upper); YE1down.setQuick(i, lower); } /** * setQuicks the ith value of a plot-point pair (x,y). After all setQuickments * are done, call updateSummary method to get autorange axis values. * * <p> * The dimension must be 3. * * @param i * index of the plot-point * @param x * x-value of the plot-point * @param y * y-value of the plot-point * @param err * - error on y (symmetric) * */ public void setQuick(int i, double x, double y, double err) { X.setQuick(i, x); Y.setQuick(i, y); YE1upper.setQuick(i, err); } /** * setQuicks the ith value of a plot-point pair (x,y). After all setQuickments * are done, call updateSummary method to get autorange axis values. * * @param i * index of the plot-point * @param x * x-value of the plot-point * @param y * y-value of the plot-point * */ public void setQuick(int i, double x, double y) { X.setQuick(i, x); Y.setQuick(i, y); } /** * Compare data with a function. The comparison tests hypotheses that * the data represent identical distribution with a function using Pearson's chi-squared test. * The number chi2/ndf gives the estimate (values close to 1 indicates * similarity between 2 histograms.). the function and histogram are identical if chi2=0. * Chi2/ndf and p-value probability is 1. Maken sure that statistical errors are included correctly. * Data with zero errors will be ignored. * @param f1 * function to compare to. * @return map with the result. It gives Chi2, gives number * of degrees of freedom (ndf), probability * ("quality", or p-value). */ public Map<String, Double> compareChi2(F1D f1) { Map<String, Double> tmp = new HashMap<String, Double>(); double sum1 = 0; double nDf = 0; for (int i = 0; i < size(); i++) { double x = getX(i); double bin1 = getY(i); double e1 = getYupper(i); double ff = f1.eval(x); if (e1 != 0) { sum1 = sum1 + ((ff - bin1) * (ff - bin1) / (e1 * e1)); nDf++; } } double chi2 = sum1; tmp.put("chi2", chi2); tmp.put("ndf", (double) nDf); org.apache.commons.math3.distribution.ChiSquaredDistribution chi2Distribution = new org.apache.commons.math3.distribution.ChiSquaredDistribution( nDf); double prob = chi2Distribution.cumulativeProbability(chi2); tmp.put("p-value", 1.0 - prob); return tmp; } /** * Compare two data sets in X-Y. Comparison of two data sets test hypotheses that * two data sets represent identical distributions in 2D. It calculates Chi2 * between values in Y taking into account errors on the Y values. * The number chi2/ndf gives the estimate (values close to 1 indicates * similarity between 2 histograms.) Two P1D are identical if chi2=0. * Chi2/ndf can be obtained as output[0]/output[1]. Probability (p-value) is 1. * <p> * Make sure that both P1D have symmetric errors on Y (first level, i.e. * obtained with the method getYupper(i) (or set them to small values). * * @param h2 * second P1D * * @return the result. It gives Chi2, gives number * of degrees of freedom (ndf), and probability * ("quality", or p-value). */ public Map<String, Double> compareChi2(P1D h2) { Map<String, Double> tmp = new HashMap<String, Double>(); int bins1x = size(); int bins2x = h2.size(); if (bins1x != bins2x) { System.out.println("Different histograms! Please use histograms with the same bin numbers in X"); return tmp; } double chi2 = 0; int nDf = 0; double sum1 = 0; double sum2 = 0; double sumw1 = 0; double sumw2 = 0; for (int i = 0; i < bins1x; i++) { double bin1 = getY(i); double bin2 = h2.getY(i); double e1 = getYupper(i); double e2 = h2.getYupper(i); if (e1 > 0) { bin1 *= bin1 / (e1 * e1); } else bin1 = 0; if (e2 > 0) { bin2 *= bin2 / (e2 * e2); } else bin2 = 0; // sum contents sum1 += bin1; sum2 += bin2; sumw1 += e1 * e1; sumw2 += e2 * e2; } //double sum = sum1 + sum2; if (sumw1 <= 0 || sumw2 <= 0) { System.out.println("Cannot compare histograms with all zero errors"); return tmp; } if (sum1 == 0 || sum2 == 0) { System.out.println("One histogram is empty!"); return tmp; } for (int i = 0; i < bins1x; i++) { double bin1 = getY(i); double bin2 = h2.getY(i); double e1 = getYupper(i); double e2 = h2.getYupper(i); //System.out.println(Double.toString(bin1)+" - "+Double.toString(bin2)); if (e1 > 0) bin1 *= bin1 / (e1 * e1); else bin1 = 0; if (e2 > 0) bin2 *= bin2 / (e2 * e2); else bin2 = 0; double binsum = bin1 + bin2; double delta = sum2 * bin1 - sum1 * bin2; if (binsum > 0) { chi2 += delta * delta / binsum; System.out.println(chi2); nDf++; } } chi2 /= (sum1 * sum2); tmp.put("chi2", chi2); tmp.put("ndf", (double) nDf); org.apache.commons.math3.distribution.ChiSquaredDistribution chi2Distribution = new org.apache.commons.math3.distribution.ChiSquaredDistribution( nDf); double prob = chi2Distribution.cumulativeProbability(chi2); tmp.put("p-value", 1.0 - prob); return tmp; } /** * Return the length of the data vector. * * @return length of the PlotPoint vector */ public int size() { return X.size(); } /** * Get array representing X-values * * @return array with X values */ public double[] getArrayX() { X.trimToSize(); return X.elements(); } /** * create a copy of this container. * * @param newtitle * new title */ public P1D copy(String newtitle) { P1D tmp = new P1D(newtitle); LinePars lppp = copyLinePars(lpp); tmp.setLinePars(lppp); tmp.setDimension(dimen); tmp.setXval(X.copy()); tmp.setYval(Y.copy()); if (dimen == 3) { tmp.setYE1upper(YE1upper.copy()); return tmp; } if (dimen == 4) { tmp.setYE1upper(YE1upper.copy()); tmp.setYE1down(YE1down.copy()); return tmp; } if (dimen == 6) { tmp.setYE1upper(YE1upper.copy()); tmp.setYE1down(YE1down.copy()); tmp.setXE1left(XE1left.copy()); tmp.setXE1right(XE1right.copy()); return tmp; } if (dimen == 10) { tmp.setYE1upper(YE1upper.copy()); tmp.setYE1down(YE1down.copy()); tmp.setXE1left(XE1left.copy()); tmp.setXE1right(XE1right.copy()); tmp.setYE2upper(YE2upper.copy()); tmp.setYE2down(YE2down.copy()); tmp.setXE2left(XE2left.copy()); tmp.setXE2right(XE2right.copy()); return tmp; } return tmp; } /** * Set left second-level errors * @param xE2left */ public void setXE2left(DoubleArrayList xE2left) { this.XE2left = xE2left; } /** * Set right second-level errors * @param xE2right */ public void setXE2right(DoubleArrayList xE2right) { this.XE2right = xE2right; } /** * Write a P0D object to a serialized file * * @param name * serialized file name for output. * * @return zero if no errors */ public int writeSerialized(String name) { return jhplot.io.Serialized.write(this, name); } /** * Read a P1D object from a serialized file * * @param name * serialized file name for input. Can be URL if starts from * http. * * @return new P1D object */ public P1D readSerialized(String name) { return (P1D) jhplot.io.Serialized.read(name); } /** * Construct a P1D from a file on the we web. The file should contain 2, or * 4, or 6, or 10 columns: 1) x,y: data without any errors 2) x,y, y(upper), * y(lower) - data with 1st level errors on Y 3) x,y, x(left), x(right), * y(upper), y(lower) - data with 1st level errors on X and Y 4) x,y, * x(left), x(right), y(upper), y(lower), x(leftSys), x(rightSys), * y(upperSys), y(lowerSys) - data with X and Y and 1st and 2nd level * errors. Comments lines starting with "#" and "*" are ignored. * * @param title * Title of the container * @param url * URL location */ public P1D(String title, URL url) { this(title); read(url); } /** * Construct a P1D from a file on the we web. The file should contain 2, or * 4, or 6, or 10 columns: 1) x,y: data without any errors 2) x,y, y(upper), * y(lower) - data with 1st level errors on Y 3) x,y, x(left), x(right), * y(upper), y(lower) - data with 1st level errors on X and Y 4) x,y, * x(left), x(right), y(upper), y(lower), x(leftSys), x(rightSys), * y(upperSys), y(lowerSys) - data with X and Y and 1st and 2nd level * errors. Comments lines starting with "#" and "*" are ignored. * * @param url * URL location */ public P1D(URL url) { this("None"); read(url); } /** * Read data using 10-column format. Each line corresponds to a new data * point. * * @param br * BufferedReader * @return 0 if no errors */ public int read(BufferedReader br) { String line; clear(); try { while ((line = br.readLine()) != null) { line = line.trim(); if (!line.startsWith("#") && !line.startsWith("*")) { StringTokenizer st = new StringTokenizer(line); int ncount = st.countTokens(); // number of words clear(); setDimension(ncount); double[] snum = new double[ncount]; if (ncount != 2 && ncount != 4 && ncount != 6 && ncount != 10) { ErrorMessage("Error in reading the file:\n" + Integer.toString(ncount) + " entries per line is found!"); } // split this line int mm = 0; while (st.hasMoreTokens()) { // make sure there is stuff // to get String tmp = st.nextToken(); // read double double dd = 0; try { dd = Double.parseDouble(tmp.trim()); } catch (NumberFormatException e) { ErrorMessage("Error in reading the line " + Integer.toString(mm + 1)); return 3; } snum[mm] = dd; mm++; } // end loop over each line if (ncount == 2) add(snum[0], snum[1]); if (ncount == 3) add(snum[0], snum[1], snum[2], snum[2]); if (ncount == 4) add(snum[0], snum[1], snum[2], snum[3]); if (ncount == 6) add(snum[0], snum[1], snum[2], snum[3], snum[4], snum[5]); if (ncount == 10) add(snum[0], snum[1], snum[2], snum[3], snum[4], snum[5], snum[6], snum[7], snum[8], snum[9]); } // skip # } } catch (IOException e) { // TODO Auto-generated catch block return -1; // e.printStackTrace(); } return 0; } /** * Read data from URL. Use a space to separate values in columns and new * line to put new data point. * * @param url * URL location of input file */ public int read(URL url) { BufferedReader is = PReader.read(url); if (is == null) return 1; return read(is); } /** * Read P1D from a GZiped file. It can read URL if the string starts from * http or ftp, otherwise a file on the file system is assumed. * <p> * Use a space to separate values in columns and new line to put new row. * * @param sfile * File name with input (extension .gz) * @return zero if success */ public int readGZip(String sfile) { BufferedReader is = PReader.readGZip(sfile); if (is == null) return 1; return read(is); } /** * Read P1D from a file. * <p> * The old content will be lost. The file should contain 2, or 4, or 6, or * 10 columns: 1) x,y: data without any errors 2) x,y, y(upper), y(lower) - * data with 1st level errors on Y 3) x,y, x(left), x(right), y(upper), * y(lower) - data with 1st level errors on X and Y 4) x,y, x(left), * x(right), y(upper), y(lower), x(leftSys), x(rightSys), y(upperSys), * y(lowerSys) - data with X and Y and 1st and 2nd level errors. Comment * lines starting with "#" and "*" are ignored. It can read URL if the * string starts from http or ftp, otherwise a file on the file system is * assumed. * * @param sfile * File name with input. If the string starts from http or ftp, * otherwise a file on the file system is assumed. * @return zero if success */ public int read(String sfile) { BufferedReader is = PReader.read(sfile); if (is == null) return 1; return read(is); } /** * Read P1D from a Zipped file. The old content will be lost. The file * should contain 2, or 4, or 6, or 10 columns: 1) x,y: data without any * errors 2) x,y, y(upper), y(lower) - data with 1st level errors on Y 3) * x,y, x(left), x(right), y(upper), y(lower) - data with 1st level errors * on X and Y 4) x,y, x(left), x(right), y(upper), y(lower), x(leftSys), * x(rightSys), y(upperSys), y(lowerSys) - data with X and Y and 1st and 2nd * level errors. Comment lines starting with "#" and "*" are ignored. * * @param sfile * File name with input (extension zip) * @return zero if success */ public int readZip(String sfile) { // clear all data clear(); try { ZipFile zf = new ZipFile(sfile); Enumeration entries = zf.entries(); BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); while (entries.hasMoreElements()) { ZipEntry ze = (ZipEntry) entries.nextElement(); // System.out.println("Read " + ze.getName() + "?"); String inputLine = input.readLine(); if (inputLine.equalsIgnoreCase("yes")) { long size = ze.getSize(); if (size > 0) { // System.out.println("Length is " + size); BufferedReader br = new BufferedReader(new InputStreamReader(zf.getInputStream(ze))); read(br); // read data br.close(); } } } } catch (FileNotFoundException e) { ErrorMessage("File not found:" + sfile); e.printStackTrace(); return 1; } catch (IOException e) { e.printStackTrace(); return 2; } return 0; } /** * Make a new data holder with the same title from the current one. * * @return new data holder */ public P1D copy() { return copy(this.title); } /** * Smooth P1D data points in either X or Y. * <p> * It is smoothed by averaging over a moving window of a size specified by * the method parameter: if the value of the parameter is <i>k</i> then the * width of the window is <i>2*k + 1</i>. If the window runs off the end of * the P1D only those values which intersect the histogram are taken into * consideration. The smoothing may optionally be weighted to favor the * central value using a "triangular" weighting. For example, for a value of * <i>k</i> equal to 2 the central bin would have weight 1/3, the adjacent * bins 2/9, and the next adjacent bins 1/9. Errors are kept the same as * before. * * @param axis * axis to which smoothing is applied (axis=0 for X, axis=1 for * Y) * * @param isWeighted * Whether values in X or Y will be weighted using a triangular * weighting scheme favoring bins near the central bin. * @param k * The smoothing parameter which must be non-negative. If zero, * the histogram object will be returned with no smoothing * applied. * @return A smoothed version of P1D. */ public P1D operSmooth(int axis, boolean isWeighted, int k) { if (axis != 0 && axis != 1) { ErrorMessage("Axis variable should be 0 or 1!"); return this; } SHisto sh = new SHisto(size(), getMin(axis), getMax(axis), 1); double[] hh = null; if (axis == 0) hh = getArrayX(); if (axis == 1) hh = getArrayY(); sh.setBins(hh); sh = sh.getSmoothed(isWeighted, k); for (int i = 0; i < size(); i++) { if (axis == 0) setQuick(i, sh.getBinsFirstBand(i), getQuickY(i)); if (axis == 1) setQuick(i, getQuickX(i), sh.getBinsFirstBand(i)); } return this; } /** * Computes a Gaussian smoothed version of P1D. Smoothing can be done either * to X or Y * * <p> * Each band of the P1D is smoothed by discrete convolution with a kernel * approximating a Gaussian impulse response with the specified standard * deviation. * * @param axis * axis to which smoothing is applied (axis=0 for X, axis=1 for * Y) * * @param standardDeviation * The standard deviation of the Gaussian smoothing kernel which * must be non-negative or an * <code>IllegalArgumentException</code> will be thrown. If zero, * the P1D object will be returned with no smoothing applied. * @return A Gaussian smoothed version of the histogram. * */ public P1D operSmoothGauss(int axis, double standardDeviation) { if (axis != 0 && axis != 1) { ErrorMessage("Axis variable should be 0 or 1!"); return this; } SHisto sh = new SHisto(size(), getMin(axis), getMax(axis), 1); double[] hh = null; if (axis == 0) hh = getArrayX(); if (axis == 1) hh = getArrayY(); sh.setBins(hh); sh = sh.getGaussianSmoothed(standardDeviation); for (int i = 0; i < size(); i++) { if (axis == 0) setQuick(i, sh.getBinsFirstBand(i), getY(i)); if (axis == 1) setQuick(i, getX(i), sh.getBinsFirstBand(i)); } return this; } /** * Return P1D array which contains 2nd level errors (or systematic errors) * evaluated from an array of P1D data holders. This means that this method * returns a P1D , but now it has systematic errors evaluated from the input * array. All systematic variations are treated independently and thus are * added in quadrature. Use this method for evaluation of systematic * uncertainties. This function implies only for Y values. * * @param p1darray * Input P1D arrays * @return output P1D arrays with the same values and systematic errors, but * systematic errors are evaluated from the input set of P1D objects */ public P1D getSys(P1D[] p1darray) { P1D tmp = new P1D("systematics"); tmp.setDimension(10); for (int i = 0; i < size(); i++) { // estimate systematics double d = 0; double up = 0; double down = 0; for (int m = 0; m < p1darray.length; m++) { d = p1darray[m].getQuickY(i) - getQuickY(i); if (d > 0) up = up + d * d; if (d < 0) down = down + d * d; } up = Math.sqrt(up); down = Math.sqrt(down); // System.out.println(up); if (p1darray[0].dimension() == 2) tmp.add(getX(i), getY(i), 0, 0, 0, 0, 0, 0, up, down); if (p1darray[0].dimension() == 3) tmp.add(getX(i), getY(i), 0, 0, getYupper(i), 0, 0, 0, up, down); if (p1darray[0].dimension() == 4) tmp.add(getX(i), getY(i), 0, 0, getYupper(i), getYlower(i), 0, 0, up, down); if (p1darray[0].dimension() == 6) tmp.add(getX(i), getY(i), getXleft(i), getXright(i), getYupper(i), getYlower(i), 0, 0, up, down); if (p1darray[0].dimension() == 10) tmp.add(getX(i), getY(i), getXleft(i), getXright(i), getYupper(i), getYlower(i), getXleftSys(i), getXrightSys(i), up, down); } return tmp; } /** * Add 1st and 2nd level in quadrature and attribute the combined error to * 1st level error. This is useful to simplify presentation of data, but * this certainly not always correct approach. The original object is * modified. * * <p> * Dimension should be 10. * * @param axis * is 0 for X errors, 1 for Y errors */ public void combineErr(int axis) { if (dimension() != 10) { ErrorMessage("The dimension for this operation must be 10. Exit now."); return; } for (int i = 0; i < size(); i++) { if (axis == 0) { double eLeft = Math.sqrt(getXleft(i) * getXleft(i) + getXleftSys(i) * getXleftSys(i)); double eRight = Math.sqrt(getXright(i) * getXright(i) + getXrightSys(i) * getXrightSys(i)); setQuick(i, getX(i), getY(i), eLeft, eRight, getYupper(i), getYlower(i), 0, 0, getYupperSys(i), getYlowerSys(i)); } if (axis == 1) { double eUpper = Math.sqrt(getYupper(i) * getYupper(i) + getYupperSys(i) * getYupperSys(i)); double eLower = Math.sqrt(getYlower(i) * getYlower(i) + getYlowerSys(i) * getYlowerSys(i)); setQuick(i, getQuickX(i), getQuickY(i), getXleft(i), getXright(i), eUpper, eLower, getXleftSys(i), getXrightSys(i), 0, 0); } } } /** * Return P1D array with weighted average of several measurements. This is a * standard weighted least-squares procedure to combine experimental data * with errors. Measurements represented by input P1Ds are assumed to be * uncorrelated. Errors in X positions are not affected during averaging. * Only 1st and 2nd level errors on Y are used. It is also assumed that * upper and lower 1st-level errors on Y have the same size. In case if the * are not the same, I average them (and print error!) * * @param p1darray * Input P1D arrays. They will be added to the original P1D * @return ouput P1D arrays with the same values and systematical errors, * but systematical errors are evaluated from the input set of P1D * objects */ public P1D addAndAverage(P1D[] p1darray) { if (dimen == 2) { return this; } P1D tmp = new P1D("Average"); tmp.setDimension(10); for (int i = 0; i < size(); i++) { double wa1 = 1.0; if (dimen == 3) { if (getYupper(i) != 0) wa1 = 1.0 / (getYupper(i) * getYupper(i)); } double wa2 = 1.0; if (dimen > 3) { if (getYlower(i) != 0) wa2 = 1.0 / (getYlower(i) * getYlower(i)); } double wsa1 = 1.0; double wsa2 = 1.0; if (dimen > 9) { if (getYupperSys(i) != 0) wsa1 = 1.0 / (getYupperSys(i) * getYupperSys(i)); if (getYlowerSys(i) != 0) wsa2 = 1.0 / (getYlowerSys(i) * getYlowerSys(i)); } if (dimen > 3) { if (getYupper(i) != getYlower(i)) { System.out.println("Check! Upper and Lower error for Y should be the same!"); System.out.println("Now I'm averaging them.."); wa1 = 0.5 * (wa1 + wa2); } } double ynew = wa1 * getY(i); double wsum = wa1; double wsum1 = wsa1; double wsum2 = wsa2; for (int m = 0; m < p1darray.length; m++) { if (size() != p1darray[m].size()) { System.out.println("input P1D arrays have diferent size!"); return this; } double w1 = 1.0; if (dimen > 2) if (p1darray[m].getYupper(i) != 0) w1 = 1.0 / (p1darray[m].getYupper(i) * p1darray[m].getYupper(i)); double w2 = 1.0; if (dimen > 3) if (p1darray[m].getYlower(i) != 0) w2 = 1.0 / (p1darray[m].getYlower(i) * p1darray[m].getYlower(i)); double ws1 = 1.0; if (dimen > 9) if (p1darray[m].getYupperSys(i) != 0) ws1 = 1.0 / (p1darray[m].getYupperSys(i) * p1darray[m].getYupperSys(i)); double ws2 = 1.0; if (dimen > 9) if (p1darray[m].getYlowerSys(i) != 0) ws2 = 1.0 / (p1darray[m].getYlowerSys(i) * p1darray[m].getYlowerSys(i)); if (dimen > 3) if (p1darray[m].getYupper(i) != p1darray[m].getYlower(i)) { System.out.println("Check! Upper and Lower error for Y should be the same!"); System.out.println("Now I'm averaging them.."); w1 = 0.5 * (w1 + w2); } ynew = ynew + w1 * p1darray[m].getY(i); wsum = wsum + w1; wsum1 = wsum1 + ws1; wsum2 = wsum2 + ws2; } // end loop over input P1D ynew = ynew / wsum; wsum = 1.0 / Math.sqrt(wsum); wsum1 = 1.0 / Math.sqrt(wsum1); wsum2 = 1.0 / Math.sqrt(wsum2); if (dimen > 9) tmp.add(getX(i), ynew, getXleft(i), getXright(i), wsum, wsum, getXleftSys(i), getXrightSys(i), wsum1, wsum2); if (dimen == 2 || dimen == 3 || dimen == 4) tmp.add(getX(i), ynew, 0, 0, wsum, wsum, 0, 0, wsum1, wsum2); } return tmp; } /** * Get array representing X-left errors * * @return array with X left errors */ public double[] getArrayXleft() { XE1left.trimToSize(); return XE1left.elements(); } /** * Get array representing X-right errors * * @return array with X right errors */ public double[] getArrayXright() { XE1right.trimToSize(); return XE1right.elements(); } /** * Get array representing X-right 2nd level errors * * @return array with X right 2nd level errors */ public double[] getArrayXrightSys() { XE2right.trimToSize(); return XE2right.elements(); } /** * Get array representing X-left 2nd level errors * * @return array with X left 2nd level values */ public double[] getArrayXleftSys() { XE2left.trimToSize(); return XE2left.elements(); } /** * Get array representing Y-values * * @return array with Y values */ public double[] getArrayY() { Y.trimToSize(); return Y.elements(); } /** * Return a specific X-value. This function returns POSINF (1e300) if index * i falls beyond the valid range. * * @param i * index of the array * @return the value of x at index i */ public double getX(int i) { return X.get(i); } /** * Return a specific left error on X-value. if index i falls beyond the * valid range. * * @param i * index of the array * @return the value of x at index i */ public double getXleft(int i) { return XE1left.get(i); } /** * Return a specific right error on X-value. if index i falls beyond the * valid range. * * @param i * index of the array * @return the value of x at index i */ public double getXright(int i) { return XE1right.get(i); } /** * Return a specific left error on X-value (systematic error). if index i * falls beyond the valid range. * * @param i * index of the array * @return the value of x at index i */ public double getXleftSys(int i) { return XE2left.get(i); } /** * Return a specific right error on X-value (systematic error). if index i * falls beyond the valid range. * * @param i * index of the array * @return the value of x at index i */ public double getXrightSys(int i) { return XE2right.get(i); } /** * Return a specific Y-value. This function returns POSINF (1e300) if index * falls beyond the valid range. * * @param i * index of the array * @return the value of y at index i */ public double getY(int i) { return Y.get(i); } /** * Return (symmetric) error on Y-value. This is equivalent to getYupper(). * Errors for Y can be added as add(X,Y,Error). * @param i * index of the array * @return error value on y at index i */ public double getErr(int i) { return getYupper(i); } /** * Return a specific Y-value quickly (no bound check). * * @param i * index of the array * @return the value of y at index i */ public double getQuickY(int i) { return Y.getQuick(i); } /** * Return a specific X-value quickly (no bound check). * * @param i * index of the array * @return the value of x at index i */ public double getQuickX(int i) { return X.getQuick(i); } /** * Return a specific upper error on Y-value. This function returns POSINF * (1e300) if index i falls beyond the valid range. * * @param i * index of the array * @return the upper error on value of y at index i */ public double getYupper(int i) { return YE1upper.get(i); } /** * Return error (uncertainty) on the Y value. * This is equivalent to getYupper(). It is assumed that upperl and lower error is the same. * @param i * index of the array * @return error on value of Y at index i */ public double getError(int i) { return YE1upper.get(i); } /** * Return a specific lower error on Y-value. This function returns POSINF * (1e300) if index i falls beyond the valid range. * * @param i * index of the array * @return the value of y at index i */ public double getYlower(int i) { return YE1down.get(i); } /** * Get array representing Y lower errors * * @return array with Y lower error */ public double[] getArrayYlower() { YE1down.trimToSize(); if (YE1down == null) ErrorMessage("This container was not initialized with >6 dimensions!"); return YE1down.elements(); } /** * Get array representing Y lower 2nd level errors * * @return array with Y lower 2nd level error */ public double[] getArrayYlowerSys() { YE2down.trimToSize(); if (YE2down == null) ErrorMessage("This container was not initialized with >6 dimensions!"); return YE2down.elements(); } /** * Return a specific systematical upper error on Y-value. This function * returns POSINF (1e300) if index i falls beyond the valid range. * * @param i * index of the array * @return the value of y at index i */ public double getYupperSys(int i) { return YE2upper.get(i); } /** * Get array representing Y upper errors * * @return array with Y upper error */ public double[] getArrayYupper() { YE1upper.trimToSize(); if (YE1upper == null) ErrorMessage("This container was not initialized with >6 dimensions!"); return YE1upper.elements(); } /** * Get array representing (symmetric) error on Y. This is equivalent to getArrayYupper(). * * @return array with errors on the Y values. */ public double[] getArrayErr() { return getArrayYupper(); } /** * Returns the dimension of this P1D holder. The convention is: 2: only x * and y 3: x,y and symmetrical stat error on y 4: only x, y, y(up), y(down) * 6: only x, y, x(up), x(down) y(up), y(down) > the rest * * @return dimension of the P1D */ public int dimension() { return dimen; } /** * Returns the dimension of this P1D holder. The convention is: 2: only x * and y 3: x,y and symmetrical stat error on y 4: only x, y, y(up), y(down) * 6: only x, y, x(up), x(down) y(up), y(down) > the rest * * @return dimension of the P1D */ public int getDimension() { return dimen; } /** * Return a specific total lower error on Y-value. This function returns * POSINF (1e300) if index i falls beyond the valid range. * * @param i * index of the array * @return the value of y at index i */ public double getYlowerSys(int i) { return YE2down.get(i); } /** * Get array representing Y upper 2nd level errors * * @return array with Y upper 2nd level error */ public double[] getArrayYupperSys() { YE2upper.trimToSize(); if (YE2upper == null) ErrorMessage("This container was not initialized with 10 dimensions!"); return YE2upper.elements(); } /** * Get IDataPointSet. If systematical errors included, they are added in * quadrature with statistical errors. * * @return IDataPointSet made of P1D */ public IDataPointSet getIDataPointSet() { IAnalysisFactory af = IAnalysisFactory.create(); ITree tree = af.createTreeFactory().create(); IDataPointSetFactory dpsf = af.createDataPointSetFactory(tree); IDataPointSet fDps2D = dpsf.create(getTitle(), getTitle(), 2); fillIDataPointSet(fDps2D); return fDps2D; } /** * Fill IDataPointSet. If systematical errors included, they are added in * quadrature with statistical errors. * * @return IDataPointSet made of P1D */ public void fillIDataPointSet(IDataPointSet fDps2D) { // System.out.println("DEBUG=conversion"); double sup, slow, xleft, xright; // Fill the data point set with the generated data values. //System.out.println("Size in fillIDataPointSet="); //System.out.println(dimen); if (dimen == 2) { for (int i = 0; i < size(); i++) { fDps2D.addPoint(); fDps2D.point(i).coordinate(0).setValue(X.getQuick(i)); fDps2D.point(i).coordinate(1).setValue(Y.getQuick(i)); } } if (dimen == 3) { for (int i = 0; i < size(); i++) { fDps2D.addPoint(); fDps2D.point(i).coordinate(0).setValue(X.getQuick(i)); fDps2D.point(i).coordinate(1).setValue(Y.getQuick(i)); fDps2D.point(i).coordinate(1).setErrorPlus(YE1upper.getQuick(i)); fDps2D.point(i).coordinate(1).setErrorMinus(YE1upper.getQuick(i)); } } if (dimen == 4) { for (int i = 0; i < size(); i++) { fDps2D.addPoint(); fDps2D.point(i).coordinate(0).setValue(X.getQuick(i)); fDps2D.point(i).coordinate(1).setValue(Y.getQuick(i)); fDps2D.point(i).coordinate(1).setErrorPlus(YE1upper.getQuick(i)); fDps2D.point(i).coordinate(1).setErrorMinus(YE1down.getQuick(i)); } } if (dimen == 6) { for (int i = 0; i < size(); i++) { fDps2D.addPoint(); fDps2D.point(i).coordinate(0).setValue(X.getQuick(i)); fDps2D.point(i).coordinate(0).setErrorPlus(XE1right.getQuick(i)); fDps2D.point(i).coordinate(0).setErrorMinus(XE1left.getQuick(i)); fDps2D.point(i).coordinate(1).setValue(Y.getQuick(i)); fDps2D.point(i).coordinate(1).setErrorPlus(YE1upper.getQuick(i)); fDps2D.point(i).coordinate(1).setErrorMinus(YE1down.getQuick(i)); } } if (dimen == 10) { for (int i = 0; i < size(); i++) { fDps2D.addPoint(); fDps2D.point(i).coordinate(0).setValue(X.getQuick(i)); fDps2D.point(i).coordinate(1).setValue(Y.getQuick(i)); sup = Math.sqrt(getYupperSys(i) * getYupperSys(i) + getYupper(i) * getYupper(i)); slow = Math.sqrt(getYlowerSys(i) * getYlowerSys(i) + getYlower(i) * getYlower(i)); fDps2D.point(i).coordinate(1).setErrorPlus(sup); fDps2D.point(i).coordinate(1).setErrorMinus(slow); // errors on X if (getXleft(i) != 0 && getXleftSys(i) != 0) { xleft = Math.sqrt(getXleftSys(i) * getXleft(i) + getXright(i) * getXright(i)); fDps2D.point(i).coordinate(0).setErrorMinus(xleft); } if (getXright(i) != 0 && getXrightSys(i) != 0) { xright = Math.sqrt(getXleftSys(i) * getXleft(i) + getXright(i) * getXright(i)); fDps2D.point(i).coordinate(0).setErrorPlus(xright); } } } } /** * Returns the maximum value in the range. * * @param axis * defines to which axis this function applies (0=X; 1=Y); * @return the maximum value. */ public double getMax(int axis) { if (axis == 0) return Descriptive.max(X); if (axis == 1) return Descriptive.max(Y); return 0; } /** * Returns the index of maximum value in the range. * * @param axis * defines to which axis this function applies (0=X; 1=Y); * @return index of maximum value. */ public int getMaxIndex(int axis) { if (axis != 0 && axis != 1) { ErrorMessage("Axis variable should be 0 or 1!"); } double[] values = null; if (axis == 0) values = getArrayX(); if (axis == 1) values = getArrayY(); int index = DoubleArray.maxIndex(values); return index; } /** * Returns the minimum value in the range. Careful, no error checking on the * value of axis, which should be less than N_AXES, defined in * GraphSettings. * * @param axis * defines to which axis this function applies (0=X; 1=Y); * @return the minimum value. */ public double getMin(int axis) { if (axis == 0 && X.size() > 0) return Descriptive.min(X); if (axis == 1 && Y.size() > 0) return Descriptive.min(Y); return 0; } /** * Returns the index of minimum value in the range. * * @param axis * defines to which axis this function applies (0=X; 1=Y); * @return index of maximum value. */ public int getMinIndex(int axis) { if (axis != 0 && axis != 1) { ErrorMessage("Axis variable should be 0 or 1!"); } double[] values = null; if (axis == 0) values = getArrayX(); if (axis == 1) values = getArrayY(); int index = DoubleArray.minIndex(values); return index; } /** * Remove a (X,Y) value at a given index * @param index index */ public void removeAt(int index) { X.remove(index); Y.remove(index); if (dimen == 3) { YE1upper.remove(index); return; } if (dimen == 4) { YE1upper.remove(index); YE1down.remove(index); return; } ; if (dimen == 6) { YE1upper.remove(index); YE1down.remove(index); XE1left.remove(index); XE1right.remove(index); return; } ; if (dimen == 10) { YE1upper.remove(index); YE1down.remove(index); XE1left.remove(index); XE1right.remove(index); YE2upper.remove(index); YE2down.remove(index); YE2upper.remove(index); YE2down.remove(index); return; } ; return; } /** * Obtain a new PD1 in the range between Min and Max indexes. Min and Max are * included. All errors will be copied to a new P1D. For example, * getRange(2,2) will return a P1D at index=2 (only one point with errors). * * @param IndexMin * Min index * @param IndexMax * Max index * @return a new P1D with the value in the range. * */ public P1D range(int IndexMin, int IndexMax) { P1D tmp = new P1D(getTitle()); LinePars lppp = copyLinePars(lpp); tmp.setLinePars(lppp); tmp.setDimension(dimen); tmp.setXval((DoubleArrayList) X.partFromTo(IndexMin, IndexMax)); tmp.setYval((DoubleArrayList) Y.partFromTo(IndexMin, IndexMax)); if (dimen == 2) return tmp; if (dimen == 3) { tmp.setYE1upper((DoubleArrayList) YE1upper.partFromTo(IndexMin, IndexMax)); return tmp; } if (dimen == 4) { tmp.setYE1upper((DoubleArrayList) YE1upper.partFromTo(IndexMin, IndexMax)); tmp.setYE1down((DoubleArrayList) YE1down.partFromTo(IndexMin, IndexMax)); return tmp; } if (dimen == 6) { tmp.setYE1upper((DoubleArrayList) YE1upper.partFromTo(IndexMin, IndexMax)); tmp.setYE1down((DoubleArrayList) YE1down.partFromTo(IndexMin, IndexMax)); tmp.setXE1left((DoubleArrayList) XE1left.partFromTo(IndexMin, IndexMax)); tmp.setXE1right((DoubleArrayList) XE1right.partFromTo(IndexMin, IndexMax)); return tmp; } if (dimen == 10) { tmp.setYE1upper((DoubleArrayList) YE1upper.partFromTo(IndexMin, IndexMax)); tmp.setYE1down((DoubleArrayList) YE1down.partFromTo(IndexMin, IndexMax)); tmp.setXE1left((DoubleArrayList) XE1left.partFromTo(IndexMin, IndexMax)); tmp.setXE1right((DoubleArrayList) XE1right.partFromTo(IndexMin, IndexMax)); tmp.setYE2upper((DoubleArrayList) YE2upper.partFromTo(IndexMin, IndexMax)); tmp.setYE2down((DoubleArrayList) YE2down.partFromTo(IndexMin, IndexMax)); tmp.setXE2left((DoubleArrayList) XE2left.partFromTo(IndexMin, IndexMax)); tmp.setXE2right((DoubleArrayList) XE2right.partFromTo(IndexMin, IndexMax)); return tmp; } return tmp; } /** * Calculate derivative for X-Y data points. It is used to express how fast * a Y-values are changing, and are therefore related, mathematically, to * the slope of a line. It is calculate as: getY(i+1)-getY(i) / * getX(i+1)-getX(i), assuming that all points are ordered in X. For a * series of data X-Y points, you can join each pair of adjacent points with * a straight line and a slope can be associated with each such line * segment. * <p> * Data points can have errors (statistical), with upper and lower error on Y (dimen=4). *Statistical uncertainties on Y are propagated and included into * the final P1D with derivatives. Second-level errors are ignored. * * @return a new P1D with derivative in each data point. */ public P1D derivative() { P1D tmp = new P1D("Derivative of " + title); if (dimen == 4) { for (int i = 0; i < size() - 1; i++) { double dx = getQuickX(i + 1) - getQuickX(i); double dy = getQuickY(i + 1) - getQuickY(i); double dyUP = (getQuickY(i + 1) + getYupper(i + 1)) - getQuickY(i); double dyDW = (getQuickY(i + 1) - getYlower(i + 1)) - getQuickY(i); double slope = 0; double slopeUP = 0; double slopeDW = 0; if (dx != 0) { slope = dy / dx; slopeUP = dyUP / dx; slopeDW = dyDW / dx; } tmp.add(getX(i), slope, 0, 0, slopeUP, slopeDW, 0, 0, 0, 0); } } ; if (dimen != 4) { for (int i = 0; i < size() - 1; i++) { double dx = getQuickX(i + 1) - getQuickX(i); double dy = getQuickY(i + 1) - getQuickY(i); double slope = 0; if (dx != 0) { slope = dy / dx; } tmp.add(getX(i), slope); } } ; return tmp; } /** * Construct P1D removing a range of values defined by Min and Max. All * errors will be copied to a new P1D. TMin and max are included in the * final output. * * @param axis * if axis=0, applied for X, if axis=1, applied for Y. * @param Min * Min value * @param Max * Max value * @return a new P1D */ public P1D rangeCut(int axis, double Min, double Max) { if (axis != 0 && axis != 1) { ErrorMessage("Axis variable should be 0 or 1!"); } P1D tmp = new P1D(title); tmp.setLinePars(lpp); for (int i = 0; i < size(); i++) { if (axis == 0) { if (getX(i) < Min || getX(i) > Max) if (dimen == 2) tmp.add(getX(i), getY(i)); else if (dimen == 3) tmp.add(getX(i), getY(i), getYupper(i)); else if (dimen == 4) tmp.add(getX(i), getY(i), getYupper(i), getYlower(i)); else if (dimen > 4) tmp.add(getX(i), getY(i), getXleft(i), getXright(i), getYupper(i), getYlower(i), getXleftSys(i), getXrightSys(i), getYupperSys(i), getYlowerSys(i)); } if (axis == 1) { if (getY(i) < Min || getY(i) > Max) if (dimen == 2) tmp.add(getX(i), getY(i)); else if (dimen == 3) tmp.add(getX(i), getY(i), getYupper(i)); else if (dimen == 4) tmp.add(getX(i), getY(i), getYupper(i), getYlower(i)); else tmp.add(getX(i), getY(i), getXleft(i), getXright(i), getYupper(i), getYlower(i), getXleftSys(i), getXrightSys(i), getYupperSys(i), getYlowerSys(i)); } } return tmp; } /** * Sorting the original array using either X or Y values. The sorting done in increasing order. * We use exchange sort method. Currently supports dimensions 2 (X-Y), 3 (X-Y,errror on Y), 4 (X-Y, errors upper and lower on Y). * @param axis * if axis=0, sorting applied for X, if axis=1, sorting is applied for Y. */ public void sort(int axis) { if (axis != 0 && axis != 1) { ErrorMessage("Axis variable should be 0 or 1!"); } // use exchange sort if (axis == 0) { if (dimen == 2) { double tempX; double tempY; for (int i = 0; i < size() - 1; i++) { for (int j = i + 1; j < size(); j++) { if (X.getQuick(i) > X.getQuick(j)) { tempX = X.getQuick(i); tempY = Y.getQuick(i); X.setQuick(i, getQuickX(j)); Y.setQuick(i, getQuickY(j)); X.setQuick(j, tempX); Y.setQuick(j, tempY); } ; } } } if (dimen == 3) { double tempX; double tempY; double tempEY; for (int i = 0; i < size() - 1; i++) { for (int j = i + 1; j < size(); j++) { if (X.getQuick(i) > X.getQuick(j)) { tempX = X.getQuick(i); // swap tempY = Y.getQuick(i); // swap tempEY = YE1upper.getQuick(i); X.setQuick(i, getQuickX(j)); Y.setQuick(i, getQuickY(j)); YE1upper.setQuick(i, YE1upper.getQuick(j)); X.setQuick(j, tempX); Y.setQuick(j, tempY); YE1upper.setQuick(j, tempEY); } ; } } } if (dimen == 4) { double tempX; double tempY; double tempEYu; double tempEYd; for (int i = 0; i < size() - 1; i++) { for (int j = i + 1; j < size(); j++) { if (X.getQuick(i) > X.getQuick(j)) { tempX = X.getQuick(i); // swap tempY = Y.getQuick(i); // swap tempEYu = YE1upper.getQuick(i); tempEYd = YE1down.getQuick(i); X.setQuick(i, getQuickX(j)); Y.setQuick(i, getQuickY(j)); YE1upper.setQuick(i, YE1upper.getQuick(j)); YE1down.setQuick(i, YE1down.getQuick(j)); X.setQuick(j, tempX); Y.setQuick(j, tempY); YE1upper.setQuick(j, tempEYu); YE1down.setQuick(j, tempEYd); } ; } } } } if (axis == 1) { if (dimen == 2) { double tempX; double tempY; for (int i = 0; i < size() - 1; i++) { for (int j = i + 1; j < size(); j++) { if (Y.getQuick(i) > Y.getQuick(j)) { tempX = X.getQuick(i); // swap tempY = Y.getQuick(i); // swap X.setQuick(i, getQuickX(j)); Y.setQuick(i, getQuickY(j)); X.setQuick(j, tempX); Y.setQuick(j, tempY); } ; } } } if (dimen == 3) { double tempX; double tempY; double tempEY; for (int i = 0; i < size() - 1; i++) { for (int j = i + 1; j < size(); j++) { if (Y.getQuick(i) > Y.getQuick(j)) { tempX = X.getQuick(i); // swap tempY = Y.getQuick(i); // swap tempEY = YE1upper.getQuick(i); X.setQuick(i, getQuickX(j)); Y.setQuick(i, getQuickY(j)); YE1upper.setQuick(i, YE1upper.getQuick(j)); X.setQuick(j, tempX); Y.setQuick(j, tempY); YE1upper.setQuick(j, tempEY); } ; } } } if (dimen == 4) { double tempX; double tempY; double tempEYu; double tempEYd; for (int i = 0; i < size() - 1; i++) { for (int j = i + 1; j < size(); j++) { if (Y.getQuick(i) > Y.getQuick(j)) { tempX = X.getQuick(i); // swap tempY = Y.getQuick(i); // swap tempEYu = YE1upper.getQuick(i); tempEYd = YE1down.getQuick(i); X.setQuick(i, getQuickX(j)); Y.setQuick(i, getQuickY(j)); YE1upper.setQuick(i, YE1upper.getQuick(j)); YE1down.setQuick(i, YE1down.getQuick(j)); X.setQuick(j, tempX); Y.setQuick(j, tempY); YE1upper.setQuick(j, tempEYu); YE1down.setQuick(j, tempEYd); } ; } } } } return; } /** * Integrate P1D between two indices (between 1 and max index) * * @param IndexMin * Min minimal index for integration starting from 1 (included to * integration) * @param IndexMax * Max maximal index for integration (included to integration) * @return integral (sum of all Y-values) */ public double integral(int IndexMin, int IndexMax) { int Nbins = size(); if (IndexMin > IndexMax) { ErrorMessage("Wrong index!"); return -1; } if (IndexMin < 1 || IndexMax > Nbins) { ErrorMessage("Wrong index!"); return -1; } double sum = 0.0; for (int i = IndexMin - 1; i < IndexMax; i++) { sum += getQuickY(i); } return sum; } /** * Integrate P1D (sum up all Y values) * * @return integral (sum of all Y-values) */ public double integral() { double sum = 0.0; for (int i = 0; i < size(); i++) { sum += getQuickY(i); } return sum; } /** * Returns variance for X-values. This is a measure of how far a set of * numbers are spread out from each other. * * @return variance for X values **/ public double varianceX() { double var; int degrees = (size() - 1); int m = size(); double c; double s; c = 0; s = 0; for (int k = 0; k < m; k++) s += getQuickX(k); s = s / m; for (int k = 0; k < m; k++) c += (getQuickX(k) - s) * (getQuickX(k) - s); var = c / degrees; return var; } /** * Standard deviation of values X. * * @return standard deviation of values X */ public double stddeviationX() { return Math.sqrt(varianceX()); } /** * Standard deviation of values Y. * * @return standard deviation of values Y */ public double stddeviationY() { return Math.sqrt(varianceY()); } /** * Returns variance for Y-values. This is a measure of how far a set of * numbers are spread out from each other. * * @return variance for Y values **/ public double varianceY() { double var; int degrees = (size() - 1); int m = size(); double c; double s; c = 0; s = 0; for (int k = 0; k < m; k++) s += getQuickY(k); s = s / m; for (int k = 0; k < m; k++) c += (getQuickY(k) - s) * (getQuickY(k) - s); var = c / degrees; return var; } /** * Returns RMS for X-values. It represents a root-mean-square (sometimes * called the quadratic mean), is the square root of mean of the values * x_i^2, * * @return RMS for X **/ public double rmsX() { double mx = 0.; for (int i = 0; i < X.size(); i++) { mx += X.getQuick(i) * X.getQuick(i); } mx = mx / X.size(); mx = Math.sqrt(mx); return mx; } /** * Returns RMS for Y-values. It represents a root-mean-square (sometimes * called the quadratic mean), is the square root of mean of the values * x_i^2, * * @return RMS for Y **/ public double rmsY() { double mx = 0.; for (int i = 0; i < Y.size(); i++) { mx += Y.getQuick(i) * Y.getQuick(i); } mx = mx / Y.size(); mx = Math.sqrt(mx); return mx; } /** * Returns the mean value in X. * * @return Mean value in X **/ public double meanX() { double mx = 0.; for (int i = 0; i < X.size(); i++) { mx += X.getQuick(i); } mx /= X.size(); return mx; } /** * Returns the standard error of the mean values for X. * This is (standard deviation)/sqrt(size). * * @return standard error of the mean values for X **/ public double meanXerror() { return stddeviationX() / Math.sqrt(size()); } /** * Returns the standard error of the mean values for Y. * This is (standard deviation)/sqrt(size). * * @return standard error of the mean values for X **/ public double meanYerror() { return stddeviationY() / Math.sqrt(size()); } /** * Get complete statistics for this container for a given axis. * It return mean, error on the mean, RMS, variance, standard deviation. <p> * The key for the output <b>map are: mean, error, rms, variance, stddev </b>. * * @param axis axis=0 for X and axis=1 for Y * @return map representing statistics */ public Map<String, Double> getStat(int axis) { Map<String, Double> tmp = new HashMap<String, Double>(); if (axis == 0) { tmp.put("mean", meanX()); tmp.put("mean_error", meanXerror()); tmp.put("rms", rmsX()); tmp.put("variance", varianceX()); tmp.put("standardDeviation", stddeviationX()); } if (axis == 1) { tmp.put("mean", meanY()); tmp.put("mean_error", meanYerror()); tmp.put("rms", rmsY()); tmp.put("variance", varianceY()); tmp.put("standardDeviation", stddeviationY()); } return tmp; } /** * Returns the mean value in Y. * * @return Mean value in Y **/ public double meanY() { double mx = 0.; for (int i = 0; i < Y.size(); i++) { mx += Y.getQuick(i); } mx /= Y.size(); return mx; } /** * Clear the container. */ public void clear() { if (dimen == 2) { X.clear(); Y.clear(); } else if (dimen == 3) { X.clear(); Y.clear(); YE1upper.clear(); } else if (dimen == 4) { X.clear(); Y.clear(); YE1upper.clear(); YE1down.clear(); } else if (dimen == 6) { X.clear(); Y.clear(); XE1left.clear(); XE1right.clear(); YE1upper.clear(); YE1down.clear(); } else if (dimen == 10) { X.clear(); Y.clear(); XE1left.clear(); XE1right.clear(); YE1upper.clear(); YE1down.clear(); XE2left.clear(); XE2right.clear(); YE2upper.clear(); YE2down.clear(); } } /** * Show in a Table in a separate Frame. The numbers are * formatted to scientific format. One can sort and search the data in this * table (but not modify) */ public void toTable() { new HTable(this); } /** * Fill a P1D container from 2 arrays. If it is not empty, add values will * be appended. It is assumed that all errors are zero. * * @param xa * array with X values * @param ya * array with Y values * */ public void fill(double[] xa, double[] ya) { if (xa.length != ya.length) { System.out.println("Different dimensions of arrays!"); return; } setDimension(2); for (int i = 0; i < xa.length; i++) { X.add(xa[i]); Y.add(ya[i]); } } /** * Fill a P1D container from 2 integer arrays. If it is not empty, add values will * be appended. It is assumed that all errors are zero. * * @param xa * integer array with X values * @param ya * integer array with Y values * */ public void fill(int[] xa, int[] ya) { if (xa.length != ya.length) { System.out.println("Different dimensions of arrays!"); return; } setDimension(2); for (int i = 0; i < xa.length; i++) { X.add(xa[i]); Y.add(ya[i]); } } /** * Fill a P1D container from 2 P0D arrays. If it is not empty, add values * will be appended. It is assumed that all errors are zero. * * @param xa * P0D with X values * @param ya * P0D with Y values * */ public void fill(P0D xa, P0D ya) { if (xa.size() != ya.size()) { System.out.println("Different dimensions of arrays!"); return; } setDimension(2); for (int i = 0; i < xa.size(); i++) { X.add(xa.getQuick(i)); Y.add(ya.getQuick(i)); } } /** * Fill a P1D container from a Cloud2D. * * @param c2D * input Cloud * */ public void fill(Cloud2D c2d) { setDimension(2); for (int i = 0; i < c2d.entries(); i++) { X.add(c2d.valueX(i)); Y.add(c2d.valueY(i)); } } /** * Get array of X values; * @return */ public DoubleArrayList getXval() { return X; } /** * Get array of Y values; * @return */ public DoubleArrayList getYval() { return Y; } /** * Left error on X (1st level) * @return */ public DoubleArrayList getXE1left() { return XE1left; } /** * Left error on X (2nd level) * @return */ public DoubleArrayList getXE2left() { return XE2left; } /** * Right eroor on X * @return */ public DoubleArrayList getXE1right() { return XE1right; } /** * Right error (2nd level) on X * @return */ public DoubleArrayList getXE2right() { return XE2right; } /** * Down error on Y (1st level) * @return */ public DoubleArrayList getYE1down() { return YE1down; } /** * Upper error on Y (1st level) * @return */ public DoubleArrayList getYE1upper() { return YE1upper; } /** * Down error on Y (2nd level) * @return */ public DoubleArrayList getYE2down() { return YE2down; } /** * Upper error on Y (2nd level) * @return */ public DoubleArrayList getYE2upper() { return YE2upper; } /** * Error on X left.Statistical error. * @param xE1left left statistical error. */ public void setXE1left(DoubleArrayList xE1left) { XE1left = xE1left; } /** * Set X values as array * @param array with X values */ public void setXval(DoubleArrayList X) { this.X = X; } /** * Error on X. right error (1st level). * @param xE1right */ public void setXE1right(DoubleArrayList xE1right) { XE1right = xE1right; } /** * Set statististical down error * @param yE1down down error */ public void setYE1down(DoubleArrayList yE1down) { YE1down = yE1down; } /** * Set statistical error on Y 91st level) * @param yE1upper upper error on Y */ public void setYE1upper(DoubleArrayList yE1upper) { YE1upper = yE1upper; } /** * Set second level down error on Y * @param yE2down error on Y down (2nd level) */ public void setYE2down(DoubleArrayList yE2down) { YE2down = yE2down; } /** * Set second level upper error on Y * @param yE2upper upper error on Y */ public void setYE2upper(DoubleArrayList yE2upper) { YE2upper = yE2upper; } /** * Set Y values * @param yval Y value */ public void setYval(DoubleArrayList yval) { Y = yval; } /** * Fill a P1D container from 3 arrays (one represents symmetrical errors on * Y). If it is not empty, add values will be appended. It is assumed that * all other errors are zero. Arrays must be of the same size. * * @param xa * array with X values * @param ya * array with Y values * @param yerror * array with errors on Y values * */ public void fill(double[] xa, double[] ya, double[] yerror) { if (xa.length != ya.length) { System.out.println("Different dimensions of arrays!"); return; } if (xa.length != yerror.length) { System.out.println("Different dimensions of arrays!"); return; } setDimension(3); X.elements(xa); Y.elements(ya); YE1upper.elements(yerror); } /** * Fill a P1D container from P0D arrays (one represents symmetrical errors * on Y). If it is not empty, add values will be appended. It is assumed * that all other errors are zero. Arrays must be of the same size. * * @param xa * P0D array with X values * @param ya * P0D array with Y values * @param yerror * P0D array with errors on Y values * */ public void fill(P0D xa, P0D ya, P0D yerror) { if (xa.size() != ya.size()) { System.out.println("Different dimensions of arrays!"); return; } if (xa.size() != yerror.size()) { System.out.println("Different dimensions of arrays!"); return; } setDimension(3); for (int i = 0; i < xa.size(); i++) { X.add(xa.getQuick(i)); Y.add(ya.getQuick(i)); YE1upper.add(yerror.getQuick(i)); } } /** * Fill a P1D container from 4 arrays (last represents asymmetrical upper * and lower errors on Y). If it is not empty, add values will be appended. * It is assumed that all other errors are zero. All arrays must be of the * same size. * * @param xa * array with X values * @param ya * array with Y values * @param yupper * array with upper errors on Y values * @param ylower * array with upper errors on Y values * */ public void fill(double[] xa, double[] ya, double[] yupper, double[] ylower) { if (xa.length != ya.length) { System.out.println("Different dimensions of arrays!"); return; } if (xa.length != yupper.length) { System.out.println("Different dimensions of arrays!"); return; } if (xa.length != ylower.length) { System.out.println("Different dimensions of arrays!"); return; } setDimension(4); X.elements(xa); Y.elements(ya); YE1upper.elements(yupper); YE1down.elements(ylower); } /** * Fill the values of a X-Y plot-points with full errors. It includes upper * and lower errors on X and Y, including 1st and 2nd level errors (i.e. * statistical and systematic). All arrays must be of the same size. * * @param x * array of x-value of the plot-point * @param y * array of y-value of the plot-point * @param left * - array of error on x (left) * @param right * - array of error on x (right) * @param upper * - array of error on y (upper) * @param lower * - array of error on y (lower) * @param left_sys * - array of error on x (left) - second level, used for * systematics * @param right_sys * - array of error on x (right) * @param upper_sys * - array of error on y (upper) * @param lower_sys * - array of error on y (lower) */ public void fill(double[] x, double[] y, double[] left, double[] right, double[] upper, double[] lower, double[] left_sys, double[] right_sys, double[] upper_sys, double[] lower_sys) { setDimension(10); X.elements(x); Y.elements(y); XE1left.elements(left); XE1right.elements(right); XE2left.elements(left_sys); XE2right.elements(right_sys); YE1upper.elements(upper); YE1down.elements(lower); YE2upper.elements(upper_sys); YE2down.elements(lower_sys); } /** * Set array at once * @param x X-values */ public void setArrayX(double[] x) { X.clear(); X.elements(x); } /** * Set array at once * @param x Y-values */ public void setArrayY(double[] y) { Y.clear(); Y.elements(y); } /** * Generate error message * * @param a * Message */ private void ErrorMessage(String a) { jhplot.utils.Util.ErrorMessage(a); } /** * Show online documentation. */ public void doc() { String a = this.getClass().getName(); a = a.replace(".", "/") + ".html"; new HelpBrowser(HelpBrowser.JHPLOT_HTTP + a); } }