Index: modules/CscClusterEfficiency.cc
===================================================================
--- modules/CscClusterEfficiency.cc	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
+++ modules/CscClusterEfficiency.cc	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
@@ -0,0 +1,115 @@
+/*
+ *  Delphes: a framework for fast simulation of a generic collider experiment
+ *  Copyright (C) 2012-2014  Universite catholique de Louvain (UCL), Belgium
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ /** \class CscClusterEfficiency
+  *
+  *  This module is specific to the CMS paper searching for neutral LLPs in the CMS endcap muon detectors: https://arxiv.org/abs/2107.04838
+  *  It is implemented based on the ClusterEfficiency parameterization function provided in the HEPData entry of the paper: https://www.hepdata.net/record/104408
+  *
+  *  \author Christina Wang
+  *
+  */
+
+#include "modules/CscClusterEfficiency.h"
+
+#include "classes/DelphesClasses.h"
+#include "classes/DelphesFactory.h"
+#include "classes/DelphesCscClusterFormula.h"
+
+#include "ExRootAnalysis/ExRootClassifier.h"
+#include "ExRootAnalysis/ExRootFilter.h"
+#include "ExRootAnalysis/ExRootResult.h"
+
+#include "TDatabasePDG.h"
+#include "TFormula.h"
+#include "TLorentzVector.h"
+#include "TMath.h"
+#include "TObjArray.h"
+#include "TRandom3.h"
+#include "TString.h"
+
+#include <algorithm>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+
+using namespace std;
+
+//------------------------------------------------------------------------------
+
+CscClusterEfficiency::CscClusterEfficiency() :
+  fFormula(0), fItInputArray(0)
+{
+  fFormula = new DelphesCscClusterFormula;
+}
+
+//------------------------------------------------------------------------------
+
+CscClusterEfficiency::~CscClusterEfficiency()
+{
+  if(fFormula) delete fFormula;
+}
+
+//------------------------------------------------------------------------------
+
+void CscClusterEfficiency::Init()
+{
+  // read CscClusterEfficiency formula
+  fFormula->Compile(GetString("EfficiencyFormula", "1.0"));
+
+  // import input array
+
+  fInputArray = ImportArray(GetString("InputArray", "ParticlePropagator/stableParticles"));
+  fItInputArray = fInputArray->MakeIterator();
+
+  // create output array
+
+  fOutputArray = ExportArray(GetString("OutputArray", "stableParticles"));
+}
+
+//------------------------------------------------------------------------------
+
+void CscClusterEfficiency::Finish()
+{
+  if(fItInputArray) delete fItInputArray;
+}
+
+//------------------------------------------------------------------------------
+
+void CscClusterEfficiency::Process()
+{
+  Candidate *candidate;
+  Double_t Ehad, Eem, decayR, decayZ;
+
+  fItInputArray->Reset();
+  while((candidate = static_cast<Candidate *>(fItInputArray->Next())))
+  {
+    const TLorentzVector &candidateDecayPosition = candidate->DecayPosition;
+    decayZ = abs(candidateDecayPosition.Z());
+    decayR = sqrt(pow(candidateDecayPosition.X(),2)+pow(candidateDecayPosition.Y(),2));
+    Ehad = candidate->Ehad;
+    Eem = candidate->Eem;
+    // apply an efficency formula
+    if(gRandom->Uniform() > fFormula->Eval(decayR, decayZ, Ehad, Eem)) continue;
+
+
+    fOutputArray->Add(candidate);
+  }
+}
+
+//------------------------------------------------------------------------------
Index: modules/CscClusterEfficiency.h
===================================================================
--- modules/CscClusterEfficiency.h	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
+++ modules/CscClusterEfficiency.h	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
@@ -0,0 +1,60 @@
+/*
+ *  Delphes: a framework for fast simulation of a generic collider experiment
+ *  Copyright (C) 2012-2014  Universite catholique de Louvain (UCL), Belgium
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CscClusterEfficiency_h
+#define CscClusterEfficiency_h
+
+
+
+/** \class CscClusterEfficiency
+ *
+ *  This module is specific to the CMS paper searching for neutral LLPs in the CMS endcap muon detectors: https://arxiv.org/abs/2107.04838
+ *  It is implemented based on the ClusterEfficiency parameterization function provided in the HEPData entry of the paper: https://www.hepdata.net/record/104408
+ *
+ *  \author Christina Wang
+ *
+ */
+#include "classes/DelphesModule.h"
+
+class TIterator;
+class TObjArray;
+class DelphesCscClusterFormula;
+
+class CscClusterEfficiency: public DelphesModule
+{
+public:
+  CscClusterEfficiency();
+  ~CscClusterEfficiency();
+
+  void Init();
+  void Process();
+  void Finish();
+
+private:
+  DelphesCscClusterFormula *fFormula; //!
+
+  TIterator *fItInputArray; //!
+
+  const TObjArray *fInputArray; //!
+
+  TObjArray *fOutputArray; //!
+
+  ClassDef(CscClusterEfficiency, 1)
+};
+
+#endif
Index: modules/CscClusterId.cc
===================================================================
--- modules/CscClusterId.cc	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
+++ modules/CscClusterId.cc	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
@@ -0,0 +1,132 @@
+/*
+ *  Delphes: a framework for fast simulation of a generic collider experiment
+ *  Copyright (C) 2012-2014  Universite catholique de Louvain (UCL), Belgium
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ /** \class CscClusterId
+  *
+  *  This module is specific to the CMS paper searching for neutral LLPs in the CMS endcap muon detectors: https://arxiv.org/abs/2107.04838
+  *  It is implemented based on the cut_based_id.py function provided in the HEPData entry of the paper: https://www.hepdata.net/record/104408
+  *  to reproduce the cut-based ID efficiency of the CMS paper.
+  *
+  *  \author Christina Wang
+  *
+  */
+
+#include "modules/CscClusterId.h"
+
+#include "classes/DelphesClasses.h"
+#include "classes/DelphesFactory.h"
+#include "classes/DelphesCscClusterFormula.h"
+
+#include "ExRootAnalysis/ExRootClassifier.h"
+#include "ExRootAnalysis/ExRootFilter.h"
+#include "ExRootAnalysis/ExRootResult.h"
+
+#include "TDatabasePDG.h"
+#include "TFormula.h"
+#include "TLorentzVector.h"
+#include "TMath.h"
+#include "TObjArray.h"
+#include "TRandom3.h"
+#include "TString.h"
+
+#include <algorithm>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include "assert.h"
+using namespace std;
+
+//------------------------------------------------------------------------------
+
+CscClusterId::CscClusterId() :
+  fFormula(0), fEtaFormula(0), fItInputArray(0)
+{
+  fFormula = new DelphesCscClusterFormula;
+  fEtaFormula = new DelphesCscClusterFormula;
+}
+
+//------------------------------------------------------------------------------
+
+CscClusterId::~CscClusterId()
+{
+  if(fFormula) delete fFormula;
+  if(fEtaFormula) delete fEtaFormula;
+}
+
+//------------------------------------------------------------------------------
+
+void CscClusterId::Init()
+{
+  // read efficiency formula
+
+  fFormula->Compile(GetString("EfficiencyFormula", "1.0"));
+  fEtaFormula->Compile(GetString("EtaCutFormula", "1.0"));
+  fEtaCutMax = GetDouble("EtaCutMax", 999.0);
+
+  // import input array
+
+  fInputArray = ImportArray(GetString("InputArray", "ParticlePropagator/stableParticles"));
+  fItInputArray = fInputArray->MakeIterator();
+
+  // create output array
+
+  fOutputArray = ExportArray(GetString("OutputArray", "stableParticles"));
+}
+
+//------------------------------------------------------------------------------
+
+void CscClusterId::Finish()
+{
+  if(fItInputArray) delete fItInputArray;
+}
+
+//------------------------------------------------------------------------------
+
+void CscClusterId::Process()
+{
+  Candidate *candidate;
+  Double_t Ehad, Eem, decayR, decayZ, NStationEff, eta, eta_cut;
+  Int_t avgStation;
+  Double_t signPz, cosTheta;
+
+  fItInputArray->Reset();
+  while((candidate = static_cast<Candidate *>(fItInputArray->Next())))
+  {
+    const TLorentzVector &momentum = candidate->Momentum;
+    const TLorentzVector &candidateDecayPosition = candidate->DecayPosition;
+    decayZ = abs(candidateDecayPosition.Z());
+    decayR = sqrt(pow(candidateDecayPosition.X(),2)+pow(candidateDecayPosition.Y(),2));
+    Ehad = candidate->Ehad;
+    Eem = candidate->Eem;
+
+    cosTheta = TMath::Abs(momentum.CosTheta());
+    signPz = (momentum.Pz() >= 0.0) ? 1.0 : -1.0;
+    eta = (cosTheta == 1.0 ? signPz * 999.9 : momentum.Eta());
+
+    // calculate the NStation > 1 efficiency, implemented according to Additional Figure 8 in HEPData
+    NStationEff = fFormula->Eval(decayR, decayZ, Ehad);
+
+    // depending on the decay region (station Number), different eta cut is applied, implemented based on cut_based_id.py in HEPData
+    float eta_cut = fEtaFormula->Eval(decayR, decayZ);
+    if(gRandom->Uniform() > NStationEff*(abs(eta)<fEtaCutMax)+(1.0-NStationEff)*(abs(eta)<eta_cut)) continue;
+
+    fOutputArray->Add(candidate);
+  }
+}
+
+//------------------------------------------------------------------------------
Index: modules/CscClusterId.h
===================================================================
--- modules/CscClusterId.h	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
+++ modules/CscClusterId.h	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
@@ -0,0 +1,60 @@
+/*
+ *  Delphes: a framework for fast simulation of a generic collider experiment
+ *  Copyright (C) 2012-2014  Universite catholique de Louvain (UCL), Belgium
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CscClusterId_h
+#define CscClusterId_h
+
+/** \class CscClusterId
+ *
+ *  This module is specific to the CMS paper searching for neutral LLPs in the CMS endcap muon detectors: https://arxiv.org/abs/2107.04838
+ *  It is implemented based on the cut_based_id.py function provided in the HEPData entry of the paper: https://www.hepdata.net/record/104408
+ *
+ *  \author Christina Wang
+ *
+ */
+#include "classes/DelphesModule.h"
+
+class TIterator;
+class TObjArray;
+class DelphesCscClusterFormula;
+
+class CscClusterId: public DelphesModule
+{
+public:
+  CscClusterId();
+  ~CscClusterId();
+
+  void Init();
+  void Process();
+  void Finish();
+
+private:
+  DelphesCscClusterFormula *fFormula; //!
+  DelphesCscClusterFormula *fEtaFormula; //!
+  Double_t fEtaCutMax;
+
+  TIterator *fItInputArray; //!
+
+  const TObjArray *fInputArray; //!
+
+  TObjArray *fOutputArray; //!
+
+  ClassDef(CscClusterId, 1)
+};
+
+#endif
Index: modules/LLPFilter.cc
===================================================================
--- modules/LLPFilter.cc	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
+++ modules/LLPFilter.cc	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
@@ -0,0 +1,212 @@
+/*
+ *  Delphes: a framework for fast simulation of a generic collider experiment
+ *  Copyright (C) 2012-2014  Universite catholique de Louvain (UCL), Belgium
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** \class LLPFilter
+ *
+ *  Filter LLPs with particular PDG ID/status and calculate the EM and hadronic energy of LLP based on decay particles
+ *  The classification of EM and hadronic energy of LLP is based on instructions from the HEPData entry for the CMS paper searching
+ *  for neutral LLPs in the CMS endcap muon detectors: https://www.hepdata.net/record/104408
+ *  Muons and neutrinos are ignored. Photons, electrons, and pi0 are EM energy and everything else is hadronic energy.
+ *
+ *  \author Christina Wang
+ *
+ */
+
+#include "modules/LLPFilter.h"
+
+#include "classes/DelphesClasses.h"
+#include "classes/DelphesFactory.h"
+#include "classes/DelphesFormula.h"
+
+#include "ExRootAnalysis/ExRootClassifier.h"
+#include "ExRootAnalysis/ExRootFilter.h"
+#include "ExRootAnalysis/ExRootResult.h"
+
+#include "TDatabasePDG.h"
+#include "TFormula.h"
+#include "TLorentzVector.h"
+#include "TMath.h"
+#include "TObjArray.h"
+#include "TRandom3.h"
+#include "TString.h"
+
+#include <algorithm>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+
+using namespace std;
+
+//------------------------------------------------------------------------------
+
+LLPFilter::LLPFilter() :
+  fItInputArray(0)
+{
+}
+
+//------------------------------------------------------------------------------
+
+LLPFilter::~LLPFilter()
+{
+}
+
+//------------------------------------------------------------------------------
+
+void LLPFilter::Init()
+{
+
+  ExRootConfParam param;
+  Size_t i, size;
+
+  // PT threshold
+  fPTMin = GetDouble("PTMin", 0.0);
+
+  fInvert = GetBool("Invert", false);
+  fDaughterNumber = GetInt("DaughterNumber", 0);
+  fRequireDecayRegion = GetBool("RequireDecayRegion", 0);
+
+  fDecayRegionRMax = GetDouble("DecayRegionRMax", 0.0); //mm
+  fDecayRegionRMin = GetDouble("DecayRegionRMin", 0.0); //mm
+  fDecayRegionZMax = GetDouble("DecayRegionZMax", 0.0); //mm
+  fDecayRegionZMin = GetDouble("DecayRegionZMin", 0.0); //mm
+  fDecayRegionEtaMax = GetDouble("DecayRegionEtaMax", 0.0); // requirement on abs(eta)
+  fDecayRegionEtaMin = GetDouble("DecayRegionEtaMin", 0.0); //requirement on abs(eta)
+
+
+  // no pileup
+  fRequireNotPileup = GetBool("RequireNotPileup", false);
+
+  fRequireStatus = GetBool("RequireStatus", false);
+  fStatus = GetInt("Status", 1);
+
+  fRequireCharge = GetBool("RequireCharge", false);
+  fCharge = GetInt("Charge", 1);
+
+  // import input array
+  fInputArray = ImportArray(GetString("InputArray", "Delphes/allParticles"));
+  fItInputArray = fInputArray->MakeIterator();
+
+  fParticleInputArray =  ImportArray(GetString("InputArray", "Delphes/allParticles"));
+  fItParticleInputArray = fParticleInputArray->MakeIterator();
+
+
+  param = GetParam("PdgCode");
+  size = param.GetSize();
+
+  // read PdgCodes to be filtered out from the data card
+
+  fPdgCodes.clear();
+  for(i = 0; i < size; ++i)
+  {
+    fPdgCodes.push_back(param[i].GetInt());
+  }
+
+  // create output array
+  fOutputArray = ExportArray(GetString("OutputArray", "filteredParticles"));
+}
+
+//------------------------------------------------------------------------------
+
+void LLPFilter::Finish()
+{
+  if(fItInputArray) delete fItInputArray;
+}
+
+//------------------------------------------------------------------------------
+
+void LLPFilter::Process()
+{
+
+  Candidate *candidate;
+  Int_t pdgCode;
+  Bool_t pass;
+  Double_t pt, eta;
+  Candidate *tempCandidate;
+
+  Candidate *daughter;
+  Int_t daughterPdg;
+
+
+  // loop over particles to find LLP
+  fItInputArray->Reset();
+  int index = -1;
+  while((candidate = static_cast<Candidate *>(fItInputArray->Next())))
+  {
+    index++;
+
+    //all distance units are in mm
+    pdgCode = candidate->PID;
+    const TLorentzVector &candidateMomentum = candidate->Momentum;
+    const TLorentzVector &candidateProdPosition = candidate->Position;
+    const TLorentzVector &candidateDecayPosition = candidate->DecayPosition;
+    pt = candidateMomentum.Pt();
+    eta = candidateMomentum.Eta();
+    if(pt < fPTMin) continue;
+    if (fDaughterNumber > 0)
+    {
+      if (candidate->D2-candidate->D1 != fDaughterNumber) continue;//require at least fDaughterNumber daughters
+
+    }
+    if(find(fPdgCodes.begin(), fPdgCodes.end(), pdgCode) == fPdgCodes.end()) continue; //require pdgID is one of the LLP id
+    if(fRequireStatus && (candidate->Status != fStatus)) continue;
+
+    // loop over particles to find LLP daughters and assign EM and hadronic energy
+    candidate->Eem = 0.0;
+    candidate->Ehad = 0.0;
+    fItParticleInputArray->Reset();
+
+    while((daughter = static_cast<Candidate *>(fItParticleInputArray->Next())))
+    {
+
+      daughterPdg = daughter->PID;
+      if (daughter->Status != 1)continue;
+      if (daughter->IsPU)continue;
+      if (abs(daughterPdg)==12 || abs(daughterPdg)==14 || abs(daughterPdg)==16 || abs(daughterPdg)==13)continue; // ignore neutrinos and muons
+      if (abs(daughterPdg) > 1000000) continue;//ignore BSM particles
+
+      const TLorentzVector &daughterMomentum = daughter->Momentum;
+
+      // look for mother until find LLP or reach the top of the tree
+      tempCandidate = daughter;
+      while(tempCandidate->M1 != -1 && tempCandidate->M1 != index)
+      {
+        tempCandidate  = static_cast<Candidate *>(fParticleInputArray->At(tempCandidate->M1));
+      }
+      if (tempCandidate->M1 == -1) continue;
+
+      // assign LLP EM or hadronic energy, depending on the daughter ID
+      if (abs(daughterPdg)==11 || abs(daughterPdg)==22 || abs(daughterPdg)==111)candidate->Eem += daughterMomentum.E();
+      else candidate->Ehad += daughterMomentum.E();
+    }
+
+    if (fRequireDecayRegion)
+    {
+      if (abs(eta) < fDecayRegionEtaMax && abs(eta) > fDecayRegionEtaMin
+         && abs(candidateDecayPosition.Z()) < fDecayRegionZMax && abs(candidateDecayPosition.Z()) > fDecayRegionZMin
+         && sqrt(pow(candidateDecayPosition.X(),2)+pow(candidateDecayPosition.Y(),2)) < fDecayRegionRMax
+         && sqrt(pow(candidateDecayPosition.X(),2)+pow(candidateDecayPosition.Y(),2)) > fDecayRegionRMin)
+      {
+        fOutputArray->Add(candidate);
+      }
+
+    }
+    else{
+      fOutputArray->Add(candidate);
+    }
+  }//end of while loop
+}
Index: modules/LLPFilter.h
===================================================================
--- modules/LLPFilter.h	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
+++ modules/LLPFilter.h	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
@@ -0,0 +1,82 @@
+/*
+ *  Delphes: a framework for fast simulation of a generic collider experiment
+ *  Copyright (C) 2012-2014  Universite catholique de Louvain (UCL), Belgium
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//------------------------------------------------------------------------------
+
+#ifndef LLPFilter_h
+#define LLPFilter_h
+
+
+/** \class LLPFilter
+ *
+ *  Filter LLPs with particular PDG ID/status and calculate the EM and hadronic energy of LLP based on decay particles
+ *  The classification of EM and hadronic energy of LLP is based on instructions from the HEPData entry for the CMS paper searching
+ *  for neutral LLPs in the CMS endcap muon detectors: https://www.hepdata.net/record/104408
+ *
+ *  \author Christina Wang
+ *
+ */
+
+#include "classes/DelphesModule.h"
+#include <vector>
+
+class TIterator;
+class TObjArray;
+
+class LLPFilter: public DelphesModule
+{
+public:
+  LLPFilter();
+  ~LLPFilter();
+
+  void Init();
+  void Process();
+  void Finish();
+
+private:
+  Double_t fPTMin; //!
+  Bool_t fRequireDecayRegion;
+  Double_t fDecayRegionRMax;
+  Double_t fDecayRegionRMin;
+  Double_t fDecayRegionZMax;
+  Double_t fDecayRegionZMin;
+  Double_t fDecayRegionEtaMax;
+  Double_t fDecayRegionEtaMin;
+  Int_t fDaughterNumber;
+  Bool_t fInvert; //!
+  Bool_t fRequireStatus; //!
+  Int_t fStatus; //!
+  Bool_t fRequireCharge; //!
+  Int_t fCharge; //!
+  Bool_t fRequireNotPileup; //!
+
+  std::vector<Int_t> fPdgCodes;
+
+  TIterator *fItInputArray; //!
+
+  const TObjArray *fInputArray; //!
+
+  TIterator *fItParticleInputArray;
+  const TObjArray *fParticleInputArray;
+
+  TObjArray *fOutputArray; //!
+
+  ClassDef(LLPFilter, 1)
+};
+
+#endif
Index: modules/ModulesLinkDef.h
===================================================================
--- modules/ModulesLinkDef.h	(revision 4e8e72b29f2e9bc564ccf210abe4da8e61623055)
+++ modules/ModulesLinkDef.h	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
@@ -79,4 +79,7 @@
 #include "modules/TruthVertexFinder.h"
 #include "modules/ExampleModule.h"
