Shower Deconstruction
==============================

To compile this, execute:

./configure --with-fastjet=[Fastjet directory]

(substituting [Fastjet directory] with the appropriate path for where Fastjet is installed)

The actual code can be compiled with:

make

The libraries will be in the .libs directory.
To link this to your code, use the flags -L[THISDIRECTORY]/.libs -lDeconstruction and remember to add this directory to your include path.


Example code
===============================

There is an example code that generates Z prime particles decaying into hadronic tops, makes a C/A R=1.0 jet, takes the leading jet, makes
sub-jets from its constituents with kt R=0.2 and feeds the leading 9 sub-jets to SD.
It can be compiled by adjusting the HepMC, Pythia 8, Fastjet and ROOT paths in compile_test.sh and running:
source compile_test.sh

Execute with ./TestAnalysis --help to see your options.

One can also include --prefix=[dir] in configure and then call make install to install the libraries generated in the
directory to be used in an outside analysis.


Library usage
================================

TestAnalysis shows an example of how to use the ShowerDeconstruction code.

One needs to setup the ShowerDeconstruction parameters, by creating an AnalysisParameter instance:

AnalysisParameters *param = new AnalysisParameters("input_card.dat");

One can change the parameters in input_card.dat, or one can create the object and set the parameters
manually in the code:

AnalysisParameters *param = new AnalysisParameters();
(*param)["R"] = 1.0;                                 // R value of the seed jet
(*param)["lambda_mu_ext"] = 1.0;
(*param)["lambda_thetha_ext"] = 1.0;
(*param)["fractionISR_of_hardInt_PT"] = 0.5;
(*param)["noISR"] = 0.0;
(*param)["topmass"] = 172.0;                         // top quark mass in GeV
(*param)["topwindow"] = 50.0;                        // window around top mass to consider in GeV
(*param)["wmass"] = 80.403;                          // W boson mass in GeV
(*param)["wwindow"] = 20.0;                          // window around W boson mass to consider in GeV
(*param)["Higgsmass"] = 125.0;                       // Higgs boson mass in GeV
(*param)["delta_Higgsmass"] = 20.0;                  // window around Higgs boson mass to consider in GeV
(*param)["br_wqq"] = 0.6666666666;                   // Branching Ratio of W->qq'
(*param)["useBtag"] = 0;                             // Use b-tagging information
(*param)["tagprob"] = 0.7;                           // average b-tagging efficiency
(*param)["fakeprob"] = 0.01;                         // average b-tagging fake rate

One needs then to set up the signal and background model representation objects, as well as a model for the
ISR:

WModel = new Deconstruction::WDecayModel(*param);       // W->qq model
topModel = new Deconstruction::TopGluonModel(*param);   // top-gluon model
bkgModel = new Deconstruction::BackgroundModel(*param); // QCD multijet model
isrModel = new Deconstruction::ISRModel(*param);        // ISR model

The main object can be setup as follows (in this example, using the top model as signal):

Deconstruction::Deconstruct deconstruct = new Deconstruction::Deconstruct(*param, *topModel, *bkgModel, *isrModel);

Finally, given an input object "jet", one can calculate the ShowerDeconstruction weight by
making sub-jets from the constituents of the seed jet and then feeding the four-momenta of the subjets
to the Deconstruct object, as it can be seen in the following example.

double runShowerDeconstruction(const fastjet::PseudoJet &jet) {
  if(jet.constituents().size() == 0) return -999;

  fastjet::JetDefinition microjet_def(fastjet::cambridge_algorithm, 0.2); // make sub-jets with R=0.2
  fastjet::ClusterSequence microjet_cs(jet.constituents(), microjet_def);
  float pt_cut = 20; // cut on sub-jet pT of 20 GeV, for example

  // make sub-jets
  std::vector<fastjet::PseudoJet> microjets = fastjet::sorted_by_pt(microjet_cs.inclusive_jets(pt_cut));

  // if there are too many subjets, take only the leading 9 sub-jets, to limit time taken in SD
  if(microjets.size() > 9) {
    microjets.erase(microjets.begin() + (int) 9, microjets.begin() + microjets.size());
  }

  double chi = -100; // to hold the result of SD

  // chi is the ratio of signal and background weights
  // Deconstruct also returns the sum of signal and background weights for convenience
  double wSignal = -100, wBackground = -100;

  chi = deconstruct->deconstruct(microjets, wSignal, wBackground);

  // now return the logarithm of chi
  double lchi = -100;
  if (chi > 0) lchi = std::log(chi);

  return lchi;
}

