Chameleon Tutorial (Version 0.51)

Tutorial Authors:
Philip Schuster, Natalia Toro 

Harvard Blackbox Team:
Nima Arkani-Hamed, Matthew Baumgart, Clifford Cheung, Liam Fitzpatrick, Tom Hartman, Can Kilic, Philip Schuster, Jesse Thaler, Natalia Toro, Lian-Tao Wang 

Harvard University, Jefferson Laboratory
Nov 2, 2005

IMPORTANT: USER LEVEL SPEED-UP ADVICE

First, a disclaimer: This package is a Beta version of Chameleon.  The inclusive signature counting functions and many of the histograms in this Tutorial have been tested extensively against those produced by other members of the Harvard Black Box team with C- and Root-based analysis software.  We are still developing and testing the Chameleon package, however, and hope to add new features in the near future, improve performance, and add to the documentation in this Tutorial.  
Currently, Chameleon requires roughly 1 MB of memory to store 5000 lines from the PGS output files, with additional memory required for the creation of subarrays for the analysis.  For this reason, we recommend that large data sets be approached with caution.  The 5 (fb^(-1)) Harvard black box should not require more than 100 MB of memory, even with many subarrays defined.
Please contact Natalia Toro (toro@fas.harvard.edu) or Philip Schuster (schuster@fas.harvard.edu) with any possible bugs, feature suggestions, or questions about the Chameleon package or Tutorial.

