Home : Map : Chapter 8 : Java : Tech : Physics :
Fitting Histogram With Errors
JavaTech
Course Map
Chapter 8

Introduction
Threads Overview
  Demo 1   Demo 2
Stopping Threads
Multi-Processing
Thread Tasks
Animations
 
 Demo 3   Demo 4  
  Demo 5

Non-interacting
  Demo 6

Task Splitting
  Demo 7

Exclusivity
  Demo 8

Communicating
  Demo 9

Priority/Scheduling
More Thread

Exercises

    Supplements
Java2D Animation
  Demo 1 
Processor View
More Concurrency
Cloning
  Demo 2  Demo 3 

     About JavaTech
     Codes List
     Exercises
     Feedback
     References
     Resources
     Tips
     Topic Index
     Course Guide
     What's New

Now that we have a framework of classes for drawing functions on our PlotPanel subclasses and for data fitting, we can use it with our histograms. In Chapter 8: Tech: Errors we used the class HistogramStatR1 to obtain errors for each bin and we plotted it on an instance of HistErrPanel. As with the DrawPanel from Chapter 6: Tech, the HistErrPanel class loops through a list of DrawFunction instances to draw on top of the histogram. Here we take advantage of that drawing capability.

The applet below derives from the demo program RanDistAnglesApplet.java from Chapter 7: Physics: Custom Distribution except that here we create a distribution that follows a quadratic polynominal shape. In addition, we fit a polynominal to the distribution and draw the line over the data points.

The DrawPoly instance of DrawFunction draws the polynominal using the data obtained with FitPoly.java. Since we may want to do similar fitting in the future, we create the class HistogramFit that holds a static method for fitting data to the binned data of a histogram.


HistFitApplet.java - Create a random distribution of values and then fit a polynominal to the bin values.

+ New classes:
HistogramFit.java - provides a static class that takes a histogram as an argument and fits the distribution of values to a polynominal of a given degree.

+ Previous classes:
Ch.8:Physics
: FitPoly.java DrawPoly.java
Ch.8:Physics
: Fit.java
Ch.8:Tech
:
HistErrPanel.java
Ch.8:Tech:
HistogramStatR1.java
Ch.6:Tech: Histogram.java, HistPanel.java
Ch.6:Tech: DrawFunction.java,DrawLine.java,DrawPoints.java
, DrawPanel.java
Ch.6:Tech: PlotPanel.java, PlotFormat.java

 

/**
  *  Provides a static method for fitting a polynominal to the
  *  distribution of values in a histogram. The middle of each
  *  bin is taken as the "x" value and the bin contents as the
  *  "y" for a fit of y vs. x. If bin errors are available, they
  *  are used in the fit.
 **/
public class HistogramFit
{

  /**
    *  Fit the histogram data. If available, use bin errors from histogram.
    *  Assume no error on horizontal variable.
    *
   **/
  public static double [] fit (Histogram histogram, int degree) {

    // Get data from histogram.
    int [] bins = histogram.getBins ();
    double lo = histogram.getLo ();
    double hi = histogram.getHi ();

    // Need arrays for fit.
    double [] y = new double[bins.length];
    double [] x = new double[bins.length];

    double x_del =  (hi-lo)/bins.length;
    double x_start = lo + x_del/2.0;

    // Make floating point arrays for the fit.
    for (int i=0; i < bins.length; i++) {

        // Convert to FP array for bins
        y[i] = bins[i];
        // Use middle of bin as the x value.
        x[i] = i * x_del + x_start;
    }

    // Create an array to hold the polynominal coefficients in
    // bottom half and their error estimates in top half.
    double [] parameters = new double[2*degree];

    //
    if (histogram instanceof HistogramStatR1) {
        double [] err = ((HistogramStatR1)histogram).getBinErrors ();
        FitPoly.fit (parameters, x, y,null,err,bins.length);
    } else{
        FitPoly.fit (parameters, x,y,null,null,bins.length);
    }

    return parameters;

  } // fit

} // HistogramFit
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
  *  Create a random distribution of values and then fit a
  *  polynominal to the bin values.
  *
  *  The applet uses the HistPanel to display contents of
  *  an instance of Histogram. HistFormat used by HistPanel to
  *  format the scale values.
  *
  *  This program will run as an applet inside
  *  an application frame.
  *
  *  Includes "Go" button to add random values from a Gaussian
  *  distribution to the histogram. The number of values taken from
  *  entry in a JTextField. "Clear"  button clears the histogram.
  *  In standalone mode, the Exit button closes the program.
  *  
 **/