The full code above looks as follows:



#include <Deconstruct.h>
#include <AnalysisParameters.h>
#include <TopGluonModel.h>
#include <WDecayModel.h>
#include <BackgroundModel.h>
#include <ISRModel.h>

#include <fastjet/PseudoJet.hh>
#include <fastjet/ClusterSequence.hh>

#include <vector>

std::vector<fastjet:PseudoJet> clusterJetsInEvent(); // this is not shown here: this is where your input enters

// defined below
double runShowerDeconstruction(const fastjet::PseudoJet &jet);

int main(int argc, char **argv) {

  AnalysisParameters *param = new AnalysisParameters();
  (*param)["R"] = 1.0;                                 // R value of the seed jet
  (*param)["lambda_mu_ext"] = 1.0;
  (*param)["lambda_thetha_ext"] = 1.0;
  (*param)["fractionISR_of_hardInt_PT"] = 0.5;
  (*param)["noISR"] = 0.0;
  (*param)["topmass"] = 172.0;                         // top quark mass in GeV
  (*param)["topwindow"] = 50.0;                        // window around top mass to consider in GeV
  (*param)["wmass"] = 80.403;                          // W boson mass in GeV
  (*param)["wwindow"] = 20.0;                          // window around W boson mass to consider in GeV
  (*param)["Higgsmass"] = 125.0;                       // Higgs boson mass in GeV
  (*param)["delta_Higgsmass"] = 20.0;                  // window around Higgs boson mass to consider in GeV
  (*param)["br_wqq"] = 0.6666666666;                   // Branching Ratio of W->qq'
  (*param)["useBtag"] = 0;                             // Use b-tagging information
  (*param)["tagprob"] = 0.7;                           // average b-tagging efficiency
  (*param)["fakeprob"] = 0.01;                         // average b-tagging fake rate

  WModel = new Deconstruction::WDecayModel(*param);       // W->qq model
  topModel = new Deconstruction::TopGluonModel(*param);   // top-gluon model
  bkgModel = new Deconstruction::BackgroundModel(*param); // QCD multijet model
  isrModel = new Deconstruction::ISRModel(*param);        // ISR model

  Deconstruction::Deconstruct deconstruct = new Deconstruction::Deconstruct(*param, *topModel, *bkgModel, *isrModel);

  std::vector<fastjet:PseudoJet> jets = clusterJetsInEvent(); // this is to be done elsewhere

  for (int k = 0; k < jets.size(); ++k) {
    double log_chi = runShowerDeconstruction(jets[k]);
    // histogram log_chi here
  }
  return 0;
}

double runShowerDeconstruction(const fastjet::PseudoJet &jet) {
  if(jet.constituents().size() == 0) return -999;

  fastjet::JetDefinition microjet_def(fastjet::cambridge_algorithm, 0.2); // make sub-jets with R=0.2
  fastjet::ClusterSequence microjet_cs(jet.constituents(), microjet_def);
  float pt_cut = 20; // cut on sub-jet pT of 20 GeV, for example

  // make sub-jets
  std::vector<fastjet::PseudoJet> microjets = fastjet::sorted_by_pt(microjet_cs.inclusive_jets(pt_cut));

  // if there are too many subjets, take only the leading 9 sub-jets, to limit time taken in SD
  if(microjets.size() > 9) {
    microjets.erase(microjets.begin() + (int) 9, microjets.begin() + microjets.size());
  }

  double chi = -100; // to hold the result of SD

  // chi is the ratio of signal and background weights
  // Deconstruct also returns the sum of signal and background weights for convenience
  double wSignal = -100, wBackground = -100;

  chi = deconstruct->deconstruct(microjets, wSignal, wBackground);

  // now return the logarithm of chi
  double lchi = -100;
  if (chi > 0) lchi = std::log(chi);

  return lchi;
}