Speeding Up Chameleon: Because Mathematica requires ~16 bytes per number, the total memory usage can be prohibitively large for data samples with more than 50,000 events. Consequently, run time for essentially all functions can be quite slow if they are applied to full data sets. The trick is to use smaller lists of events that have been constructed by applying good preselection criterion to the big data set. However, this won't avoid the initial file load time of a minute or so (for a 5 (fb^(-1))data set) depending on your machine capabilities. This also won't avoid the fact that 40 \(TraditionalForm\`\(\(fb\^\(-1\)\)\(\ \)\(samples\)\(\ \)\(may\)\(\ \)\(take\)\(\ \)\)\)up to 700MB of free memory (we're still working on this one). Useful speed up steps are outlined below.
1) Use event preselection (described in this the "advanced analysis" section of this tutorial) to define sublists of events that are of a smaller size (with ~1000-10,000 events). Multiple analyses of the sublists will take much less time than re-processing the large list each time.  You can still perform basic analysis on the full data set, but you might have to wait tens of seconds for histogram construction and minutes for inclusive counts.
2) Each time you turn on Mathematica to run Chameleon, you'll have to load in data sets all over again (and this is the most time consuming part of Chameleon). If you're doing a particular analysis that only requires events of a particular type (say di-lepton events), then you can use Chameleon to write your own smaller .dat files. That way, you can just read in the .dat files you care about with all the preselection you want done ahead of time. Usually, this means that the load in time is reduced to less than 10 seconds for most samples. Of course, you still have to go to the trouble of loading in the big data set at least once.

BASIC SETUP: Set directory, configure "master cuts", load data sets, basic checks

Files You Need to Download.

Before using Chameleon, you need to download a few files from the LHC olympics website:
     Chameleon0.51.m  contains the definitions of all functions we will use here.
     Chameleon0.51.nb is used to generate Chameleon0.51.m.  You don't need it to run this package, but if you want to improve on our functions or see how they're defined, you'll want to start here.  When you modify Chameleon0.51.nb, it should automatically update Chameleon0.51.m. 
     Data sets from the website or that you've generated yourself.  This package uses harvardbb_5.dat.   You can change the commands later in this section to read from other files.

Set Working Directory and Load the Chameleon Package

This command sets Mathematica's working directory, where it will look for all the files you need (Windows: you may need to use "\\" instead of "\").

\(\(\( (*SetDirectory["C:\Documents and Settings\NataliaT\LHC Olympics\webversion"]*) \)\(
\)\(SetDirectory["C:\Documents and Settings\Philip Schuster\My Documents\Projects\LHC Olympics"]\)\)\)

Now load the package:

<< "Chameleon0_51.m"

If you can't get this to work, uncomment the line below to bring up a file browser.  Ignore the warning about overwriting files--it won't.

Configure the "master" cuts

The cuts shown here are applied before any analysis is done.  Objects failing the minimum (Subscript[p, T]) and maximum |η| cuts are deleted from the data set.  PTCUT and ETACUT affect photons and leptons (e, μ, and τ), while PTCUTJET and ETACUTJET for jets are separate variables.  MISSINGPTCUT controls the minimum missing PT of an event for which a separate missing PT object is included in the listing, but events with lower missing PT remain in the data set.  After these objects have been removed from the event record, events with summed (Subscript[p, T]) less than EFFMASSCUT are also deleted from the data set. (Sublists can be created later that satisfy more stringent cuts).
IMPORTANT: After changing these cuts, you must reload all data sets for the changes to take effect! (If you do this, remember to also run fastReset[])

PTCUT = 25;
ETACUT = 2;
PTCUTJET = 50;
ETACUTJET = 3;
MISSINGPTCUT = 50;
EFFMASSCUT = 0;

Load One or More Data Files with the LoadEvents Command

This command imports the data in a file (.dat) or set of files (.dat.i, for i=0 to n) in the BlackBox output format and separates it into events.  It also deletes from the record objects that fail the "master" cuts defined above, and any events that are empty after this filtering.
To import a single data file, say "HarvardBB\harvardbb-all_5s.dat", and store it to the variable HarvBB, use
	HarvBB=LoadEvents["HarvardBB\\harvardbb_5.dat"];
To import from a set of files, use the "filename.dat.0", and add as a second argument the number of files to use.  This syntax would load the first 2 files:
	HarvBB=LoadEvents["HarvardBB\\harvardbb_5.dat.0",2];
Make sure you end this call with a semicolon, or Mathematica will freeze as it tries to print the whole event record to your screen!
If you enter an invalid filename, a file browser may (depending on your Mathematica version) appear to let you select a file.  When you do so, it will ask if you want to overwrite the existing file.  But don't worry! Your file will not be overwritten.

HarvBB = 
        LoadEvents["..\\calibration\\harvbb.dat.0"];

NOTE: The fastMake command (demonstrated in previous versions of the tutorial) stores intermediate data calculated by Chameleon, and reduces computation time for some calculations.  This syntax is still included in the Chameleon package, but we do not use it in the tutorial or distribution-creation notebooks.  If you want to use it, please see the section on fastMake in the function reference list below to avoid common errors.

If you want to compare several data sets, you can load each into a different list.

Check the Data Set

Let's take a look at the number of events in HarvBB and the first few objects in the first event.

Length[HarvBB]
ShowEvent[HarvBB, 1]
ShowEvent[HarvBB, 2]

Each object is a list of 8 numbers specifying its properties, each event is a list of objects, and HarvBB is a list of events!

EXAMPLES OF BASIC ANALYSIS (on the Harvard Black Box)

Inclusive Signatures

The RunInclusiveCount function displays several inclusive signatures.

RunInclusiveCounts[HarvBB]

More Simple Counting

Below, we explicitly construct several inclusive counts, many of which are included in the set produced by RunInclusiveCounts.  They are included here to show you how to generate them yourself or generalize them, and to introduce the notation used in the remainder of the program.

SpeciesCount tabulates the number of events in which a given species of object appears n times.  All object types begin with o, and most have long and short forms (a list of all object types is below (click on this link)).  For example, oL (or oLepton) matches a leptons of any type, e, μ, or τ.  Thus, the command below counts events with 0, 1, 2, 3, or 4 leptons.

SpeciesCount[HarvBB, oL, 5]

Counts number from 0 to 4 of oγ (oPhoton) objects in HarvBB.

SpeciesCount[HarvBB, oγ, 4]

Counts number from 0 to 8 of oJet objects.

SpeciesCount[HarvBB, oJet, 8]

Counts number from 0 to 5 of oBJet= B Jet objects.

SpeciesCount[HarvBB, oB = oBJet, 5]

SingleLeptonCount counts the total number of letpons of each type. The arguement is the event list, HarvBB in this case.

SingleLeptonCount[HarvBB]

DiLeptonCount tabulates a matrix of di-lepton counts in the event list, HarvBB.

DiLeptonCount[HarvBB]

Counting with Preselection

If we want to count events satisfying a more complicated criterion, we can use CriterionCount.  This counts all events with at least two jets and missing PT of at least 300.

CriterionCount[HarvBB, 
      and[NumOf[oJet]~ge~2, MissingPT~ge~300]]

To combine general criteria with the counting functions introduced above (e.g. SingleLeptonCount), we can use the Select function to consider only those events that satisfy a criterion.  These calls to SingleLeptonCount tabulates the number of events with 0 to 5 leptons and different numbers of jets:

No jets (NumOf[oJet]~eq~0):

SingleLeptonCount[Select[HarvBB, NumOf[oJet]~eq~0]]

At least 2 jets (NumOf[oJet]~ge~2)

DiLeptonCount[Select[HarvBB, NumOf[oJet]~ge~2]]

Similarly, we can count frequency of n-lepton, 2-photon events with

SpeciesCount[Select[HarvBB, NumOf[oγ]~eq~2], oLepton, 
      5]

Here's a more complicated example. oHard[patt, pThard] is a pattern that matches only objects of type patt with pT>pThard.
In the case below, Select picks out events that have at least one jet with pt greater than 200 GeV.

DiLeptonCount[Select[HarvBB, NumOf[oHard[oJet, 200]]~gt~0]]

Constructing Histograms at the Event Level (building up basic notation from simple histograms)

Histograms in Chameleon can be generated with the command Hist.  The first argument to Hist is a list of frequency data (generated by the helper function Freq or the dummy "function" Bin, which are explained below), and the second is a list specifying histogram range and number of bins.

If you want to save frequency data for repeated plotting or further manipulation, you can generate it with Freq:

Freq[evtList,crit,objsel,plotfunc,{min,max,nbins}] creates nbins bins between min and max, and counts elements of evtList satisfying criterion for which the value of plotfunc on the objects selected by objsel is within each bin.

This is best illustrated by example.  We construct several frequency data lists using Freq, then plot histograms with them.

Eff1 = 
        Freq[HarvBB, all, GetAll, 
          EffMass, {0, 3000, 50}];
Eff2 = 
        Freq[HarvBB, all, HGet[oJet, All], 
          EffMass, {0, 3000, 50}];
Inv1 = 
        Freq[HarvBB, all, GetAll, 
          InvMass, {0, 3000, 50}];
Inv2 = 
        Freq[HarvBB, LeptonContent[{1, -1}], GetAll, 
          InvMass, {0, 3000, 50}];
Inv3 = 
        Freq[HarvBB, LeptonContent[{1, -1}], HGet[oL, 2], 
          InvMass, {0, 3000, 50}];
Inv4 = 
        Freq[HarvBB, and[LeptonContent[{1, -1}], NumOf[oJet]~ge~2], 
          HGet[oL, 2], InvMass, {0, 3000, 50}];
Inv5 = 
        Freq[HarvBB, and[LeptonContent[{1, -1}], NumOf[oJet]~lt~2], 
          HGet[oL, 2], InvMass, {0, 3000, 50}];

List Eff1 is binned data for the total effective mass of each accepted event (the criterion "all" is always true, and GetAll[evt] returns the whole event).  EffMass returns the sum of pT's of all the objects it acts on (in this case, the whole event):
        Eff1=Freq[HarvBB,all,GetAll,EffMass,{0,3000,50}];

Hist[Eff1, {0, 3000, 50}];

In Eff2, we have changed the object selection to HGet[oJet,All], which selects all jets from an event.  Instead of plotting the sum of pTs (EffMass) of all objects in an event, we plot the sum of pTs of jets only.  But we're still looking at the same list of events. 
         Eff2=Freq[HarvBB,all,HGet[oJet,All],EffMass,{0,3000,50}];

Hist[Eff2, {0, 3000, 50}];

In the histogram above, had we entered a different range specification for the Hist and Freq commands, the histogram axes would have been labelled incorrectly.  When used inside a Hist call, the Bin "function" is interpreted as a Freq function, whose range is assumed to be the same as that of the histogram.  Thus, we could have generated the Eff1 graph with the code:

Hist[Bin[HarvBB, all, GetAll, EffMass],{0, 3000, 50}];

Similarly, Inv1 is binned data for the total invariant mass in all accepted events.
        Inv1=Freq[HarvBB,all,GetAll,InvMass,{0,3000,50}];

Hist[Inv1, {0, 3000, 50}];

In the definition of Inv2, we again evaluate the invariant mass of all objects in each event, but here we have restricted the set of events over which we calculate it: we tabulate the total invariant mass only of events with an e+, an e-, and no other leptons, specified by the LeptonContent command.
        Inv2=Freq[HarvBB,LeptonContent[{1,-1}],GetAll,InvMass,{0,3000,50}];

Hist[Inv2, {0, 3000, 50}];

Inv3 selects the same events as Inv2, but now instead of tabulating the invariant mass of all particles, we tabulate the invariant mass of the hardest two leptons (as we have selected events with precisely an e+ and an e- and no other leptons, it must always be computing the e+ e- invariant mass).
        Inv3=Freq[HarvBB,LeptonContent[{1,-1}],HGet[oL,2],InvMass,{0,3000,50}];

Hist[Inv3, {0, 3000, 50}];

Inv4 further restricts the set of events used in generating the histogram, requiring that they have ≥2 jets.
        Inv4=Freq[HarvBB,and[LeptonContent[{1,-1}],NumOf[oJet]~ge~2],HGet[oL,2],InvMass,{0,3000,50}];

Hist[Inv4, {0, 3000, 50}];

If we want to look at events with <2 jets and two leptons, we can use the data set Inv5:
          Inv5=Freq[HarvBB,and[LeptonContent[{1,-1}],NumOf[oJet]~ge~2],HGet[oL,2],InvMass,{0,3000,50}];

Hist[Inv5, {0, 3000, 50}];

...or we can subtract Inv4 from Inv3:

Hist[Inv3 - Inv4, {0, 3000, 50}];

By building your own event-selection criteria and functions to act on the selected events, or by further combining those built into Chameleon, you can make more complicated histograms quite easily.  Some of these are discussed in the following section.

MORE ADVANCED ANALYSIS (also on Harvard Black Box)

Histogram Analysis of OS Di-Lepton Events (Examples of Speed Up Tricks)

Let's do some event preselection by picking out events with a lepton content of {1,-1}={electron, positron} or {2,-2}={muon,anti-muon}and check the number of such events.

DA1 = 
        Select[HarvBB, 
          or[LeptonContent[{1, -1}], 
            LeptonContent[{2, -2}]]];
Length[DA1]

This is a good time to write this preselected list to a .dat file so that later we won't have to read in the full data set to reconstruct this list. We do this using Mathematica's Export[] command. We need to specify the file name (by deafult the file will be stored to the local directory that the user specifies at the beginning of the tutorial), the of the sublist, and the format ("Table" in all cases). We also need to flatten the list we want to write (DA1 in this case) to avoid read-in errors later on.

Export["harvbb5fb_OSDiLepton.dat", 
      Flatten[DA1, 1], "Table"]

Now let's pick out events from the above sample without any jets.

DA2 = Select[DA1, NumOf[oJet]~eq~0];
Length[DA2]

Now plot the invariant mass of the two leptons in the events from DA1. To pick out the objects in this case, we pick out the hardest positive lepton and negative lepton. oLP=positive lepton object, oLM=negative lepton object. HGet[{{oLP,1},{oLM,1}}] return these objects. InvMass acts on all of the objects that HGet returns.

Hist[
        Bin[DA1, all, HGet[{{oLP, 1}, {oLM, 1}}], InvMass], {0, 2000, 
          50}];

Let's do the same for DA2 (i.e. events with no jets). In this case, we pick out the hardest two lepton. HGet[oL,2] returns these objects. Both this and the above object selector do the same thing because our event selection made sure that there are exactly two leptons in each event.

Hist[
        Bin[DA2, all, HGet[oL, 2], InvMass], {0, 2000, 50}];

Let's now look at the ΔR distibution of the leptons. Again, we pick out the leptons by using HGet[oL,2].

Hist[Bin[DA2, all, HGet[oL, 2], DeltaR], {0, 6, 50}];

Now we'll cut on ΔR demanding that ΔR>3.14 and plot the invariant mass of the leptons for all events in the no jet sample (DA2) that pass this cut. Note the way that the argument for HGet is passed outside of DeltaR. We have to pass the argument for HGet outside of DeltaR because the argument for DeltaR is the output of HGet acting on an event (i.e. a list of two leptons in this case).

Hist[
        Bin[DA2, DeltaR[HGet[oL, 2][#]] &~gt~3.14, HGet[oL, 2], 
          InvMass], {0, 2000, 50}];

Let's apply the same ΔR cut on the Di-Lepton sample (DA1).

Hist[
        Bin[DA1, DeltaR[HGet[oL, 2][#]] &~gt~3.14, HGet[oL, 2], 
          InvMass], {0, 2000, 50}];

Hist Analysis of Di-Lepton + Di-Photon Events

Let's pick out events that have a lepton content of {1,-1}={electron,positron} or {2,-2}={muon,anti-muon} and exactly two photons. Do do this, we use NumOf[] and LeptonContent[] inside of an and[].

DB1 = 
      Select[HarvBB, 
        and[or[LeptonContent[{1, -1}], LeptonContent[{2, -2}]], 
          NumOf[oγ]~eq~2]]; Length[DB1]

Now we plot the distribution of the invariant mass of the two leptons with the two photons and the missing pt. For this, we pick out the events using HGet to take to two hardest leptons, the two hardest photons, and the missing pt. We use {oMPT,All} because we only want to include a missing pt object if it exists. If we used {oMPT,1} for example, HGet would crash in cases where there is no missing pt object in the event.

Hist[
        Bin[DB1, all, HGet[{{oL, 2}, {oγ, 2}, {oMPT, All}}], 
          InvMass], {0, 2000, 50}];

Let's do additional preselection by demanding no jets.

DB2 = Select[DB1, NumOf[oJet]~eq~0]; Length[DB2]

Having done this, let's plot the same invariant mass of the two leptons with the two photons and missing pt.

Hist[
        Bin[DB2, all, HGet[{{oL, 2}, {oγ, 2}, {oMPT, All}}], 
          InvMass], {0, 2000, 50}];

Perhaps we should look at the ΔR distribution of objects in this sample. There are several possible ΔR s, but let's try looking at lepton-photon pairs. For simplicity, let's plot the distribution of minimum ΔR between lepton-photon pairs in the DB2 sample. For this, we use the KTuples function do define all 2-tuples that have one lepton and one photon. This is done with KTuples[ 2, and[NumOf[oL]~eq~1,NumOf[oγ]~eq~1] ], which return all 2-tuples with exactly one lepton and one photon. We then use PickATuple to pick the tuple with the minimum DeltaR, PickATuple[ KTuples[... ], DeltaR ,-1]. Note that -1 specifies minimizing the function DeltaR (+1 would maximize). Finally, we place this command inside the Hist[Bin[...],{}] function to plot DeltaR of these 2-tuples. All of this could have been done by first defining a list of all such 2-tuples and then using it as the argument in place of DB2.

Hist[
        Bin[DB2, all, 
          PickATuple[KTuples[2, and[NumOf[oL]~eq~1, NumOf[oγ]~eq~1]], 
            DeltaR, -1], DeltaR], {0, 4, 50}];

Now let's select out events for wich the minimum DeltaR of lepton-photon pairs passes a cut ΔR<1. To do this, we use KTest to select events with a lepton-photon pair that has ΔR<1. The KTest syntax is similar to KTuples, but it returns true or false instead of a set of tuples. KTest is true whenever the list that KTuples would produce on the same arguments is nonempty.

DB3 = 
        Select[DB2, 
          KTest[2,      and[NumOf[oL]~eq~1, NumOf[oγ]~eq~1, 
              DeltaR~lt~1]    ]      ];

Plot the invariant mass of the leptons and photons on the ΔR-cut sample DB3.

Hist[
        Bin[DB3, all, HGet[{{oL, 2}, {oγ, 2}, {oMPT, All}}], 
          InvMass], {0, 2000, 50}];

Let's use KTest for someting else. Let's select out events for which the two lepton have ΔR>3. DB2 already contains events with exactly two leptons, so we can just assume that in KTest. The criterion we'll use is and[NumOf[oL]~eq~2,DeltaR~gt~3]. This argument goes inside KTest[2, crite...].

DB4 = 
        Select[DB2, 
          KTest[2,      and[NumOf[oL]~eq~2, 
              DeltaR~gt~3]    ]      ];

Now let's plot the invariant mass of both lepton, the photons, and the missing pt.

Hist[
        Bin[DB4, all, HGet[{{oL, 2}, {oγ, 2}, {oMPT, All}}], 
          InvMass], {0, 2000, 50}];

In this sample, let's look at the ivariant mass of the hardest lepton with the second hardest photon. Note that to pick out the second hardest photon, extra brackets are needed. HGet[{oγ,2}] would pick out the two hardest photons whereas HGet[{oγ,{2}}] picks out the second hardest photon.

Hist[
        Bin[DB3, all, HGet[{{oL, 1}, {oγ, {2}}}], InvMass], {0, 2000, 
          50}];

Simple Hist Analysis of 2 b Jets and Photons

Preselect to pick out events with two B jets, at least one non-B jet, and at least two photons.

DC1 = 
      Select[HarvBB, 
        and[NumOf[oB]~eq~2, NumOf[oNonB]~gt~0, NumOf[oγ]~gt~1]]; 
    Length[DC1]

Plot the invariant mass of the two B jets.

Hist[Bin[DC1, all, HGet[oB, 2], InvMass], {0, 700, 40}];

Plot the invariant mass of the hardest B with the hardest photon.

Hist[
        Bin[DC1, all, HGet[{{oB, 1}, {oγ, {1}}}], InvMass], {0, 1000, 
          40}];

Plot the invariant mass of the hardest B with the second hardest photon.

Hist[
        Bin[DC1, all, HGet[{{oγ, {2}}, {oBJet, 1}}], EffMass], {0, 
          1000, 40}];

More Advanced Hist Analysis of 2 b jet-photon events

Let's create a sublist to work with:

TwoGTwoB = 
      Select[HarvBB, and[NumOf[oBJet]~eq~2, NumOf[oγ]~eq~2]]; 
    Length[TwoGTwoB]

Here we look at the invariant mass of the bjet-photon pair in each event with the lowest DeltaR:
OrdTuples produces a list of bjet-photon pairs (we could also have done this using KTuples[2,and[NumOf[oBJet]~eq~1,NumOf[oγ]~eq~1]]), and PickATuple sorts them in order of decreasing DeltaR, and picks the last one.

Hist[
        Bin[TwoGTwoB, all, 
          PickATuple[OrdTuples[2, {oBJet, oγ}], DeltaR, -1], 
          InvMass], {0, 500, 40}];

We could instead look at all bjet-photon pairs whose DeltaR is less than 2 (the notation (DeltaR[#]<2&) defines an unnamed function that returns True if DeltaR of its argument is less than 2, and the combination patt?criterion is matched only by expressions that match patt and satisfy criterion).

Hist[
      Bin[TwoGTwoB, all, 
        OrdTuples[2, {oBJet, oγ}?(DeltaR[#] < 2 &)], InvMass], {0, 
        500, 40}]

A more sophisticated delta-R cut could be imposed if we expect that the two b's are coming from the same source, but make no assumptions about the gammas.  We can then test whether the gammas are correlated in DeltaR with the B's, and the total invariant mass:

BDRCut[cut_][{B1_, 
            B2_, γ1_, γ2_}] := (DeltaR[{B1, B2}] < 
            cut);

DRGamma[{B1_, B2_, γ1_, γ2_}] := 
        DeltaR[{B1, γ1}];

Hist[ .5 Bin[TwoGTwoB, all, 
            OrdTuples[
              4, {oBJet, oBJet, oγ, oγ}?(BDRCut[2])], 
            DRGamma], {0, 8, 40}];

Hist[ .25 Bin[TwoGTwoB, all, 
            OrdTuples[
              4, {oBJet, oBJet, oγ, oγ}?(BDRCut[2])], 
            InvMass], {0, 1500, 40}];

In doing this sort of analysis, it is easy to double-count.  For example, because all permutations of 4-object sublists of an event are matched to the pattern {oBJet,oBJet,oγ,oγ}, we are actually quadruple-counting the same group of objects.  This is why we multiply the Bin functions by 0.25 in the graph above.  In the DRGamma graph, we are actually only double-counting, because {B1,B2,γ1,γ2} and {B1,B2,γ2,γ1} result in different DRGamma, but we are plotting two quantities per event on the same graph.

STANDARD INCLUSIVE SIGNATURES AND DISTRIBUTIONS (for Harvard Black Box)

Inclusive Signatures

The RunInclusiveCount function displays several inclusive signatures.

Timing[RunInclusiveCounts[HarvBB]]

Standard Distributions

Distribution of missing pt for 0 lepton events with greater than or equal to 4 jets.

H1 = 
        Hist[Bin[HarvBB, and[NumOf[oL]~eq~0, NumOf[oJet]~gt~3], 
            HGet[oMPT, All], MissingPT], {0, 700, 50}];

G1 = 
        Show[H1, Frame -> True, 
          FrameLabel -> {StyleForm["Missing PT", 
                FontSize -> 14, FontWeight -> "Bold"], 
              StyleForm["", FontSize -> 14, 
                FontWeight -> "Bold"]}];

Distribution of \(TraditionalForm\`M\_eff\ for\ 0\ lepton\ and\ greater\ than\ or\ equal\ to\ 4\ \(\(jets\)\(.\)\)\)

H2 = 
        Hist[Bin[HarvBB, and[NumOf[oL]~eq~0, NumOf[oJet]~gt~3], 
            HGet[{{oJet, All}, {oMPT, All}}], EffMass], {0, 3000, 
            50}];

\(\(G2 = 
        Show[H2, Frame -> True, 
          FrameLabel -> {StyleForm[\*""\!\(M\_eff\)"", 
                FontSize -> 14, FontWeight -> "Bold"], 
              StyleForm["", FontSize -> 14, 
                FontWeight -> "Bold"]}];\)\)

Distribution of invariant mass of Oposite sign dileptons (muon or electron) with at least two jets in the event

H3 = 
        Hist[Bin[HarvBB, 
            and[NumOf[oJet]~ge~2, 
              or[LeptonContent[{1, -1}], LeptonContent[{2, -2}]]], 
            HGet[oL, 2], InvMass], {0, 400, 50}];

G3 = 
        Show[H3, Frame -> True, 
          FrameLabel -> {StyleForm["OS dilepton invariant mass", 
                FontSize -> 14, FontWeight -> "Bold"], 
              StyleForm["", FontSize -> 14, 
                FontWeight -> "Bold"]}];

Distribution of invariant mass of OS dilepton (muon or electron) with no jets in the event.

H4 = 
        Hist[Bin[HarvBB, 
            and[NumOf[oJet]~eq~0, 
              or[LeptonContent[{1, -1}], LeptonContent[{2, -2}]]], 
            HGet[oL, 2], InvMass], {0, 2500, 50}];

G4 = 
        Show[H4, Frame -> True, 
          FrameLabel -> {StyleForm["OS dilepton invariant mass", 
                FontSize -> 14, FontWeight -> "Bold"], 
              StyleForm["", FontSize -> 14, 
                FontWeight -> "Bold"]}];

Distribution of invariant mass of \(e\^+\)\(e\^-\) + \(TraditionalForm\`\(μ\^+\) \(μ\^-\)\)- \(TraditionalForm\`\(e\^+\) \(μ\^-\)\)- \(TraditionalForm\`\(e\^-\) \(μ\^+\)\)

NA = 
        Freq[HarvBB, 
          and[NumOf[oJet]~gt~1, 
            or[LeptonContent[{1, -1}], LeptonContent[{2, -2}]]], 
          HGet[oL, 2], InvMass, {0, 400, 50}];
NB = 
        Freq[HarvBB, 
          and[NumOf[oJet]~gt~1, 
            or[LeptonContent[{1, -2}], LeptonContent[{-1, 2}]]], 
          HGet[oL, 2], InvMass, {0, 400, 50}];

H5 = Hist[NA - NB, {0, 400, 50}];

G5 = 
        Show[H5, Frame -> True, 
          FrameLabel -> {StyleForm["OS dilepton invariant mass", 
                FontSize -> 14, FontWeight -> "Bold"], 
              StyleForm["", FontSize -> 14, 
                FontWeight -> "Bold"]}];

Distribution of invariant mass of hardest b jest in events with two b jets.

H6 = 
        Hist[Bin[HarvBB, NumOf[oBJet]~eq~2, HGet[oBJet, 2], InvMass], {0, 
            2000, 50}];

G6 = 
        Show[H6, Frame -> True, 
          FrameLabel -> {StyleForm["invariant mass of b jets", 
                FontSize -> 14, FontWeight -> "Bold"], 
              StyleForm["", FontSize -> 14, 
                FontWeight -> "Bold"]}];

FUNCTION REFERENCE LIST

Object Types (patterns)

Built-in patterns

Chameleon uses Mathematica pattern-matching to determine the (purported) identities of objects in an event listing.  Each pattern can be given in a long or short form.
The lepton patterns are:

oElectron=oE (matches e+or e-)
oElectronPlus=oEP (matches only e+)
oElectronMinus=oEM (matches only e-)
oElectron=oμ (matches μ+or μ-)
oElectronPlus=oμP (matches only μ+)
oElectronMinus=oμM (matches only μ-)
oElectron=oτ (matches τ+or τ-)
oElectronPlus=oτP (matches only τ+)
oElectronMinus=oτM (matches only τ-)
oLepton=oL(matches any lepton)
oLeptonPlus=oLP(matches any l+)
oLeptonMinus=oLM(matches any l-)

Leptons can also be referred to by a number between -3 and +3 (generation number × charge), as

oLeptonType[-1] =  oElectronMinus;
oLeptonType[1] =  oElectronPlus;
oLeptonType[-2] =  oMuonMinus;
oLeptonType[2] =  oMuonPlus;
oLeptonType[-3] =  oTauMinus;
oLeptonType[3] =  oTauPlus;

Photons and jet patterns are

oPhoton = oγ (matches photons)
oJet (matches any jet)
oBJet =oB (matches a b-tagged jet)
oNonBJet = oNonB (matches a jet that was not  tagged as a b

PGS also includes as an object the missing PT of an event.  If it is greater than MISSINGPTCUT, this object remains in the listing processed by Chameleon, and matches

oMissingPT=oMPT

A few additional patterns are

oAny (matches any properly formed object, including missing pt)
oNot[oType] (matches any object that doesn't match type oType.  For example,oNot[oLepton] matches jets,photons,and missing pt)
oHard[oType, pthard] (matches an object of type oType with pt ⩾ pthard)
oLessHard[oType, pthard] (matches an object of type oType with pt < pthard)

Creating your own kinematically constrained patterns

The oHard function above creates a kinematically constrained pattern from an unconstrained pattern (e.g. the pattern "electron with pT>30 GeV" from the pattern "electron").
It is possible to create your own constrained patterns using Mathematica's pattern?criterion construction, which matches only things that match pattern and satisfy the Boolean function criterion.  Thus, for example, if you are interested in looking at particles well separated from the beamline, you can define the function 
         EtaRestrict[etaMax_][obj_]:=(etaOf[obj]>0 && etaOf[obj]<etaMax)
and then use oJet?EtaRestrict[1.5] the same way you would use any other pattern.

Building criteria

A number of functions that can assist in creating criteria for object or ktuple selection or for event selection are listed here.
The trivial criterion is all, and is satisfied by anything.

Kinematic and object-counting functions

etaOf[obj], phiOf[obj], and ptOf[obj] return the values of eta, phi, and pT determined by PGS for any object. 
DeltaR[{obj1,obj2}] returns \(TraditionalForm\`\(\(\@\(\((ϕ1 - ϕ2)\)\^2 + \((η1 - η2)\)\^2\)\)\(.\)\)\)
InvMass[objList] returns the invariant mass obtained by treating all constituents as massless and summing their four-momenta.
EffMass[objList] returns the effective mass obtained by summing the pT of all constituents.
MissingPT[objList] returns the missing energy in an event, if any.
NumOf[patt][objList] returns the number of objects in objList that match the pattern patt, which can be any of the patterns described above (e.g. NumOf[oJet])

Comparison functions and predefined criteria

The functions eq (=), gt (>), lt (<), ge (≥), le (≤) compare the value of any function on an object list to a numerical value, and can be used as infixes.
For example, eq is defined as eq[attr_,n_][objList_]:=attr[objList]==n.  These functions can be used to generate criteria such as NumOf[oL]~le~2 or 
MissingPT~ge~100, which are True on events containing at most 2 leptons or, in the second case, for those with large missing PT.   They can be written in infix notation, as above, or in conventional function notation as le[NumOf[oL],2] and ge[MissingPT,100].  The construct "NumOf[oL]~le~2" is itself a function, which acts on an object list (such as an event, or a collection of objects selected from an event) and returns True or False.

The functions and and or can be used to join criteria (and[crit1 ,crit2][x]=crit1[x] && crit2[x], or[crit1 ,crit2][x]=crit1[x] || crit2[x]).  For example, and[NumOf[oL]~eq~2 , MissingPT~gt~200] is a function (again, acting on an object list) that returns true on events that have precisely 2 leptons and missing PT > 200.

To assist in cutting on leptonic content of events, the following are shortcuts to search for specific lepton content.

LeptonContent[leptonlist][objList] returns True if the number of leptons in objList of each type matches the number of times it appears in leptonlist, where each lepton is deonoted in leptonlist by a number (+1, +2, +3) for positive-charge e, μ, and τ, (-1, -2, -3) for negative-charge e, μ, and τ.  For example, LeptonContent[{1,1,-2}][objList]returns true when the leptons in objList are precisely two e+ and one μ-.
OSDiLepton[objList] returns True if the lepton content of objList is precisely two opposite-sign, same-flavor leptons (e+e-, μ+μ-, or τ+τ-).  It is equivalent to the composite criterion or[LeptonContent[{-1,1}],LeptonContent[{-2,2}],LeptonContent[{-3,3}]] (not to and[NumOf[oLP]~eq~1, NumOf[oLM]~eq~1], which does not demand that the leptons be of the same flavor.
SSDiLepton[objList] returns True if the lepton content of objList is precisely two same-sign, same-flavor leptons

Selecting objects from an event

In a function that inputs an object selection function, if you would like to just use the whole list, the function GetAll will do this.

In many, cases, we would like to apply some function to a collection of objects in an event, for example calculating the invariant mass of all jets in an event, or of the two hardest leptons.  The simplest way to select these objects is with the function HGet, which can be used in several different modes:

HGet[patt, n][evt] returns the hardest n objects in the "event" evt that match a pattern patt
	HGet[patt, -n][evt]    "      softest n     "          "           "    
	HGet[patt,All][evt] returns all objects in evt that match patt
	HGet[patt,{k1,k2...,km}][evt] returns k1'th,k2'th,..km'th hardest objects matching patt
	HGet[{{patt1,n},{patt2,{k}},{patt3,-n}}][evt] joins what you'd get from acting on each pair separately.

For example, HGet[oγ,2] selects the 2 hardest photons from an event, and HGet[{{oγ,2},{oB,{2}}}] selects both the 2 hardest photons and the 2nd-hardest b-tagged jet.
Note also that HGet will fail (sometimes badly) if you try to HGet something that doesn't exist (for example, three leptons in a di-lepton event), so you should always select for events that have the proper content, or use HGet[patt, All].

The FGet function is a generalization of HGet, in which the user specifies the function used to rank elements.  The syntax is similar:

FGet[func,patt,n][evt] returns the n elements of evt that maximize func
FGet[func,patt,-n][evt] returns the n elements of evt that minimize func 
FGet[func,patt,{n}][evt] returns the element of evt with the n'th highest func
FGet[[func,patt,All][evt] returns all of evt
FGet[{{func1,patt1,n},{func2,patt2,{k}},...}][evt] joins what you'd get by applying FGet to each triplet

Thus, FGet[ptOf,patt, n][evt] is equivalent to HGet[patt, n][evt].

Another more powerful means of object selection is through the use of KTuples.  Whereas HGet only allows selection based on the properties of the individual objects, KTuples can be selected based on functions on all the objects.  The simplest (and fastest) such function is KTuples, and the related KTest:

KTuples[k,crit][objList] forms a list of all (unordered) sublists of objList of length k that satisfy crit.
KTest[k,crit][objList] returns True if there exists a sublist of objList of length k that satisfy crit.

For example, KTuples[2,NumOf[oLepton]~eq~2][objList] selects all pairs of leptons from an event.  One can then act on these pairs with InvMass and plot this in a histogram. KTuples[4,and[NumOf[oJet]~eq~2,NumOf[oγ]~eq~2,InvMass~ge~100]][objList] selects groups of four objects from an event--two jets and two photons-- with the constraint that their total invariant mass be greater than or equal to 100 GeV.

A more powerful but more time-consuming variation is OrdTuples.  This tries to match all permutations of k-sublists to a pattern (which can be of the form patt?criterion for more sophisticated selection, as in some of the examples above)

OrdTuples[k,patt][objList] forms a list of permuted k-subsets from ordList that match patt.
OrdTest[k,patt][objList] returns true if there exists a (possibly permuted) subset of ordList that matches patt.

This allows us to define criteria and functions that are not symmetric on the elements of the -tuple, but depend on the species in question.  For example, we can define the criterion LeptonDRCut[lplus_,lminus_,photon1_,photon2_]:=(DeltaR[{lplus,lminus}]>3) and OrdTuples[4,{oLP,oLM,oγ,oγ}?LeptonDRCut] will pick out dilepton diphoton groups from an event that satisfy this criterion.

In many cases, we want to choose not all the -tuples that exist, but the one that optimizes some function.  For this, we can use PickATuple: the first argument TupleFunc acts on evt to return a list of tuples.  They are then ranked according to sortf (first elt. maximizes sortf, last minimizes it, etc) and chosen as in HGet:

PickATuple[TupleFunc,sortf,n][evt] creates a list of tuples by calling TupleFunc, and picks the ones with the n highest (or -n lowest) values of sortf among them
PickATuple[TupleFunc,sortf,{k1,k2,...,km}][evt]creates a list of tuples by calling TupleFunc, and picks the ones with the ki'th highest values of sortf among them

Counting and Histogramming

Further documentation may be added later.  For now, please see the examples above.

fastMake

Usage and Caveats

The  fastMake command is executed as in the example below:
      fastReset[];
PrelimHarvBB = LoadEvents["HarvardBB\\harvardbb_5.dat"];
HarvBB = fastMake[PrelimHarvBB];
When Chameleon runs analysis on HarvBB, it stores the results of some intermediate calculations, thereby speeding up some analysis.  Aside from this feature, analyses on HarvBB are identical to those on PrelimHarvBB.  When used appropriately,  fastMake can make some routines (such as the inclusive counts) run 2-4 times faster than they would otherwise.  But there are a few caveats to its use, namely:
1. If you use fastMake as above, you should also include the fastReset[]; command, which was not included in earlier tutorials, and was added in Chameleon 0.51.  This prevents Chameleon from keeping intermediate results on previous data sets and mistakenly associating them with a new data set.  Not running fastReset[]; may produce incorrect output!
2. Running analysis on HarvBB defined with fastMake can make some procedures run up to 10 times slower than they would on PrelimHarvBB.  This seems to be particularly true when KTuples or OrdTuples are used. 
3.  Using fastMake can also further obscure the error messages resulting from improper syntax (which are cryptic to begin with).  When debugging, we recommend either running commands on the raw event list (PrelimHarvBB) or bypassing  fastMake altogether by storing the LoadEvents output directly to HarvBB.

How fastMake works

When  fastMake is called in the example above, it creates a list with elements fast(PrelimHarvBB,i) (note that these are associated to the name PrelimHarvBB, not to the data stored in PrelimHarvBB).  Functions acting on the "fast" variables HarvBB[[i]] evaluate the function on PrelimHarvBB[[i]], but the return values of certain functions (LeptonContent,NumOf) are also saved.  Thus, if NumOf[oE][fast(PrelimHarvBB,i)] is called more than once, the first call will evaluate NumOf[oE][PrelimHarvBB[[i]]], while all subsequent calls just look up the result in a table.  In a function call such as RunInclusiveCounts, where many of the same functions are evaluated many times over, this results in appreciable time savings.
Now, the problems: 
1.  When PrelimHarvBB is overwritten (say, because you have changed the master cuts, or a different data file is being used), the lookup table associated with the name PrelimHarvBB is not reset.  So NumOf[oE][HarvBB[[i]]] will only evaluate NumOf on the new data set if there is no stored data from the old data set with the same name.  If there is stored data, NumOf assumes it to be up-to-date, which in this case it is not.  The safest way to avoid this problem is by deleting all stored data whenever a new data set is loaded (this is what fastReset[] does).  Also, if you are working with multiple data sets, they must have both unique "fast" data set names (e.g. HarvBB and TTBar) and unique raw data set names (PrelimHarvBB and PrelimTTBar).
2.  We don't understand why the slowdowns mentioned above happen well enough to say definitively when it is faster to use a list generated by fastMake, and when it isn't.  We have found the "fast" lists faster for inclusive counts, and slower for KTuple and OrdTuple operations, but this is only heuristic. If execution speed of a particular command is a concern, we recommend timing the command with both HarvBB and PrelimHarvBB as inputs, to see which is faster.