+#include "modules/LLPFilter.h"
+#include "modules/CscClusterEfficiency.h"
+#include "modules/CscClusterId.h"
 
 #ifdef __CINT__
@@ -139,4 +142,7 @@
 #pragma link C++ class TruthVertexFinder+;
 #pragma link C++ class ExampleModule+;
+#pragma link C++ class LLPFilter+;
+#pragma link C++ class CscClusterEfficiency+;
+#pragma link C++ class CscClusterId+;
 
 #endif
Index: modules/TreeWriter.cc
===================================================================
--- modules/TreeWriter.cc	(revision 4e8e72b29f2e9bc564ccf210abe4da8e61623055)
+++ modules/TreeWriter.cc	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
@@ -77,4 +77,5 @@
   fClassMap[Electron::Class()] = &TreeWriter::ProcessElectrons;
   fClassMap[Muon::Class()] = &TreeWriter::ProcessMuons;
+  fClassMap[CscCluster::Class()] = &TreeWriter::ProcessCscCluster;
   fClassMap[Jet::Class()] = &TreeWriter::ProcessJets;
   fClassMap[MissingET::Class()] = &TreeWriter::ProcessMissingET;
@@ -251,4 +252,5 @@
     entry->Z = position.Z();
     entry->T = position.T() * 1.0E-3 / c_light;
