[Feedback][Tutorial Contents][Welcome Page]
In the previous tutorial you used a pre-written analysis module to analyze some MC data and create histograms. In this tutorial we will show you how to write your own analysis routines, and how to understand the structure of the LCD data.
When you write analysis code in Java Analysis Studio you normally create a
new class, such as MyAnalysis
which extends a base class called
EventAnalyzer. EventAnalyzer is a sort of no-op analysis which provides the
framework for doing analysis, but doesn't actually do any specific
analysis. For LCD analysis your main routine normally extends Driver
instead of EventAnalyzer. Driver adds some LCD specific functionality to the
EventAnalyzer class. By extending Driver your MyAnalysis
class
automatically inherits all of the framework, but can extend it to actually do
some useful analysis. Typically you do this by overriding a single method called
process. The process method is called by the framework each time a new event is
ready for analysis.
Lets look in detail now at the process method from the previous tutorial, and go through it line by line explaining what is going on.
// Called by the framework to process each event public void process(LCDEvent event) {
The first line declares the process method. It must be public (so the framework can call it) and void (it doesn't return anything). The argument to the process method is the event to be analyzed. Since the Driver class is specific to LCD, the event passed to the process method is an LCDEvent.
LCDEvent is defined as part of the hep.lcd classes, and is an event header
that occurs in each LCD event. From the LCDEvent class it is possible to
navigate to the rest of the event data. There are a lot of classes defined in
hep.lcd, but you will not need to refer to most of the classes unless you want
to write your own reconstruction modules. To do data analysis you just need to
know about the relatively few hep.lcd.event classes, of which LCDEvent is one.
You can find detailed documentation on the hep.lcd.event classes here.
In the rest of this tutorial we will include a link to the detailed
documentation on new classes as we introduce them, like this: LCDEvent.
Continuing with our analysis routine:
// Loop over the MC particles ParticleVector list = event.getMCParticles(); Enumeration e = list.particles(); double etot = 0; while (e.hasMoreElements()) {
The first line here declares a variable called list, which is a
reference to an object of type ParticleVector.
This variable is initialized to refer to a ParticleVector object, obtained from
the LCDEvent by calling the getMCParticles() method. Since we want to loop over
all of the particles we must first obtain an Enumeration
of the particles. An Enumeration is a built-in Java class that makes it easy to
loop over collections of objects without knowing about the detailed organization
of the collection. The while loop is used to actually do the looping.
MCParticle mc = (MCParticle) e.nextElement(); // histogram particle energy double energy = mc.getEnergy(); histogram("Particle Energy").fill(energy);
The first line here assigns the variable mc to point to the current MCParticle.
MCParticle is an LCD specific class which extends the general purpose Particle
class. Most of the useful methods are defined as part of the Particle class. In
this example we extract the energy of the particle using the getEnergy() method,
and then create a histogram of the particle energy. Note that it takes only one
line to declare and fill a histogram, which makes adding histograms to programs
in Java Analysis Studio very straightforward.
In more detail what is happening here is that we are calling a method called
histogram which takes a String argument (the histogram name) and returns a Histogram
object, we are then calling the fill method of the Histogram object, which takes
a single numeric argument (the value to fill into the histogram). The histogram
method is a framework method that our class inherited from the EventAnalyzer
class. It looks for a named histogram and returns a reference to the
corresponding Histogram object. If a Histogram of the given name does not exist
it creates a new Histogram and returns that.
// reject non final state particles histogram("Particle Status").fill(mc.getStatusCode()); if (mc.getStatusCode() != mc.FINALSTATE) continue;
In the next lines of the program we create and fill another histogram, this time with the particle status code (which can be one of FINALSTATE, INTERMEDIATE or DOCUMENTATION). We reject the particle if it is not a final state particle. The continue statement causes execution to switch to the next iteration of the while loop without executing the rest of the body of the while loop.
// reject neutral particles ParticleType type = mc.getType(); int charge = (int) type.getCharge(); histogram("Particle Charge").fill(charge); if (charge == 0) continue;
These lines are very similar to the last set, this time we are getting the
particles charge, histogramming it and rejecting neutral particles. The
MCParticle class does not have a getCharge() method, but instead has a getType()
method that returns a ParticleType
object, from which we can extract the charge.
// Some more histograms String name = type.getName(); histogram("Particle Type").fill(name); // Create a folder for each particle type HistogramFolder.setDefaultFolder("/"+name); histogram("Energy").fill(energy); HistogramFolder.setDefaultFolder("/");
Here we extract the name of the particle type as a String,
and histogram it (JAS allows you to histogram Strings and Dates as well as ints,
floats and doubles). We also exploit the capability to create folders containing
histograms by using the HistogramFolder
class to create a folder for each particle type, and inside that folder we
create a histogram of particle energy for that particular type of particle.
The remainder of the process method should be self-explanatory, we add each particles energy to etot, and then finally, outside the while loop, we fill a histogram of etot.
etot += energy; } histogram("Etot").fill(etot); }
Finally lets look at the entire analysis routine to see what boilerplate code we need to make a complete analysis routine.
import hep.analysis.*; import hep.physics.*; import hep.lcd.util.driver.*; import hep.lcd.event.*; import java.util.*; public class MyAnalysis extends Driver { // Called by the framework to process each event public void process(LCDEvent event) { // Loop over the MC particles ParticleVector list = event.getMCParticles(); Enumeration e = list.particles(); double etot = 0; while (e.hasMoreElements()) { MCParticle mc = (MCParticle) e.nextElement(); // histogram particle energy double energy = mc.getEnergy(); histogram("Particle Energy").fill(energy); // reject non final state particles histogram("Particle Status").fill(mc.getStatusCode()); if (mc.getStatusCode() != mc.FINALSTATE) continue; // reject neutral particles ParticleType type = mc.getType(); int charge = (int) type.getCharge(); histogram("Particle Charge").fill(charge); if (charge == 0) continue; // Some more histograms String name = type.getName(); histogram("Particle Type").fill(name); // Create a folder for each particle type HistogramFolder.setDefaultFolder("/"+name); histogram("Energy").fill(energy); HistogramFolder.setDefaultFolder("/"); etot += energy; } histogram("Etot").fill(etot); } }
The full name of the LCDEvent class (for instance) is hep.lcd.event.LCDEvent. To avoid having to always specify the entire long name each time we use it, we can use the import statement. The import statement is used to import a namespace into the current routine, so that the abbreviated name can be used. In this case we start the routine by importing five namespaces, hep.lcd.event (used for LCDEvent, CalorimeterHits and CalorimeterHit classes), java.util (used for Enumeration), hep.analysis (used for Histogram and EventAnalyzer), hep.physics (used for Particle, ParticleVector and ParticleType) and hep.lcd.util.driver (used for Driver)..
Next we declare the class itself, in this case called MyAnalysis, which as we
have explained before extends the framework routine Driver.
The class must be declared public for JAS to be able to access it. There is no
explicit constructor declared for the class since Java always assumes a
zero-argument public constructor if none is specified. If we needed to do some
initialization we could do it in the body of the class constructor.
The remaining tutorials in this series contain several more examples of writing analysis routines. Other resources that may be useful: