Java source code of 'jhplot.P1D'

/**
*    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 .
*
*    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 ),
*    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.awt.Color;
import java.io.*;
import java.net.URL;
import java.util.*;
import hep.aida.*;
import hep.aida.ref.histogram.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import cern.colt.list.DoubleArrayList;
import cern.jet.stat.Descriptive;
import java.lang.Math;

/**
 * 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.
 * 
 * 

* * 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
* 3: for X,Y and error on Y
* 4: for X,Y and error on Y (up) and Y (down)
* 6: for X,Y and error on Y (up) and Y (down) and X(left) and X(right)
* 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. *

* 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-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; i5){ 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:
"+" add a P1D container to * the original;
"-" subtract a P1D from the original;
"*" * multiply;
"/" divide by P1D * @return error code: * 0 means OK
* 1: means divistion by zero
* 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. *

* 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. *

* 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. *

* 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. * *

* 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. * *

* 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. * *

* 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. * *

* 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. * *

* * 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. * *

* 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. * *

* 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. * *

* 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. * *

* 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. * *

* 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 compareChi2(F1D f1) { Map tmp= new HashMap(); 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. *

* 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 compareChi2(P1D h2) { Map tmp= new HashMap(); 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. * Numbers are separated by a space. * * @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. * Numbers are seprated by space. * @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(); int ncount=0; boolean first=true; try { while ((line = br.readLine()) != null) { line = line.trim(); if (!line.startsWith("#") && !line.startsWith("*") && line.length()>1) { String[] currentLine = line.split("\\s+"); if (first) { setDimension(ncount); first=false; ncount = currentLine.length;}; 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 for (int k=0; k * 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. *

* 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. *

* It is smoothed by averaging over a moving window of a size specified by * the method parameter: if the value of the parameter is k then the * width of the window is 2*k + 1. 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 * k 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 * *

* 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 * IllegalArgumentException 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. * *

* 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. *

* 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; jX.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; jX.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; jX.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; jY.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; jY.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; jY.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.

* The key for the output map are: mean, error, rms, variance, stddev . * * @param axis axis=0 for X and axis=1 for Y * @return map representing statistics */ public Map getStat(int axis) { Map tmp= new HashMap(); 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