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
|