+
   }
 }
@@ -907,4 +909,57 @@
   }
 }
+//------------------------------------------------------------------------------
+
+void TreeWriter::ProcessCscCluster(ExRootTreeBranch *branch, TObjArray *array)
+{
+  TIter iterator(array);
+  Candidate *candidate = 0;
+  CscCluster *entry = 0;
+  Double_t pt, signPz, cosTheta, eta, rapidity;
+
+  const Double_t c_light = 2.99792458E8; // in unit of m/s
+
+  array->Sort();
+
+
+  // loop over all clusters
+  iterator.Reset();
+  while((candidate = static_cast<Candidate *>(iterator.Next())))
+  {
+    const TLorentzVector &momentum = candidate->Momentum;
+    const TLorentzVector &position = candidate->DecayPosition;
+
+    pt = momentum.Pt();
+    cosTheta = TMath::Abs(momentum.CosTheta());
+    signPz = (momentum.Pz() >= 0.0) ? 1.0 : -1.0;
+    eta = (cosTheta == 1.0 ? signPz * 999.9 : momentum.Eta());
+
+    entry = static_cast<CscCluster *>(branch->NewEntry());
+
+    entry->SetBit(kIsReferenced);
+    entry->SetUniqueID(candidate->GetUniqueID());
+
+    entry->Eta = eta;
+    entry->Phi = momentum.Phi();
+
+    entry->PT = momentum.Pt(); // pt of LLP
+    entry->Px = momentum.Px();// px of LLP
+    entry->Py = momentum.Py();// py of LLP
+    entry->Pz = momentum.Pz();// pz of LLP
+    entry->E = momentum.E(); // E of LLP
+    entry->pid = candidate->PID; // LLP pid
+    entry->Eem = candidate->Eem; // LLP Eem
+    entry->Ehad = candidate->Ehad; // LLP Ehad
+    Double_t beta = momentum.P()/momentum.E();
+    Double_t gamma = 1.0/sqrt(1-beta*beta);
+    Double_t decayDistance = sqrt(pow(position.X(),2)+pow(position.Y(),2)+pow(position.Z(),2)); // mm
+    entry->beta = beta; // LLP pid
+    entry->ctau = decayDistance/(beta * gamma); // LLP travel time in its rest frame
+    entry->T = decayDistance*(1./beta-1)* 1.0E-3/c_light*1e9; // ns
+    entry->X = position.X(); // LLP decay x
+    entry->Y = position.Y(); //  LLP decay y
+    entry->Z = position.Z(); //  LLP decay z
+  }
+}
 
 //------------------------------------------------------------------------------
Index: modules/TreeWriter.h
===================================================================
--- modules/TreeWriter.h	(revision 4e8e72b29f2e9bc564ccf210abe4da8e61623055)
+++ modules/TreeWriter.h	(revision cc8716bacadbc6b5ce104a0e669ebfa9cd640210)
@@ -60,4 +60,5 @@
   void ProcessElectrons(ExRootTreeBranch *branch, TObjArray *array);
   void ProcessMuons(ExRootTreeBranch *branch, TObjArray *array);
+  void ProcessCscCluster(ExRootTreeBranch *branch, TObjArray *array);
   void ProcessTauJets(ExRootTreeBranch *branch, TObjArray *array);
   void ProcessJets(ExRootTreeBranch *branch, TObjArray *array);
@@ -67,4 +68,5 @@
   void ProcessWeight(ExRootTreeBranch *branch, TObjArray *array);
   void ProcessHectorHit(ExRootTreeBranch *branch, TObjArray *array);
+
 
 #if !defined(__CINT__) && !defined(__CLING__)