public class HistFitApplet extends JApplet
             implements ActionListener
{
  // Use the HistPanel JPanel subclass here
  HistErrPanel fOutputPanel;

  HistogramStatR1 fHistogram;

  DrawFunction [] fDrawFunctions;

  double [] fFitParameters;

  int fNumDataPoints = 10000;

  // Set the angular range for scattered tracks
  double fMinAngle;
  double fMaxAngle;

  // Random number generator
  java.util.Random fRan;

  // A text field for input strings
  JTextField fTextField;

  // Flag for whether the applet is in a browser
  // or running via the main () below.
  boolean fInBrowser = true;

  //Buttons
  JButton fGoButton;
  JButton fClearButton;
  JButton fExitButton;

  /**
    * Create a User Interface with histograms and buttons to
    * control the program. A textfield holds number of entries
    * to be generated for the histogram.
   **/
  public void init ()  {

    JPanel panel = new JPanel (new BorderLayout ());

    // Create a histogram with Gaussian distribution.
    makeHist ();

    // Create the Histogram drawing panel and include
    // drawing objects.
    fDrawFunctions = new DrawFunction[1];
    fDrawFunctions[0] = new DrawPoly ();
    fOutputPanel = new HistErrPanel (fHistogram, fDrawFunctions);
    fOutputPanel.setDrawType (HistErrPanel.DRAW_PTS_ERRS);

    // Fit the line to the histogram.
    fitHist ();

    panel.add (fOutputPanel,"Center");

    // Use a textfield for an input parameter.
    fTextField =
      new JTextField (Integer.toString (fNumDataPoints), 10);

    // If return hit after entering text, the
    // actionPerformed will be invoked.
    fTextField.addActionListener (this);

    fGoButton = new JButton ("Go");
    fGoButton.addActionListener (this);

    fClearButton = new JButton ("Clear");
    fClearButton.addActionListener (this);

    fExitButton = new JButton ("Exit");
    fExitButton.addActionListener (this);

    JPanel controlPanel = new JPanel ();

    controlPanel.add (fTextField);
    controlPanel.add (fGoButton);
    controlPanel.add (fClearButton);
    controlPanel.add (fExitButton);

    if (fInBrowser) fExitButton.setEnabled (false);

    panel.add (controlPanel,"South");

    // Add text area with scrolling to the contentPane.
    add (panel);

  } // init

  /**
    * Respond to the buttons.
   **/
  public void actionPerformed (ActionEvent e) {
    Object source = e.getSource ();
    if (source == fGoButton || source == fTextField) {
      String strNumDataPoints = fTextField.getText ();
      try {
        fNumDataPoints = Integer.parseInt (strNumDataPoints);
      }
      catch (NumberFormatException ex) {
        // Could open an error dialog here but just
        // display a message on the browser status line.
        showStatus ("Bad input value");
        return;
      }
      makeHist ();
      fitHist ();
      repaint ();
    }
    else if (source == fClearButton) {
        fHistogram.clear ();
        repaint ();
    }
    else if (!fInBrowser)
        System.exit (0);

  } // actionPeformed

  /**
    * Create a random distribution of angles to
    * simulate the tracks in a particle scattering
    * experiment entering a detector element.
   **/
  void makeHist () {
    // Create an instance of the Random class for
    // producing our random values.
    fRan = new java.util.Random ();

    // Could modify the program to select these via the GUI
    fMinAngle = 25.0;
    fMaxAngle = 50.0;

    // Create an instance of our basic histogram class.
    // Make it wide enough enough to include most of the
    // gaussian values.
    if (fHistogram == null)
        fHistogram = new HistogramStatR1 ("Scatter Angles into a Detector",
                                "Degrees",
                                25,fMinAngle,fMaxAngle);

    // Use the method to generate a
    // quadratic distribution.
    for (int i=0; i < fNumDataPoints; i++) {
        // Generate random vals 0.0 to 1.0
        double r1 = fRan.nextDouble ();
        double angle = fMinAngle + (fMaxAngle-fMinAngle)*r1;
        if ( acceptAngle (angle)){
            fHistogram.add (angle);
        }
    }

    // Make the errors from the bin contents
    fHistogram.makeBinErrors ();

  } // makeHist

  /**
    * This rejection function uses a quadratic
    * function to determine the acceptance of the
    * angle.
   **/
  boolean acceptAngle (double angle){
    if ( angle < fMinAngle || angle > fMaxAngle) return false;
    double c = 0.2;
    double slope = 0.020;
    double non_lin_factor = 0.0007;

    double limit = c +  (angle - fMinAngle) * slope -
         (angle - fMinAngle) *  (angle - fMinAngle) * non_lin_factor;
    double r2 = fRan.nextDouble ();
    if ( r2 <= limit) return true;
    return false;

  } // acceptAngle

  /**
    * Fit a polynominal to the hist data.
   **/
  void fitHist () {

    // Use it to fit the histogram data.
    fFitParameters = HistogramFit.fit (fHistogram, 3);

    // Pass the parameters to the drawing function object.
    fDrawFunctions[0].setParameters (fFitParameters,null);
  } // fitHist

  public static void main (String[] args)
  {
    //
    int frame_width=450;
    int frame_height=300;

    //
    HistFitApplet applet = new HistFitApplet ();
    applet.fInBrowser = false;
    applet.init ();

    // Following anonymous class used to close window & exit program
    JFrame f = new JFrame ("Demo");
    f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

    // Add applet to the frame
    f.getContentPane ().add ( applet);
    f.setSize (new Dimension (frame_width,frame_height));
    f.setVisible (true);

  } // main

} // HistFitApplet

 

References & Web Resources

Last update: Sept. 20, 2005

              Tech
Timers
  Demo 1
Hist. Adapt Range
  Demo 2
Sorting in Java
  Demo 3
Histogram Median
  Demo 4
Refactoring
  Demo 5
Error Bars
  Demo 6
Exercises

           Physics
Least Squares Fit
  Demo 1
Fit to Polynomial
  Demo 2
Fit Hist Errors
  Demo 3
Discretization
  Demo 4
Timing
  Demo 5
Exercises

  Part I Part II Part III
Java Core 1  2  3  4  5  6  7  8  9  10  11  12 13 14 15 16 17
18 19 20
21
22 23 24
Supplements

1  2  3  4  5  6  7  8  9  10  11  12

Tech 1  2  3  4  5  6  7  8  9  10  11  12
Physics 1  2  3  4  5  6  7  8  9  10  11  12

Java is a trademark of Sun Microsystems, Inc.