Java source code of 'jhplot.HProf1D'

/**
*    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 javax.swing.*;

import root.Converter;


import java.io.*;
import java.util.*;

import hep.aida.*;
import hep.aida.ref.histogram.*;

import java.text.DecimalFormat;

import jhplot.gui.HelpBrowser;
import jhplot.utils.SHisto;


// reading root files
import hep.io.root.interfaces.*;

/**
 * Create profile histogram in 1D. It is used to
 * show the mean values in each bin of a second variable.
 * To show it, convert it to the usual H1D histogram (getH1D method).
 * You can specify errors as errors on the mean or spread RMS.
 * 
 * @author S.Chekanov
 * 
 */
public class HProf1D  implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private Profile1D h1;

	private IAxis axis;

	private double min;

	private double max;

	private int bins;
	
	private double[] edges;

	private String title;
	
	

 /**
         * Build 1D histogram. 
         * Default constructor. Does not do anything.  
         */
        public HProf1D() {
              
                this.title = "NOT SET";
        }



	/**
	 * Build 1D profile histogram
	 * 
	 * @param title
	 *            Title
	 * @param bins
	 *            Number of bins
	 * @param min
	 *            Minimum value
	 * @param max
	 *            Maximum value
	 */
	public HProf1D(String title, int bins, double min, double max) {

	
		this.title = title;
		this.bins = bins;
		this.min = min;
		this.max = max;
		axis = new FixedAxis(this.bins, this.min, this.max);
		h1 = new Profile1D(this.title, this.title, axis);
	}








	/**
	 * Create 1D profile histogram with variable bin size.
	 * 
	 * @param title
	 *            Title of histogram.
	 * @param edges
	 *            edges
	 */
	public HProf1D(String title, double[] edges) {

		
		this.edges = edges;
	        this.title = title;
		this.bins = edges.length - 1;
		this.min = edges[0];
		this.max = edges[edges.length-1];
		axis=new VariableAxis(edges);
		h1 = new Profile1D(this.title, this.title, axis);
	}

	
	/**
	 * Create 1D histogram with variable bin size.
	 * 
	 * @param title
	 *            Title of histogram.
	 * @param edges
	 *            edges
	 */
	public HProf1D(String title, IAxis axis) {

	
	    this.title = title;
		this.axis=axis;
		min=axis.lowerEdge();
		max=axis.upperEdge();
		bins=axis.bins();
		h1 = new Profile1D(this.title, this.title, axis);
	}

	
	
	
	
	/**
	 * Create H1D histogram from JAIDA Histogram1D class.
	 * 
	 * @param h1
	 *            Profile1D histogram from JAIDA
	 */

	public HProf1D(Profile1D h1) {

		
		this.h1 = h1;
		this.title=h1.title();
		this.axis = h1.axis();
		this.min = axis.lowerEdge();
		this.max = axis.upperEdge();
		this.bins = axis.bins();
	}

	/**
	 * Create profile histogram from JAIDA  class
	 * 
	 * @param h1
	 *            IProfile1D histogram from JAIDA
	 */

	public HProf1D(IProfile1D h1) {

		
		this.h1 = (Profile1D) h1;
		this.title=h1.title();
		this.axis = h1.axis();
		this.min = axis.lowerEdge();
		this.max = axis.upperEdge();
		this.bins = axis.bins();
	}

      /**
         * Create profile histogram  from another instance. 
         *  
         * @param title 
         *              new title
         *  
         * @param h1d 
         *          input H1D 
         */

        public HProf1D(String title, HProf1D h1d) {

              
                this.title=title;
                this.axis = h1d.getAxis();
                this.min = axis.lowerEdge();
                this.max = axis.upperEdge();
                this.bins = axis.bins();
                this.h1 = h1d.get(); 
        }






	/**
	 * Print histogram on screen
	 * 
	 */
	public void print() {

		DecimalFormat dfb = new DecimalFormat("##.#####E00");
		Date dat = new Date();
		String today = String.valueOf(dat);
		IAxis axis = h1.axis();
		System.out.println("");
		System.out.println("# DataMelt: output from H1D: " + this.title);
		System.out.println("# DataMelt: created at " + today);
		System.out.println("# x,  y,  error(upper),  error(lower)");
		System.out.println("#");
		for (int i = 0; i < axis.bins(); i++) {
			String x = dfb.format(h1.binMean(i)); // The weighted mean of a
			// bin.
			String y = dfb.format(h1.binHeight(i));
			String y1 = dfb.format(h1.binError(i));
			String y2 = dfb.format(h1.binError(i));
			System.out.println(x + "    " + y + "    " + y1 + "    " + y2);
		}

	}

	/**
	 * Print a H1D histogram to a Table in a separate frame. The numbers are
	 * formatted to scientific format. One can sort and search the data in this
	 * table (cannot be modified).
	 */
    /*
	public void toTable() {

		new HTable(this);

	}
   */
	
	/**
	 * Fill histogram from two  P0D arrays
	 * 
	 * @param p0d
	 *            input P0D array
	 * @param p1d
	 *            input P1D           
	 */

	public void fillP0D(P0D p0d, P0D p1d) {

		for (int i = 0; i < p0d.size(); i++)
			h1.fill(p0d.get(i), p1d.get(i));

	}

	/**
	 * Get histogram Axis class.
	 * 
	 * @return Axis used for this histogram.
	 */

	public IAxis getAxis() {

		return axis;

	}

	/**
	 * Get bin centres.
	 * 
	 * @param index
	 *            bin index
	 * @return bin centre.
	 */

	public double binCenter(int index) {

		return axis.binCenter(index);

	}

	/**
	 * Get all bin centers in form of array
	 * 
	 * @return double[] array of bin centers
	 */

	public double[] binCenters() {

		double[] tmp = new double[bins];
		for (int i = 0; i < bins; i++)
			tmp[i] = axis.binCenter(i);

		return tmp;
	}

	/**
	 * Get bin lower edge.
	 * 
	 * @param index
	 *            bin index
	 * @return lower edge
	 */

	public double binLowerEdge(int index) {

		return axis.binLowerEdge(index);

	}

	/**
	 * Get all lower edges in form of array
	 * 
	 * @return double[] array of low edges
	 */

	public double[] binLowerEdges() {

		double[] tmp = new double[bins];
		for (int i = 0; i < bins; i++)
			tmp[i] = axis.binLowerEdge(i);

		return tmp;
	}

	/**
	 * Get bin upper edge.
	 * 
	 * @param index
	 *            bin index
	 * @return upper edge
	 */

	public double binUpperEdge(int index) {

		return axis.binUpperEdge(index);

	}

	/**
	 * Get all upper edges in form of array
	 * 
	 * @return double[] array of upper edges
	 */

	public double[] binUpperEdges() {

		double[] tmp = new double[bins];
		for (int i = 0; i < bins; i++)
			tmp[i] = axis.binUpperEdge(i);

		return tmp;
	}

	/**
	 * Print the profile  histogram to a Table in a separate Frame. One can sort and
	 * search the data in this table (but not modify)
	 */

	public void toTable() {

		new HTable(this.getH1D(title));

	}
    
	
	/**
	 * Write the profile  histogram to a file
	 * 
	 * @param name
	 *            File name
	 */

	public void toFile(String name) {

		DecimalFormat dfb = new DecimalFormat("##.#####E00");
		Date dat = new Date();
		String today = String.valueOf(dat);
		IAxis axis = h1.axis();

		try {
			FileOutputStream f1 = new FileOutputStream(new File(name));
			PrintStream tx = new PrintStream(f1);
			tx.println("# DataMelt: output from H1D " + this.title);
			tx.println("# DataMelt: created at " + today);
			tx.println("# x,  y,  error(upper),  error(lower)");
			tx.println("#");
			for (int i = 0; i < axis.bins(); i++) {
				String x = dfb.format(h1.binMean(i)); // The weighted mean of
				// a bin.
				String y = dfb.format(h1.binHeight(i));
				String y1 = dfb.format(h1.binError(i));
				String y2 = dfb.format(h1.binError(i));
				tx.println(x + "    " + y + "    " + y1 + "    " + y2);
			}
			f1.close();
		} catch (IOException e) {
			ErrorMessage("Error in the output file");
			e.printStackTrace();
		}

	}

	
	
	/**
	 * Create profile  histogram from JAIDA  histogram class
	 * 
	 * @param h1t
	 *            TProfile histogram from JAIDA
	 */
	public HProf1D(TProfile h1t) {

		this.title = h1t.getTitle();
		setTitle(this.title);

		TAxis axis = h1t.getXaxis();
		this.min = axis.getXmin();
		this.max = axis.getXmax();
        h1=Converter.convert(h1t,this.title);
     
	}

	/**
	 * Sets the content of  histogram. Start from 1 to bins+2.
	 * 
	 * @param values
	 *            array with values in Y (dimension: bins + 2)
	 * @param errors
	 *            array with errors on Y (dimension: bins + 2)
	 */
	public void setContents(double[] values, double[] errors) {
		h1.setContents(values, errors, null, null, null);
	}

	
	  /**
     * Set the content of the whole Histogram at once. This is a convenience method for saving/restoring
     * Histograms. Of the arguments below the heights array cannot be null. The errors array should in
     * general be non-null, but this depends on the specific binner.
     * The entries array can be null, in which case the entry of a bin is taken to be the integer part
     * of the height.
     * If the means array is null, the mean is defaulted to the geometric center of the bin.
     * If the rms array is null, the rms is taken to be the bin width over the root of 12.
     *
     * @param heights The bins heights
     * @param errors The bins errors
     * @param entries The bin entries.
     * @param means The means of the bins.
     * @param rmss The rmss of the bins
     *
     */
    public void setContents(double[] heights, double[] errors, int[] entries, double[] means, double[] rmss ) {
    	h1.setContents(heights, errors, entries, means, rmss);
    }
	
	
	/**
	 * Sets the Mean and RMS of H1D histogram
	 * 
	 * @param mean
	 *            mean of the histogram
	 * @param rms
	 *            RMS to be set
	 */
	public void setMeanAndRms(double mean, double rms) {
		h1.setMean(mean);
		h1.setRms(rms);
	}

	/**
	 * Sets number of entries of the  histogram.
	 * 
	 * @param entries
	 *            Number of entries
	 */
	public void setNEntries(int entries) {
		h1.setNEntries(entries);
	}

	/**
	 * Sets number of valid entries.
	 * 
	 * @param entries
	 *            Number of valid entries
	 */
	public void setValidEntries(int entries) {
		h1.setValidEntries(entries);
	}

	/**
	 * Sets the mean
	 * 
	 * @param mean
	 *            mean
	 */
	/*
	 * public void setMean(double mean) { h1.setMean(mean); }
	 */

	/**
	 * Sets the title
	 * 
	 * @param title
	 *            Title
	 */
	public void setTitle(String title) {
		this.title = title;

	}

	/**
	 * get Title of the histogram
	 * 
	 * @return Title of histogram
	 */

	public String getTitle() {
		return this.title;

	}

	/**
	 * Get JAIDA histogram
	 * 
	 * @return JAIDA Profile1D histogram
	 */
	public Profile1D get() {

		return h1;

	}

	/**
	 * Set Min value of axis
	 * 
	 * @param min
	 *            Minimum value of axis
	 */
	public void setMin(double min) {
		this.min = min;

	}

	/**
	 * Get Minimum value of the axis
	 * 
	 * @return Minimum value of the axis
	 */

	public double getMin() {
		return this.min;
	}

	/**
	 * Set Maximum value of axis
	 * 
	 * @param max
	 *            Maximum value of axis
	 */

	public void setMax(double max) {
		this.min = max;

	}

	/**
	 * Get Maximum value of axis
	 * 
	 * @return Maximum value of axis
	 */

	public double getMax() {
		return this.max;

	}

	/**
	 * Sets the number of bins
	 * 
	 * @param bins
	 *            Number of bins
	 */

	public void setBins(int bins) {
		this.bins = bins;

	}

	/**
	 * Get the number of bins
	 * 
	 * @return Number of bins
	 */

	public int getBins() {
		return this.bins;

	}


 /**
 *  Get bin width in case of fixed-size bins. 
 *        
 *  @return bin width (max-min) /bins  
 **/
        public double getBinSize() {
                return (this.max - this.min) / this.bins;
        }


        
        
        /**
         * Shift all bins by some value
         * 
         * @param d
         *         parameter used to shift bins
         */
        
     public void  shift(double d) {
    	 
    	 int ibins = h1.axis().bins()+2;
         double[] newHeights = new double[ibins];
         double[] newErrors  = new double[ibins];
         double[] newMeans   = new double[ibins];
         double[] newRmss    = new double[ibins];
         int[]    newEntries = new int   [ibins];
         
         newHeights[0]= getUnderflowHeight();
         newHeights[ibins - 1] = getOverflowlowHeight();

         for(int i=0; i
	 * Each band of the histogram 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 histogram 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 isWeighted
	 *            Whether bins 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 the histogram.
	 */

	public HProf1D operSmooth(boolean isWeighted, int k) {

		SHisto sh = new SHisto(bins, min, max, 1);

		double[] hh = binHeights();
		double[] ee = binErrors();

		sh.setBins(hh);
		sh = sh.getSmoothed(isWeighted, k);

		double[] hh1 = new double[bins + 2];
		double[] ee1 = new double[bins + 2];

		hh1[0] = getUnderflowHeight();
		hh1[bins - 1] = getOverflowlowHeight();
		for (int i = 1; i < bins + 1; i++) {
			hh1[i] = sh.getBinsFirstBand(i - 1);
			ee1[i] = ee[i - 1];
			// System.out.println(hh1[i]+ " " + ee1[i]);
		}

		h1.setContents(hh1, ee1, null, null, null);
		return this;
	}

	/**
	 * Computes a Gaussian smoothed version of the histogram.
	 * 
	 * 

* Each band of the histogram is smoothed by discrete convolution with a * kernel approximating a Gaussian impulse response with the specified * standard deviation. * * @param standardDeviation * The standard deviation of the Gaussian smoothing kernel which * must be non-negative or an * IllegalArgumentException will be thrown. If * zero, the histogram object will be returned with no smoothing * applied. * @return A Gaussian smoothed version of the histogram. * */ public HProf1D operSmoothGauss(double standardDeviation) { SHisto sh = new SHisto(bins, min, max, 1); double[] hh = binHeights(); double[] ee = binErrors(); sh.setBins(hh); sh = sh.getGaussianSmoothed(standardDeviation); double[] hh1 = new double[bins + 2]; double[] ee1 = new double[bins + 2]; hh1[0] = getUnderflowHeight(); hh1[bins - 1] = getOverflowlowHeight(); for (int i = 1; i < bins + 1; i++) { hh1[i] = sh.getBinsFirstBand(i - 1); ee1[i] = ee[i - 1]; // System.out.println(hh1[i]+ " " + ee1[i]); } h1.setContents(hh1, ee1, null, null, null); return this; } /** * Returns the entropy of the histogram. * *

* The entropy is defined to be the negation of the sum of the products of * the probability associated with each bin with the base-2 log of the * probability. * * @return The entropy of the histogram. * */ public double getEntropy() { SHisto sh = new SHisto(bins, min, max, 1); double[] hh = binHeights(); sh.setBins(hh); double s[] = sh.getEntropy(); return s[0]; } /** * Make a copy of the data holder * * @return New data holder */ public HProf1D copy() { return copy(this.title); } /** * Get exact copy of the current histogram. This means it makes a new * object. * * @param newtitle * New title * @return a new copy of the histogram */ public HProf1D copy(String newtitle) { int ibins = bins+2; double[] newHeights = new double[ibins]; double[] newErrors = new double[ibins]; double[] newMeans = new double[ibins]; double[] newRmss = new double[ibins]; int[] newEntries = new int [ibins]; newHeights[0]= getUnderflowHeight(); newHeights[ibins - 1] = getOverflowlowHeight(); for(int i=0; i