#ifndef TESTSMOOTHHITS_H
#define TESTSMOOTHHITS_H

// -*- C++ -*-
//
// Package:    TestSmoothHits
// Class:      TestSmoothHits
//
/**\class TestSmoothHits TestSmoothHits.cc RecoTracker/DebugTools/src/TestSmoothHits.cc

 Description: <one line class summary>

 Implementation:
     <Notes on implementation>
*/
//
// Original Author:  Giuseppe Cerati
//         Created:  Tue Feb 13 17:29:10 CET 2007
//
//
#include <memory>
#include <vector>
#include <string>
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/Framework/interface/one/EDAnalyzer.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/InputTag.h"
#include "SimTracker/TrackerHitAssociation/interface/TrackerHitAssociator.h"
#include "MagneticField/Engine/interface/MagneticField.h"
#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
#include "Geometry/TrackerGeometryBuilder/interface/StripGeomDetUnit.h"
#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
#include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
#include "TrackingTools/Records/interface/TransientRecHitRecord.h"
#include "Geometry/CommonDetUnit/interface/TrackingGeometry.h"
#include "DataFormats/TrackCandidate/interface/TrackCandidateCollection.h"
#include "TrackingTools/GeomPropagators/interface/Propagator.h"
#include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHitBuilder.h"
#include "RecoTracker/TransientTrackingRecHit/interface/TkTransientTrackingRecHitBuilder.h"
#include "TrackingTools/PatternTools/interface/MeasurementExtractor.h"
#include "TrackingTools/TrackFitters/interface/KFTrajectoryFitter.h"
#include "TrackingTools/TrackFitters/interface/KFTrajectorySmoother.h"
#include <sstream>
#include <TFile.h>
#include <TH1F.h>
#include <TH2F.h>

class TestSmoothHits : public edm::one::EDAnalyzer<edm::one::WatchRuns> {
public:
  explicit TestSmoothHits(const edm::ParameterSet&);
  ~TestSmoothHits() override;

private:
  void beginRun(edm::Run const& run, const edm::EventSetup&) override;
  void analyze(const edm::Event&, const edm::EventSetup&) override;
  void endRun(edm::Run const& run, const edm::EventSetup&) override {}
  void endJob() override;

  std::pair<LocalPoint, LocalVector> projectHit(const PSimHit&, const StripGeomDetUnit*, const BoundPlane&);

  TrackerHitAssociator::Config trackerHitAssociatorConfig_;

  double mineta, maxeta;

  std::string propagatorName;
  std::string builderName;
  std::string srcName;
  std::string fname;
  std::string sname;

  edm::ESHandle<TrackerGeometry> theG;
  edm::ESHandle<MagneticField> theMF;
  edm::ESHandle<Propagator> thePropagator;
  edm::ESHandle<TransientTrackingRecHitBuilder> theBuilder;
  edm::Handle<TrackCandidateCollection> theTCCollection;
  edm::ESHandle<TrajectoryFitter> fit;
  edm::ESHandle<TrajectorySmoother> smooth;

  edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> theGToken;
  edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> theMFToken;
  edm::ESGetToken<Propagator, TrackingComponentsRecord> thePropagatorToken;
  edm::ESGetToken<TransientTrackingRecHitBuilder, TransientRecHitRecord> theBuilderToken;
  edm::EDGetTokenT<TrackCandidateCollection> theTCCollectionToken;
  edm::ESGetToken<TrajectoryFitter, TrajectoryFitter::Record> fitToken;
  edm::ESGetToken<TrajectorySmoother, TrajectoryFitter::Record> smoothToken;
  edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> tTopoToken;

  TFile* file;
  std::stringstream title;
  std::map<std::string, TH1F*> hPullGP_X_ts;
  std::map<std::string, TH1F*> hPullGP_Y_ts;
  std::map<std::string, TH1F*> hPullGP_Z_ts;
  std::map<std::string, TH1F*> hPullGM_X_ts;
  std::map<std::string, TH1F*> hPullGM_Y_ts;
  std::map<std::string, TH1F*> hPullGM_Z_ts;
  std::map<std::string, TH1F*> hPullGP_X_rs;
  std::map<std::string, TH1F*> hPullGP_Y_rs;
  std::map<std::string, TH1F*> hPullGP_Z_rs;
  std::map<std::string, TH1F*> hPullGP_X_tr;
  std::map<std::string, TH1F*> hPullGP_Y_tr;
  std::map<std::string, TH1F*> hPullGP_Z_tr;
  std::map<std::string, TH1F*> hChi2Increment;
  TH1F* hTotChi2Increment;
  TH2F *hChi2_vs_Process, *hChi2_vs_clsize;

  std::map<std::string, TH1F*> hPullGP_X_ts_mono;
  std::map<std::string, TH1F*> hPullGP_Y_ts_mono;
  std::map<std::string, TH1F*> hPullGP_Z_ts_mono;
  std::map<std::string, TH1F*> hPullGM_X_ts_mono;
  std::map<std::string, TH1F*> hPullGM_Y_ts_mono;
  std::map<std::string, TH1F*> hPullGM_Z_ts_mono;
  std::map<std::string, TH1F*> hPullGP_X_rs_mono;
  std::map<std::string, TH1F*> hPullGP_Y_rs_mono;
  std::map<std::string, TH1F*> hPullGP_Z_rs_mono;
  std::map<std::string, TH1F*> hPullGP_X_tr_mono;
  std::map<std::string, TH1F*> hPullGP_Y_tr_mono;
  std::map<std::string, TH1F*> hPullGP_Z_tr_mono;

  std::map<std::string, TH1F*> hPullGP_X_ts_stereo;
  std::map<std::string, TH1F*> hPullGP_Y_ts_stereo;
  std::map<std::string, TH1F*> hPullGP_Z_ts_stereo;
  std::map<std::string, TH1F*> hPullGM_X_ts_stereo;
  std::map<std::string, TH1F*> hPullGM_Y_ts_stereo;
  std::map<std::string, TH1F*> hPullGM_Z_ts_stereo;
  std::map<std::string, TH1F*> hPullGP_X_rs_stereo;
  std::map<std::string, TH1F*> hPullGP_Y_rs_stereo;
  std::map<std::string, TH1F*> hPullGP_Z_rs_stereo;
  std::map<std::string, TH1F*> hPullGP_X_tr_stereo;
  std::map<std::string, TH1F*> hPullGP_Y_tr_stereo;
  std::map<std::string, TH1F*> hPullGP_Z_tr_stereo;
};

#endif
