text: #ifndef RecoJets_JetProducers_CATopJetProducer_h
  #define RecoJets_JetProducers_CATopJetProducer_h
  
  
  /* *********************************************************
  
  
   * \class CATopJetProducer
   * Jet producer to produce top jets using the C-A algorithm to break
   * jets into subjets as described here:
   * "Top-tagging: A Method for Identifying Boosted Hadronic Tops"
   * David E. Kaplan, Keith Rehermann, Matthew D. Schwartz, Brock Tweedie
   * arXiv:0806.0848v1 [hep-ph] 
  
    \brief Jet producer to run the CATopJetAlgorithm
  
    \author   Salvatore Rappoccio
    \version  
  
           Notes on implementation:
  
  	 Because the BaseJetProducer only allows the user to produce
  	 one jet collection at a time, this algorithm cannot
  	 fit into that paradigm. 
  
  	 All of the "hard" jets are of type BasicJet, since
  	 they are "jets of jets". The subjets will be either
  	 CaloJets, GenJets, etc.
  
  	 In order to avoid a templatization of the entire
  	 EDProducer itself, we only use a templated method
  	 to write out the subjets to the event record,
  	 and to use that information to write out the
  	 hard jets to the event record.
  
  	 This templated method is called "write_outputs". It
  	 relies on a second templated method called "write_specific",
  	 which relies on some template specialization to create
  	 different specific objects (i.e. CaloJets, BasicJets, GenJets, etc). 
  
   ************************************************************/
  
  
  
  
  #include "FWCore/Framework/interface/Event.h"
  #include "FWCore/Framework/interface/EventSetup.h"
  #include "DataFormats/Common/interface/View.h"
  #include "DataFormats/Common/interface/Handle.h"
  #include "DataFormats/Provenance/interface/ProductID.h"
  #include "FWCore/MessageLogger/interface/MessageLogger.h"
  #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
  #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
  
  #include "DataFormats/JetReco/interface/CaloJetCollection.h"
  #include "DataFormats/JetReco/interface/GenJetCollection.h"
  #include "DataFormats/JetReco/interface/PFJetCollection.h"
  #include "DataFormats/JetReco/interface/BasicJetCollection.h"
  #include "RecoJets/JetAlgorithms/interface/JetAlgoHelper.h"
  #include "DataFormats/Candidate/interface/CandidateFwd.h"
  #include "DataFormats/Candidate/interface/LeafCandidate.h"
  #include "FWCore/Framework/interface/ESHandle.h"
  #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
  #include "Geometry/Records/interface/CaloGeometryRecord.h"
  
  #include "RecoJets/JetProducers/plugins/FastjetJetProducer.h"
  #include "RecoJets/JetAlgorithms/interface/CATopJetAlgorithm.h"
  #include "CATopJetProducer.h"
  #include "RecoJets/JetAlgorithms/interface/CMSTopTagger.h"
  
  #include <fastjet/tools/RestFrameNSubjettinessTagger.hh>
  #include "fastjet/SISConePlugin.hh"
  
  
  namespace cms
  {
    class CATopJetProducer : public FastjetJetProducer
    {
    public:
  
      CATopJetProducer(const edm::ParameterSet& ps);
  
      ~CATopJetProducer() override {}
      static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
  
      void produce( edm::Event& iEvent, const edm::EventSetup& iSetup ) override;
  
      void runAlgorithm( edm::Event& iEvent, const edm::EventSetup& iSetup ) override;
  
    private:
      std::unique_ptr<CATopJetAlgorithm>        legacyCMSTopTagger_;         /// The algorithm to do the work
      std::unique_ptr<fastjet::CMSTopTagger>     fjCMSTopTagger_;    // The FastJet implementation of the CMS tagger
      std::unique_ptr<fastjet::JHTopTagger>     fjJHUTopTagger_;
      std::unique_ptr<fastjet::RestFrameNSubjettinessTagger>   fjNSUBTagger_;
  
  
  
      int tagAlgo_;
      double ptMin_;
      double centralEtaCut_;
      bool verbose_;
      enum tagalgos {
  	CA_TOPTAGGER,
  	FJ_CMS_TOPTAG,
  	FJ_JHU_TOPTAG,
  	FJ_NSUB_TAG
      };
  
  
    };
  
  }
  
  
  #endif
  