[Feedback][Tutorial Contents][hep.lcd Home]

shoeline2[1].gif (1488 bytes)

Using the Event Shape and Jet Finding Utilities

There are utilities for finding jets and analyzing event shapes in the hep.lcd.physics package. The examples below show how to use this package.

Event Shape Analysis

The Jetset event shape and thrust routines have been converted to Java and can be found in the hep.lcd.physics.EventShape(in the API reference documentation) class. To use the utility it is first necessary to create EventShape object, and then to use its setEvent method to pass in the data to be analyzed. The argument to the setEvent method is an Enumeration of either 3-vectors (hep.lcd.physics.IHep3Vector(in the API reference documentation)) or 4-vectors (hep.lcd.physics.IHepLorentzVector(in the API reference documentation)), and optionally a hep.lcd.util.predicate.Predicate(in the API reference documentation) which is used to select which elements of the Enumeration are actually used in the event shape calculations. The example below passes an Enumeration of the MC truth particles to the setEvent method, along with a predicate which accepts only final-state, charger.particles.

import hep.analysis.*;
import hep.lcd.event.*;
import hep.lcd.util.predicate.*;
import hep.physics.*;
import hep.lcd.physics.*;
import java.util.*;

final public class ShapeAnalysis extends EventAnalyzer
{
   // Create an instance of the EventShape utility
   EventShape es = new EventShape();
   // Create a Predicate that accepts final state charged particles 
   Predicate predicate = new Predicate()
   {
      public boolean accept(Object in)
      {
         Particle p = (Particle) in;
         if (p.getStatusCode() != Particle.FINALSTATE) return false;
         if (p.getType().getCharge() == 0) return false;
         return true;
      }
   };
   public ShapeAnalysis()
   {
   }
   public void processEvent(final EventData d)
   {
      final LCDEvent event = (LCDEvent) d;

      // We will use the MC truth in this example
      ParticleVector pv = event.getMCParticles();
      es.setEvent(pv.particles(),predicate);
      histogram("Thrust").fill(es.thrust().x());
      histogram("Oblateness").fill(es.oblateness());
   }
}

Using the Jet Finder

The jet finder consists of an interface hep.lcd.physics.IJetFinder(in the API reference documentation) which is implemented by all jet finding algorithms, and a set of concrete jet finding algorithms. Currently there are two concrete JetFinder classes: hep.lcd.physics.JadeEJetFinder(in the API reference documentation) and  hep.lcd.physics.DurhamJetFinder(in the API reference documentation).  So far the JadeEJetFinder appears to work best for LCD events. To use a jet finder it is first necessary to create an instance of the the jet finder, and then invoke the setEvent method to pass it the data to be analysed. The argument(s) to the setEvent method is(are) the same as for the EventShape class described above. The following example program uses the same predicate as the previous example.

import hep.analysis.*;
import hep.lcd.event.*;
import hep.lcd.util.predicate.*;
import hep.physics.*;
import hep.lcd.physics.*;
import java.util.*;

final public class JetFinder extends EventAnalyzer
{
   // Create a JadeEJetFinder with a ycut of 0.02
   AbstractJetFinder jetFinder = new JadeEJetFinder(0.02);
   // Create a Predicate that accepts final state charged particles 
   Predicate predicate = new Predicate()
   {
      public boolean accept(Object in)
      {
         Particle p = (Particle) in;
         if (p.getStatusCode() != Particle.FINALSTATE) return false;
         if (p.getType().getCharge() == 0) return false;
         return true;
      }
   };
   public JetFinder()
   {
   }
   public void processEvent(final EventData d)
   {
      final LCDEvent event = (LCDEvent) d;

      // We will use the MC truth in this example to find jets
      ParticleVector pv = event.getMCParticles();

      jetFinder.setEvent(pv.particles(),predicate);
      // Fill some diagnostic histograms 
      histogram("Njets").fill(jetFinder.njets());
      histogram("Fewest Tracks").fill(jetFinder.fewestTracks());

      double totalJetEnergy = 0;
      double totalParticleEnergy = 0;
      for (int ijet =0; ijet<jetFinder.njets(); ijet++)
      {
         totalJetEnergy += jetFinder.jet(ijet).t();
         histogram("Jet Energy").fill(jetFinder.jet(ijet).t());
         histogram("Particles in Jet").fill(jetFinder.nParticlesPerJet(ijet));
         // loop over all the tracks in the jet, and add up there energy
         // (should be the same as the jet energy)
         double etot = 0;
         Enumeration e = jetFinder.particlesInJet(ijet);
         while (e.hasMoreElements()) 
            etot += ((Particle) e.nextElement()).getEnergy();
         histogram("Etot").fill(etot);
         totalParticleEnergy += etot;
      }
      histogram("Total Jet Energy").fill(totalJetEnergy);
      histogram("Total Particle Energy").fill(totalParticleEnergy);
   }
}

Displaying Jets on the Event Display

To display the found jets on the LCD event display it is only necessary to fill the jet vectors into the event header. This can be achived by adding the following three lines after the call to jetFinder.setEvent in the above example.

       Vector v = new Vector();
       for (int i=0; i<jetFinder.njets(); i++) 
          v.addElement(jetFinder.jet(i));
       event.put("Jets",v);

This should result in event displays looking something like this:

jet1.gif (8267 bytes)jet2.gif (6121 bytes)

Varying the JetFinder Y-Cut

This example shows how to vary the Jet Finders y-cut to create a histogram showing how the average number of jets varies as a functionm of y-cut. Note that the jet finder automatically reruns the jet finding algorithm when the y-cut is changed.

import hep.analysis.*;
import hep.lcd.event.*;
import hep.lcd.util.predicate.*;
import hep.physics.*;
import hep.lcd.physics.*;
import java.util.*;

final public class YCut extends EventAnalyzer
{
  // Create a DurhamJetFinder with a ycut of 0.02
   DurhamJetFinder jetFinder = new DurhamJetFinder(0.02);
   // Create a Predicate that accepts final state charged particles 
   Predicate predicate = new Predicate()
   {
      public boolean accept(Object in)
      {
         Particle p = (Particle) in;
         if (p.getStatusCode() != Particle.FINALSTATE) return false;
         if (p.getType().getCharge() == 0) return false;
         return true;
      }
   };
   public YCut()
   {
      histogram("NJets vs Y Cut").setPartition(new FixedMeanPartition(0,.1,50));
   }
   public void processEvent(final EventData d)
   {
      final LCDEvent event = (LCDEvent) d;

      // We will use the MC truth in this example to find jets		
      ParticleVector pv = event.getMCParticles();
      jetFinder.setEvent(pv.particles(),predicate);
      
      // Fill some diagnostic histograms 
		
      for (double ycut=0.001; ycut<0.1; ycut += 0.002)
      {
         jetFinder.setYCut(ycut);
         histogram("NJets vs Y Cut").fill(ycut,jetFinder.njets());
      }
   }
}