Home : Map : Chapter 11 :Java : Tech : Physics :
Simulation and Analysis Code:
Drop Generator with Instrument and Systematic Effects
JavaTech
Course Map
Chapter 11

Introduction
Image Class
Image Loading
  Demo 1 Demo 2  
Pixels/Transparency
  Demo 3
Pixel Handling
  Demo 4  
Demo 5
Exercises

    Supplements
Java 2D Imaging
BufferedImage
Creating Buf.Image
Pixel Handling
  Demo 1 Demo 2
Filters
  Convolutions
     Demo 3
  AffineTransforms
     Demo 4
  LookupTable
     Demo 5 Demo 6
  Rescale
     Demo 7
  Color Conversion
     Demo 8
  Custom
     Demo 9
Exercises
Java Adv Imaging
AWT Flicker:
  Override Update
     Demo 1  Demo 2
  Clipping
     Demo 3
  Double Buffer
     Demo 4

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

In Chapter 9: Physics: Experiment Simulation with Analysis Module we developed a demonstration program that combined a simulation of a dropped mass experiment with the analysis of the data from the "experiment". In Chapter 10: Simulated Data Generation and Analysis Demo, we split off the analysis into a separate standalone program that read data in files written by a standalone experiment simulation. This pair of programs more close resembles what the real world situation where simulation and analysis software for an real experiment involve separate programs.

The DropGenCalSysErr applet/application program shown below takes another step towards greater realism. It adds some real world complications that an actual experiment encounters. Instrument measurements, for example, often have offsets and nonlinearities that must be "calibrated out" before converting the instrument data to the parameter values used in calculations. Usually, special "calibration runs" with fixed, known inputs are carried out to determine what these instrument artifacts are so that they can be removed from the experiment data.

To illustrate this sort of calibration, in DropGenCalSysErr the user can select to add an instrument offset to the position data. The user also can perform a "calibration run" to help determine the offset.

Also in DropGenCalSysErr the user can include a systematic error. The particular systematic error that we include here involves the time span between each position measurement. For an experiment, this would typically be selected via a dial that indicates the frequency output of an oscillator. It's not impossible that the oscillator dial is mis-calibrated and does not match the actual output. It's also not impossible that we accidentally bumped the oscillator dial during the experiment and the setting was moved from what we wanted it to be. So our systematic error analysis program will allow us to examine how big of an effect on the results would be caused by variations in the measurement frequency.

Note that other types of systematic errors could be studied in an elegant way by creating subclasses of DropDetector3 and overriding the relevant methods.

The code for DropGenCalSysErr is shown here. After discussing the analysis program in the following section, we will look at several examples of how one would use such a set of programs to study the experiment.

DropGenCalSysErr

DropGenCalSysErr - Using code from the Chapter 9: Physics: Experiment Simulation with Analysis Module and Chapter 10: Simulated Data Generation and Analysis Demo, this program adds data offsets, systematic error, and can perform a "calibration run".

The controls include similar buttons as before and also the user input fields for the number of drops and the smearing sigma for the position data. As in Chatper 10, there is the option for an output data file and a user chosen name for the file

New controls include an option for including a systematic error on the time span between the position measurements. So, for example, a 1.1 entry in the Sys Err textfield will multiply the time span by 1.1.

The Add Calibration option will add the value in the Cal field to the position measurements.

The Run Calibration option creates a special set of data in which the distance between position measurements is a fixed value to simulate the type of data created to determine calibrations for an instrument. This will create create a straight line in a y vs t plot. The y intercept will indicated the size of the calibration constant added to the data.

The output data file will be analyzed by DropDataAnalysisCalSysErr discussed on the next page.

DropDetector3 - a subclass of DropDetector2, adds methods to turn on/off the instrument calibration offsets, the calibration run, and the systematic error. Also, the calibration offset and the systematic error factor must be passed.

The measure() method controls the determination of the data values. So it puts in the calibration offset and systematic error if those options are chosen. For calibration runs, it replaces the drop data with artificially created fixed spaced values for the position data.

+ Previous Classes:
Chapter 9: Physics: DropPanelDetect, DropModelDetect
Chapter 9: Physics: DropDetector2, Detector

Chapter 6: Tech: PlotPanel.java, PlotFormat.java

 

Java techniques of interest:

  • Compared to DropGenerator in Chapter 10: Physics, most of the additional code here simply deals with handling of the extra control components, i.e. the check boxes and text fields.

  • The itemStateChanged() method had to handle all of the different checkboxes

  • The different types of data are identified by the bits set in a header word in the data output file.

  • An image icon is put into the extra "slot" in the grid layout just to show how to do that. (Using a graphics program we made the gif image such that the area around the text and the two red balls was transparent.)
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;

/**
  * This program simulates an experiment in which measurements
  * are made during the fall of a mass in a constant gravitational
  * field. The measurements will be used in a separate analysis program
  * to determine the acceleration constant.
  *
  * This expands on the DropGenerator class in three ways:
  *
  * (1) The user can add an offset value to the position data.
  *     This simulates the sort of instrument effect that must
  *     be removed via a calibration procedure.
  *
  * (2) A "calibration run" option allows for data output for
  *     fixed known positions so that the analysis program can
  *     determine the proper calibration constants.
  *
  * (3) This program also allows for input of a "systematic error"
  *     The program multiplies the time data  by a value input by
  *     the user.
  *
**/
public class DropGenCalSysErr extends JApplet
             implements ActionListener, ItemListener
{

  // Set bits in constants to identify type of data.
  final static int RUN_SIM    = 0x1;  // Simulation
  final static int RUN_ADDCAL = 0x2;  // Include instrument constants
  final static int RUN_RUNCAL = 0x4;  // Calibration run
  final static int RUN_SYSERR = 0x8;  // Simulate systematic error

  int fRunType = RUN_SIM; // default run type.

  // The DropPanel displays the animation of the falling mass.
  DropPanelDetect fDropPanel;

  // The DropModel generates the physics data.
  DropModelDetect fDropModel;

  // Use a detector to measure the drop times.
  DropDetector3 fDetector;

  // File handling for the output ntuple data
  File fOutFile;
  String fOutFileName = "dropData.dat";
  DataOutputStream fDataOut;
  boolean fOutToFile = false;
  JCheckBox fFileCheckBox;
  JTextField fFileTextField;

  // Calibration items
  // Add calibration constant to position data.
  boolean fAddCalibration = false;
  JCheckBox fAddCalBox;

  // Run with calibration constant added but no smearing
  // and at fixed positions to simulate instrument
  // calibration. run
  boolean fRunCalibration = false;
  JCheckBox fRunCalBox;
  JTextField fCalTextField;

  // Calibration constant on position data.
  double fCalPos = 0.0;

  // Systematic errors
  boolean fAddSysErr = false;
  JCheckBox fAddSysErrBox;
  JTextField fSysErrTextField;

  // Value used to calculate the systematic error
  double fSysErr = 0.0;

  // Enumerated type used to direct output operations
  public enum OutputCmd {OUT_SETUP, OUT_WRITE, OUT_CLOSE}

  // Array to hold data for each drop
  double fData[][];

  // Use the java.util Timer and TimerTask combo
  // for timing events.
  java.util.Timer fTimer;

  // A text field for getting the number of drops for a
  // run and the position smearing std.dev. in cm.
  JTextField fMaxNumDropsField;
  JTextField fPosSigmaFactorField;

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

  //Buttons
  JButton fGoButton;   // start drop
  JButton fClearButton;// resets histogram
  JButton fExitButton;

   // Starting coordinates of drop
  double fXBallStart =  25.0; // cm
  double fYBallStart = 200.0; // cm
  double fYBallEnd   =   0.0; // cm

  // Range of the drop time.
  double fTStart = 0.00; // sec
  double fTEnd   = 0.75; // sec

  // Gausssian sigma for the measured values of the marker positions and t (sec).
  // (Default is 0.0 for time smearing.)
  double [] fMeasurementSigmas = {2.0, 0.0};

  // Integer and double arrays to pass info to the detector
  int []    fDetectorSetup;
  double [] fDetectorParameters;

  // Coordinate of ball.
  double fXBall;
  double fYBall;

  // Initial velocity.
  double fVyBallStart = 0.0;
  double fVxBallStart = 0.0;

  // Time in millisecs for the drop
  double fTDropTotal;
  double fTFrame = 0.020; // in secs

  // Speed up or slow down factor for animation:
  double fTFactor = 1.0;

  // Allow for multiple drops per "run"
  int fMaxNumDrops = 10;
  int fNumDrops = 0;

  // Number of times to measure the position during the drop.
  int fMaxNumMeasurements = 40;

  // Number of measurements actually taken for a given event.
  int fNumMeasures;

  /**
    *  Initialize the display. Create Detector and Model
    *  objects to use for the physics and experiment simulation.
    *  DropPanelDetect displays the dropping ball and the
    *  detector. Include the control and user input fields.
   **/
  public void init () {

    // Create a detector
    fDetector = new DropDetector3 ();

    // Need arrays to pass setup info to the detector.
    fDetectorSetup = new int[1];
    fDetectorSetup[0] = fMaxNumMeasurements;

    // Do a measurement for every frame
    fDetectorParameters = new double[1];
    fDetectorParameters[0] = fTFrame;

    // Pass the detector the necesary setup info
    fDetector.init (fDetectorSetup, fDetectorParameters, fMeasurementSigmas);

    // Create the drop physics model
    fDropModel = new DropModelDetect (fDetector);
    fDropModel.reset (fYBallStart, fVyBallStart);

    // Use a textfield to get the number of drops per run.
    fMaxNumDropsField =
      new JTextField (Integer.toString (fMaxNumDrops), 10);

    // Use a textfield to get smearing  (std.dev. in cm) of the position.
    fPosSigmaFactorField =
      new JTextField (Double.toString (fMeasurementSigmas[0]), 10);

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

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

    // Here the clear button will reset the plots
    fClearButton = new JButton ("Reset");
    fClearButton.addActionListener (this);

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

    JPanel control_panel = new JPanel (new GridLayout (5,2));
    JPanel panel1 = new JPanel (new GridLayout (1,2));
    JPanel panel2 = new JPanel (new GridLayout (1,3));

    panel1.add (fMaxNumDropsField);
    panel1.add (fPosSigmaFactorField);

    panel2.add (fGoButton);
    panel2.add (fClearButton);
    panel2.add (fExitButton);

    control_panel.add (panel1);  // control_panel -> 1, 1
    control_panel.add (panel2);  // control_panel -> 1, 2

    // Setup the output file
    fFileCheckBox = new JCheckBox ("File Output?");
    control_panel.add (fFileCheckBox); // control_panel -> 2, 1

    // Put the box on the right side of the box.
    fFileCheckBox.setHorizontalAlignment (SwingConstants.LEFT);
    fFileCheckBox.addItemListener (this);

    JPanel file_panel = new JPanel (new FlowLayout (SwingConstants.RIGHT));
    fFileTextField= new JTextField (fOutFileName,12);
    file_panel.add (new JLabel ("File:"));
    file_panel.add (fFileTextField);
    control_panel.add (file_panel); // control_panel -> 2, 2

    // Setup for systematic errors
    fAddSysErrBox = new JCheckBox ("Systematic Errors?");
    fAddSysErrBox.addItemListener (this);
    control_panel.add (fAddSysErrBox); // control_panel -> 3, 1
    fAddSysErrBox.setHorizontalAlignment (SwingConstants.LEFT);

    JPanel sys_err_panel = new JPanel (new FlowLayout (SwingConstants.RIGHT));
    fSysErrTextField= new JTextField ("0.0",12);
    sys_err_panel.add (new JLabel ("Sys Err:"));
    sys_err_panel.add (fSysErrTextField);
    control_panel.add (sys_err_panel); // control_panel -> 3, 2

    // Setup for adding calibration constants
    fAddCalBox = new JCheckBox ("Add calibration?");
    fAddCalBox.addItemListener (this);
    control_panel.add (fAddCalBox); // control_panel -> 4, 1
    fAddCalBox.setHorizontalAlignment (SwingConstants.LEFT);

    JPanel cal_input_panel = new JPanel (new FlowLayout (SwingConstants.RIGHT));
    cal_input_panel.add (new JLabel ("Cal:"));
    fCalTextField = new JTextField ("0.0", 12);
    cal_input_panel.add (fCalTextField);
    control_panel.add (cal_input_panel);  // control_panel -> 4, 2


    // Setup for calibration run control.
    fRunCalBox = new JCheckBox ("Run calibration?");
    fRunCalBox.addItemListener (this);
    control_panel.add (fRunCalBox); // control_panel -> 5, 1
    fRunCalBox.setHorizontalAlignment (SwingConstants.LEFT);

    // Use an image in a label to fill the last slot in the grid layout.
    java.net.URL img_url = DropGenCalSysErr.class.getResource ("dropLabel.gif");
    ImageIcon icon =  null;
    if (img_url != null) {
       icon = new ImageIcon (img_url);
    } else {
      System.err.println ("Image icon not found!");
    }
    JLabel controls_label;
    if (icon != null)
       controls_label = new JLabel (icon);
    else
       controls_label = new JLabel ("Drop Controls");
    control_panel.add (controls_label); // control_panel -> 5, 2
    controls_label.setHorizontalAlignment(SwingConstants.CENTER);

    // Create an instance of the DropPanel
    // Make the panel 10% taller than starting position.
    fDropPanel = new DropPanelDetect (fYBallStart*1.1, 0.0, fDetector);

    setLayout (new BorderLayout ());
    add (fDropPanel, "Center");
    add (control_panel, "South");

  } // init

  /** Stop the timer if the browser page unloaded. */
  public void stop () {
    runDone ();
  } // stop

  /**
    *  Respond to the buttons. For a click on "Drop" button,execute
    *  the number of drops in the text field.
    *  Obtain values from the text fields for the the smearing factor.
    *  calibration constant, and systematic error factor.
    *  The Reset button clears the plots and resets the drop stats.
   **/
  public void actionPerformed (ActionEvent e) {
    Object source = e.getSource ();
    if (source == fGoButton) {
      if (fGoButton.getText ().equals ("Drop")) {
        try {
          fMaxNumDrops =
            Integer.parseInt (fMaxNumDropsField.getText ());

          // Get new sigma for position smearing
          fMeasurementSigmas[0] =
            Double.parseDouble (fPosSigmaFactorField.getText ());

          // Update the position smearing
          fDetector.init (fDetectorSetup, fDetectorParameters,
                        fMeasurementSigmas);
          if (fAddCalibration) {
            fCalPos = Double.parseDouble (fCalTextField.getText ());
            fDetector.setCalibration (true, fCalPos);
          }
          if (fAddSysErr) {
            fSysErr = Double.parseDouble (fSysErrTextField.getText ());
            fDetector.setSysErrors (true, fSysErr);
          }
        }
        catch (NumberFormatException ex) {
          // Could open an error dialog here but just
          // display a message on the browser status line.
          if ( fInBrowser)
              showStatus ("Bad input value");
          else
              System.out.println ("Bad input value");
          return;
        }
        dropReset ();
        fGoButton.setText ("Stop");
        fClearButton.setEnabled (false);

      } else {
          // Stop without finishing the current drop.
          runDone ();
      }
    } else if (source == fClearButton) {
        repaint ();
    } else if (!fInBrowser)
        System.exit (0);
  } // actionPerformed


  /**
    * Respond to the file checkbox. If box checked,
    * then open the file for output. Use file name
    * given in the text field on the interface.
   **/
  public void itemStateChanged (ItemEvent evt) {

      Object source = evt.getSource ();
      if (source == fFileCheckBox) {
        if (evt.getStateChange () == ItemEvent.SELECTED)
          fOutToFile = true;
        else
          fOutToFile = false;
      } else
      if (source == fAddCalBox) {
        if (evt.getStateChange () == ItemEvent.SELECTED) {
          try {
            fCalPos = Double.parseDouble (fCalTextField.getText ());
          }
          catch (Exception e) {
            JOptionPane.showMessageDialog (
                        null,
                        "Invalid calibration value!", "Bad Calibration Input",
                        JOptionPane.ERROR_MESSAGE);
            return;
          }

          fDetector.setCalibration (true, fCalPos);
          fAddCalibration = true;
        } else {
          fDetector.setCalibration (false, fCalPos);
          fAddCalibration = false;
        }
      } else
      if (source == fRunCalBox) {
        if (evt.getStateChange () == ItemEvent.SELECTED) {
          fDetector.setRunCalibration (true);
          fRunCalibration = true;
        } else {
          fDetector.setRunCalibration (false);
          fRunCalibration = false;
        }
      } else
      if (source == fAddSysErrBox) {
        if (evt.getStateChange () == ItemEvent.SELECTED) {
          try {
            fSysErr = Double.parseDouble (fSysErrTextField.getText ());
          }
          catch (Exception e) {
            JOptionPane.showMessageDialog (
                        null,
                        "Invalid systematic error value!", "Bad Sys Err Input",
                        JOptionPane.ERROR_MESSAGE);
            return;
          }
          fDetector.setSysErrors (true, fSysErr);
          fAddSysErr = true;
        } else {
          fDetector.setSysErrors (false, fSysErr);
          fAddSysErr = false;
        }
      }

  } // itemStateChanged


  /**
    * Use the inner class technique to define the
    * TimerTask subclass for stepping through the
    * drop calculation and the frame refresh.
    *
    * Use the real time in the drop calculation instead
    * of the given frame rate times in case there were
    * delays from thread interruptions, the processing
    * in the parts of the program take extra time, etc.
   **/
  class PaintHistTask extends java.util.TimerTask {
    public void run () {

      // Drop the ball
      fYBall = fDropModel.step (fTFactor * fTFrame);

      // Update the position of the ball in the
      // animation and redraw the frame.
      fDropPanel.updatePosition (fXBall, fYBall);

      // Check if ball has crossed the finish line.
      if (fYBall <= fYBallEnd) dropDone ();
    } // run
  } // PaintHistTask



  /**
    *  This method handles the output to the file.
    *  The ennumerated type OutputCmd indicates which
    *  operation: setup, writing each drop data set, and
    *  stream closeing should be executed.
   **/
  void outputToFile (OutputCmd output_cmd) {

    switch (output_cmd) {
      // Setup creats the File object and opens a stream to
      // the file.
      case OUT_SETUP:
        // Get file name from the text field
        fOutFileName = fFileTextField.getText ();
        // And created a File object for it
        fOutFile = new File (fOutFileName);

        try {
          // Open an output stream to the file.
          FileOutputStream file_output = new FileOutputStream (fOutFile);
          // Wrap the FileOutputStream with a DataOutputStream
          fDataOut = new DataOutputStream (file_output);

          // Create a header for the data file.
          // Begin with the type of run:
          fDataOut.writeInt (fRunType);
          // Post the current time.
          fDataOut.writeLong (System.currentTimeMillis());
          // The file will have no more than these number of drops
          // (could be less if run stopped early by the user)
          fDataOut.writeInt (fMaxNumDrops);
          // Add the maximum number of measurements per drop
          fDataOut.writeInt (fMaxNumMeasurements);
        }
        catch (FileNotFoundException fnfe) {
          System.out.println ("File Not Found = " + fnfe);
        }
        catch (IOException ioe) {
          System.out.println ("IO exception = " + ioe );
        }
        break;

      case OUT_WRITE:
        // Now write the data for this event.
        try {
          fDataOut.writeInt (fNumDrops); // drop number
          fDataOut.writeInt (fNumMeasures); // Number of measurements
          // Write the data as an position/time pair
          for (int i=0; i < fNumMeasures; i++) {
            fDataOut.writeDouble (fData[0][i]); // positions
            fDataOut.writeDouble (fData[1][i]); // times
          }
        }
        catch (IOException e) {
          System.out.println ("IO exception = " + e );
        }
        break;

      case OUT_CLOSE:
        // Close file when finished with it..
        try {
          fDataOut.close ();
        }
        catch (IOException e) {
          System.out.println ("IO exception = " + e );
        }
        break;
    }

  } // outputToFile


  /**
    *  Do the setup and then start the drops.
    *  Before each set of drops, need to create a new timer,
    *  and set up its schedule. The PaintHistTask innner class
    *  object will do the setup for each frame of a drop animation.
   **/
  void dropReset () {
    // Before starting the drop, create the timer task
    // that will cause the histogram display to update
    // during the filling.
    // Create a timer. TimerTask created in MakeHist ()
    fTimer = new java.util.Timer ();

    fDropModel.reset (fYBallStart, fVyBallStart);
    fDropPanel.reset (fXBallStart, fYBallStart);

    // Reset time sum
    fTDropTotal = 0.0;
    fNumDrops = 0;
    fYBall = fYBallStart;
    fXBall = fXBallStart;

    // Reset the detector.
    fDetector.reset ();

    repaint ();

    // A run can have several variations in its settings:
    fRunType = RUN_SIM;
    if (fAddCalibration) fRunType = fRunType | RUN_ADDCAL;
    if (fRunCalibration) fRunType = fRunType | RUN_RUNCAL;
    if (fAddSysErr)      fRunType = fRunType | RUN_SYSERR;

    if (fOutToFile) outputToFile (OutputCmd.OUT_SETUP);

    // Start the run by starting the timer after 20ms and then
    // repeat callsto run in PaintHistTask object by the rate
    // set by the fTFrame value.
    fTimer.schedule (new PaintHistTask (), 20, (int) (fTFrame*1000));

  } // dropReset

  /**
    *  Invoked after a drop ends bottom. Reset
    *  all the parameters to set up for another drop.
   **/
  public void dropDone () {
    // Get the data  (times and positions during the drop)
    // from the detector and analyze it
    fData = fDetector.getResults ();
    fNumMeasures = fDetector.getNumMeasurements ();
    ++fNumDrops;
    if (fOutToFile) outputToFile (OutputCmd.OUT_WRITE);

    // Check if all drops completed.
    if (fNumDrops == fMaxNumDrops){
      // If so then finish up the data recording
      // for this run and return.
      runDone ();
      return;
    }

    // Reset time sum
    fTDropTotal = 0.0;
    fYBall = fYBallStart;
    fXBall = fXBallStart;

    fDropPanel.reset (fXBallStart, fYBallStart);
    fDropModel.reset (fYBallStart, fVyBallStart);
    fDetector.reset ();

  } // dropDone


  /**
    *  Invoked when all the drops in a run  (set of drops) are done.
    *  Kills the timer to stop the animation.  (A new timer will be
    *  created in the dropReset () for the next run.)
   **/
  public void runDone () {

    // Stop the animation.
    fTimer.cancel ();

    // Reset the buttons.
    fGoButton.setText ("Drop");
    fClearButton.setEnabled (true);

    if (fOutToFile) outputToFile (OutputCmd.OUT_CLOSE);

  } // runDone

  /** Offer the option of running the applet in an app frame. */
  public static void main (String[] args) {
    //
    int frame_width=450;
    int frame_height=450;

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

    // Following anonymous class used to close window & exit program
    JFrame f = new JFrame ("Drop Test");
    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

} // DropGenCalSysErr
import java.awt.*;
import java.io.*;
import java.util.*;

/**
  *  This class extends DropDetector2 which simulates the measuring
  *  of the the position of a mass as it drops. This could be,
  *  for example, a spark strip chart recorder used in teaching labs.
  *
  *  DropDetector3 provides three enhancements on DropDetctor2.
  *
  *  (1) It offers  the option of including a position measurement
  *  offset to simulate the sort of instrument offset typically found
  *  in real life experiments. Before an analysis of the data can be
  *  done, a calibration of the data is needed to remove this offset.
  *
  *  (2) This class provides for a special "calibration" run. This does
  *  not involve the dropped mass but is an "artificial" set of values
  *  in which the position values are equally spaced.
  *  This simulates the sort of special instrument test done to allow
  *  the user to determine calibration constants.
  *
  *  (3) Finally, there is the option to include a "systematic error"
  *  on the time steps between the position measurements. Here the
  *  systematic error is a factor multiplying the timestep width. Subclasses
  *  can override the setSysErrors() method to implement other sorts
  *  of systematic effects.
 **/
public class DropDetector3 extends DropDetector2
                           implements Detector
{
  // Calibration setup
  boolean fDoCalibration = false;
  boolean fRunCalibration= false;

  // Constant offset used to demonstrate how an
  // instrument must be calibrated to remove
  // measurement artifacts.
  double  fPosCal = 0.0;
  double  fCalPosStep = 0.0;

  // Systematic error setup
  boolean fDoSysErr = false;
  // A constant that we will use for systematic
  // error studies.
  double fSysErr = 0.0;

  /**
    *  For the y and accumulated drop time, obtain the
    *  simulated measured time by a Gaussian smearing.
    *  Include calibration run option, adding calibration
    *  constants, and including systematic error.
    *
    *  @param vals - 2 element array with the y and time values.
   **/
  public void measure (double [] vals) {

    if (fNumMeasurements >= fMaxNumMeasurements) return;
    double time = vals[1];

    // Wait for measurement to cross threshold marker.
    if (time >= fDetectTime) {

      // Set new time threshold
      fDetectTime = fNumMeasurements * fTimeStep;

      // Only record points in the sensitive area.
      if (vals[0] > fYTopLimit || vals[0] < fYBotLimit) return;

      // If making a calibration run, use .
      if (fRunCalibration) {
        // For calibration runs, use fixed distance between measurements
        fPositions[fNumMeasurements] = fYTopLimit - fCalPosStep * fNumMeasurements;

        // Use time in detector.
        fTimes[fNumMeasurements] = fDetectTime;

      } else {
        // For normal drop data, record the vertical position of the mass
        // after the time step and smear the position measure by the given sigma.
        fPositions[fNumMeasurements] = vals[0];
        fPositions[fNumMeasurements] += fSigmas[0] * fRan.nextGaussian ();

        // Can smear time as well.
        fTimes[fNumMeasurements] = vals[1] +
                          fSigmas[1] * fRan.nextGaussian ();
      }

      // Include a constant instrument effect for each position measure.
      if (fDoCalibration) {
        doCalibration (fNumMeasurements);
      }

      // Include a systematic error on the measurements.
      if (fDoSysErr) {
        doSysErrors (fNumMeasurements);
      }
      fNumMeasurements++;
    }
  } // measure


  /**
    * Turn the calibration inclusion on or off. Here we use
    * only the simple case of a constant offset value added
    * to the position measurements.
   **/
  public void setCalibration (boolean do_cal, double cal_pos) {
    fDoCalibration = do_cal;
    fPosCal = cal_pos;
  } // setCalibration


  /** Include instrument offsets and nonlinearities here. **/
  void doCalibration (int pos_id) {
    // Add a constant value to the position measurement
    //simulate an instrument offset.
    fPositions[pos_id] += fPosCal;
  } // doCalibration


  /**
    * A calibration run would be a special set of measurements
    * made specifically to show the fixed position constant offset.
   **/
  public void setRunCalibration (boolean run_cal) {
    fRunCalibration = run_cal;

    // For calibration, use fixed step positions.
    if (fRunCalibration)
      fCalPosStep = (fYTopLimit - fYBotLimit)/fMaxNumMeasurements;

  } // setRunCalibration


  /** Add systematic errors to the experimental data. **/
  public void setSysErrors (boolean flag, double sys_error) {
    fDoSysErr = flag;
    fSysErr = sys_error;
  } // setSysErrors


  /**
    * Include a systematic error on time setting.
   **/
  void doSysErrors (int pos_id) {
    // Put an error on the time span.
    fTimes[pos_id] *= fSysErr;
  } // doSysErrors

} // DropDetector3

 

 

Most recent update: Nov. 8, 2005

              Tech
Fractals
Fractal Drawing
   Demo 1
Fractal Draw Code
Fractal Images
  Demo 2
Image Processing
  Demo 3
Histogram Image
  Demo 4
Exercises

           Physics
Calibration/SysError
SimWithCal/SysErr
  Demo 1
Analysis
  Demo 2
Examples

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.