CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/Validation/RecoVertex/src/PrimaryVertexAnalyzer4PU.cc

Go to the documentation of this file.
00001 #include "Validation/RecoVertex/interface/PrimaryVertexAnalyzer4PU.h"
00002 
00003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005 #include "FWCore/Version/interface/GetReleaseVersion.h"
00006 #include "MagneticField/Engine/interface/MagneticField.h"
00007 
00008 // reco track and vertex 
00009 #include "DataFormats/TrackReco/interface/Track.h"
00010 #include "DataFormats/VertexReco/interface/Vertex.h"
00011 #include "DataFormats/Math/interface/Point3D.h"
00012 #include "RecoVertex/VertexPrimitives/interface/TransientVertex.h"
00013 
00014 // simulated vertices,..., add <use name=SimDataFormats/Vertex> and <../Track>
00015 #include <SimDataFormats/Vertex/interface/SimVertex.h>
00016 #include <SimDataFormats/Vertex/interface/SimVertexContainer.h>
00017 #include <SimDataFormats/Track/interface/SimTrack.h>
00018 #include <SimDataFormats/Track/interface/SimTrackContainer.h>
00019 
00020 #include "SimDataFormats/CrossingFrame/interface/CrossingFrame.h"
00021 #include "SimDataFormats/CrossingFrame/interface/CrossingFramePlaybackInfo.h"
00022 #include "SimDataFormats/CrossingFrame/interface/MixCollection.h"
00023 #include "SimDataFormats/TrackingHit/interface/PSimHit.h"
00024 
00025 //generator level + CLHEP
00026 #include "HepMC/GenEvent.h"
00027 #include "HepMC/GenVertex.h"
00028 
00029 
00030 // TrackingParticle
00031 #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticleFwd.h"
00032 #include "SimDataFormats/TrackingAnalysis/interface/TrackingVertexContainer.h"
00033 //associator
00034 #include "SimTracker/Records/interface/TrackAssociatorRecord.h"
00035 
00036 
00037 // fit
00038 #include "RecoVertex/KalmanVertexFit/interface/KalmanVertexFitter.h"
00039 #include "RecoVertex/AdaptiveVertexFit/interface/AdaptiveVertexFitter.h"
00040 
00041 #include "CommonTools/Statistics/interface/ChiSquaredProbability.h"
00042 
00043 // Root
00044 #include <TH1.h>
00045 #include <TH2.h>
00046 #include <TFile.h>
00047 #include <TProfile.h>
00048  
00049 #include <cmath>
00050 #include <gsl/gsl_math.h>
00051 #include <gsl/gsl_eigen.h>
00052 
00053 
00054 // cluster stufff
00055 //#include "DataFormats/TrackRecoTrack.h"
00056 #include "DataFormats/TrackerRecHit2D/interface/SiPixelRecHitCollection.h"
00057 #include "Geometry/TrackerGeometryBuilder/interface/PixelGeomDetUnit.h"
00058 
00059 
00060 using namespace edm;
00061 using namespace reco;
00062 using namespace std;
00063 //
00064 // constants, enums and typedefs
00065 //
00066 typedef reco::Vertex::trackRef_iterator trackit_t;
00067 //
00068 // static data member definitions
00069 //
00070 
00071 //
00072 // constructors and destructor
00073 //
00074 PrimaryVertexAnalyzer4PU::PrimaryVertexAnalyzer4PU(const ParameterSet& iConfig) :
00075   theTrackFilter(iConfig.getParameter<edm::ParameterSet>("TkFilterParameters")),
00076   beamSpot_(iConfig.getParameter<edm::InputTag>("beamSpot"))
00077 {
00078    //now do what ever initialization is needed
00079   simG4_=iConfig.getParameter<edm::InputTag>( "simG4" );
00080   recoTrackProducer_= iConfig.getUntrackedParameter<std::string>("recoTrackProducer");
00081   // open output file to store histograms}
00082   outputFile_  = iConfig.getUntrackedParameter<std::string>("outputFile");
00083 
00084   rootFile_ = TFile::Open(outputFile_.c_str(),"RECREATE");
00085   verbose_= iConfig.getUntrackedParameter<bool>("verbose", false);
00086   doMatching_= iConfig.getUntrackedParameter<bool>("matching", false);
00087   printXBS_= iConfig.getUntrackedParameter<bool>("XBS", false);
00088   simUnit_= 1.0;  // starting with CMSSW_1_2_x ??
00089   if ( (edm::getReleaseVersion()).find("CMSSW_1_1_",0)!=std::string::npos){
00090     simUnit_=0.1;  // for use in  CMSSW_1_1_1 tutorial
00091   }
00092   
00093   dumpPUcandidates_=iConfig.getUntrackedParameter<bool>("dumpPUcandidates", false);
00094 
00095   zmatch_=iConfig.getUntrackedParameter<double>("zmatch", 0.0500);
00096   cout << "PrimaryVertexAnalyzer4PU: zmatch=" << zmatch_ << endl;
00097   eventcounter_=0;
00098   dumpcounter_=0;
00099   ndump_=10;
00100   DEBUG_=false;
00101   //DEBUG_=true;
00102 }
00103 
00104 
00105 
00106 
00107 PrimaryVertexAnalyzer4PU::~PrimaryVertexAnalyzer4PU()
00108 {
00109     // do anything here that needs to be done at desctruction time
00110    // (e.g. close files, deallocate resources etc.)
00111   delete rootFile_;
00112 }
00113 
00114 
00115 
00116 //
00117 // member functions
00118 //
00119 
00120 
00121 std::map<std::string, TH1*>  PrimaryVertexAnalyzer4PU::bookVertexHistograms(){
00122   std::map<std::string, TH1*> h;
00123 
00124   // release validation histograms used in DoCompare.C
00125   h["nbtksinvtx"]   = new TH1F("nbtksinvtx","reconstructed tracks in vertex",40,-0.5,39.5); 
00126   h["nbtksinvtxPU"] = new TH1F("nbtksinvtxPU","reconstructed tracks in vertex",40,-0.5,39.5); 
00127   h["nbtksinvtxTag"]= new TH1F("nbtksinvtxTag","reconstructed tracks in vertex",40,-0.5,39.5); 
00128   h["resx"]         = new TH1F("resx","residual x",100,-0.04,0.04);
00129   h["resy"]         = new TH1F("resy","residual y",100,-0.04,0.04);
00130   h["resz"]         = new TH1F("resz","residual z",100,-0.1,0.1);
00131   h["resz10"]       = new TH1F("resz10","residual z",100,-1.0,1.);
00132   h["pullx"]        = new TH1F("pullx","pull x",100,-25.,25.);
00133   h["pully"]        = new TH1F("pully","pull y",100,-25.,25.);
00134   h["pullz"]        = new TH1F("pullz","pull z",100,-25.,25.);
00135   h["vtxchi2"]      = new TH1F("vtxchi2","chi squared",100,0.,100.);
00136   h["vtxndf"]       = new TH1F("vtxndf","degrees of freedom",500,0.,100.);
00137   h["vtxndfc"]       = new TH1F("vtxndfc","expected 2nd highest ndof",500,0.,100.);
00138 
00139   h["vtxndfvsntk"]  = new TH2F("vtxndfvsntk","ndof vs #tracks",20,0.,100, 20, 0., 200.);
00140   h["vtxndfoverntk"]= new TH1F("vtxndfoverntk","ndof / #tracks",40,0.,2.);
00141   h["vtxndf2overntk"]= new TH1F("vtxndf2overntk","(ndof+2) / #tracks",40,0.,2.);
00142   h["tklinks"]      = new TH1F("tklinks","Usable track links",2,-0.5,1.5);
00143   h["nans"]         = new TH1F("nans","Illegal values for x,y,z,xx,xy,xz,yy,yz,zz",9,0.5,9.5);
00144 
00145 
00146   // raw
00147   add(h, new TH1F("szRecVtx","size of recvtx collection",20, -0.5, 19.5));
00148   add(h, new TH1F("isFake","fake vertex",2, -0.5, 1.5));
00149   add(h, new TH1F("isFake1","fake vertex or ndof<0",2, -0.5, 1.5));
00150   add(h, new TH1F("bunchCrossing","bunchCrossing",4000, 0., 4000.));
00151   add(h, new TH2F("bunchCrossingLogNtk","bunchCrossingLogNtk",4000, 0., 4000.,5,0., 5.));
00152   add(h, new TH1F("highpurityTrackFraction","fraction of high purity tracks",20, 0., 1.));
00153   add(h, new TH2F("trkchi2vsndof","vertices chi2 vs ndof",50, 0., 100., 50, 0., 200.));
00154   add(h, new TH1F("trkchi2overndof","vertices chi2 / ndof",50, 0., 5.));
00155   // two track vertices
00156   add(h,new TH2F("2trkchi2vsndof","two-track vertices chi2 vs ndof",40, 0., 10., 20, 0., 20.));
00157   add(h,new TH1F("2trkmassSS","two-track vertices mass (same sign)",100, 0., 2.));
00158   add(h,new TH1F("2trkmassOS","two-track vertices mass (opposite sign)",100, 0., 2.));
00159   add(h,new TH1F("2trkdphi","two-track vertices delta-phi",360, 0, 2*M_PI));
00160   add(h,new TH1F("2trkseta","two-track vertices sum-eta",50, -2., 2.));
00161   add(h,new TH1F("2trkdphicurl","two-track vertices delta-phi (sum eta<0.1)",360, 0, 2*M_PI));
00162   add(h,new TH1F("2trksetacurl","two-track vertices sum-eta (delta-phi<0.1)",50, -2., 2.));
00163   add(h,new TH1F("2trkdetaOS","two-track vertices delta-eta (same sign)",50, -0.5, 0.5));
00164   add(h,new TH1F("2trkdetaSS","two-track vertices delta-eta (opposite sign)",50, -0.5, 0.5));
00165   // two track PU vertices
00166   add(h,new TH1F("2trkmassSSPU","two-track vertices mass (same sign)",100, 0., 2.));
00167   add(h,new TH1F("2trkmassOSPU","two-track vertices mass (opposite sign)",100, 0., 2.));
00168   add(h,new TH1F("2trkdphiPU","two-track vertices delta-phi",360, 0, 2*M_PI));
00169   add(h,new TH1F("2trksetaPU","two-track vertices sum-eta",50, -2., 2.));
00170   add(h,new TH1F("2trkdphicurlPU","two-track vertices delta-phi (sum eta<0.1)",360, 0, 2*M_PI));
00171   add(h,new TH1F("2trksetacurlPU","two-track vertices sum-eta (delta-phi<0.1)",50, -2., 2.));
00172   add(h,new TH1F("2trkdetaOSPU","two-track vertices delta-eta (same sign)",50, -0.5, 0.5));
00173   add(h,new TH1F("2trkdetaSSPU","two-track vertices delta-eta (opposite sign)",50, -0.5, 0.5));
00174   // three track vertices
00175   add(h,new TH2F("2trkchi2vsndof","two-track vertices chi2 vs ndof",40, 0., 10., 20, 0., 20.));
00176   add(h,new TH2F("3trkchi2vsndof","three-track vertices chi2 vs ndof",40, 0., 10., 20, 0., 20.));
00177   add(h,new TH2F("4trkchi2vsndof","four-track vertices chi2 vs ndof",40, 0., 10., 20, 0., 20.));
00178   add(h,new TH2F("5trkchi2vsndof","five-track vertices chi2 vs ndof",40, 0., 10., 20, 0., 20.));
00179   // same for fakes
00180   add(h,new TH2F("fake2trkchi2vsndof","fake two-track vertices chi2 vs ndof",40, 0., 10., 20, 0., 20.));
00181   add(h,new TH2F("fake3trkchi2vsndof","fake three-track vertices chi2 vs ndof",40, 0., 10., 20, 0., 20.));
00182   add(h,new TH2F("fake4trkchi2vsndof","fake four-track vertices chi2 vs ndof",40, 0., 10., 20, 0., 20.));
00183   add(h,new TH2F("fake5trkchi2vsndof","fake five-track vertices chi2 vs ndof",40, 0., 10., 20, 0., 20.));
00184   h["resxr"]        = new TH1F("resxr","relative residual x",100,-0.04,0.04);
00185   h["resyr"]        = new TH1F("resyr","relative residual y",100,-0.04,0.04);
00186   h["reszr"]        = new TH1F("reszr","relative residual z",100,-0.1,0.1);
00187   h["pullxr"]       = new TH1F("pullxr","relative pull x",100,-25.,25.);
00188   h["pullyr"]       = new TH1F("pullyr","relative pull y",100,-25.,25.);
00189   h["pullzr"]       = new TH1F("pullzr","relative pull z",100,-25.,25.);
00190   h["vtxprob"]      = new TH1F("vtxprob","chisquared probability",100,0.,1.);
00191   h["eff"]          = new TH1F("eff","efficiency",2, -0.5, 1.5);
00192   h["efftag"]       = new TH1F("efftag","efficiency tagged vertex",2, -0.5, 1.5);
00193   h["zdistancetag"] = new TH1F("zdistancetag","z-distance between tagged and generated",100, -0.1, 0.1);
00194   h["abszdistancetag"] = new TH1F("abszdistancetag","z-distance between tagged and generated",1000, 0., 1.0);
00195   h["abszdistancetagcum"] = new TH1F("abszdistancetagcum","z-distance between tagged and generated",1000, 0., 1.0);
00196   h["puritytag"]    = new TH1F("puritytag","purity of primary vertex tags",2, -0.5, 1.5);
00197   h["effvsptsq"]    = new TProfile("effvsptsq","efficiency vs ptsq",20, 0., 10000., 0, 1.);
00198   h["effvsnsimtrk"] = new TProfile("effvsnsimtrk","efficiency vs # simtracks",50, 0., 50., 0, 1.);
00199   h["effvsnrectrk"] = new TProfile("effvsnrectrk","efficiency vs # rectracks",50, 0., 50., 0, 1.);
00200   h["effvsnseltrk"] = new TProfile("effvsnseltrk","efficiency vs # selected tracks",50, 0., 50., 0, 1.);
00201   h["effvsz"]       = new TProfile("effvsz","efficiency vs z",20, -20., 20., 0, 1.);
00202   h["effvsz2"]      = new TProfile("effvsz2","efficiency vs z (2mm)",20, -20., 20., 0, 1.);
00203   h["effvsr"]       = new TProfile("effvsr","efficiency vs r",20, 0., 1., 0, 1.);
00204   h["xresvsntrk"] = new TProfile("xresvsntrk","xresolution vs # vertex tracks",40, 0., 200., 0, 0.01);
00205   h["yresvsntrk"] = new TProfile("yresvsntrk","yresolution vs # vertex tracks",40, 0., 200., 0, 0.01);
00206   h["zresvsntrk"] = new TProfile("zresvsntrk","zresolution vs # vertex tracks",40, 0., 200., 0, 0.01);
00207   h["cpuvsntrk"] = new TProfile("cpuvsntrk","cpu time vs # of fitted tracks",40, 0., 200., 0, 200.);
00208   h["cpucluvsntrk"] = new TProfile("cpucluvsntrk","clustering cpu time # of tracks",40, 0., 200., 0, 10.);
00209   h["cpufit"]    = new TH1F("cpufit","cpu time for fitting",100, 0., 200.);
00210   h["cpuclu"]    = new TH1F("cpuclu","cpu time for clustering",100, 0., 200.);
00211   h["nbtksinvtx2"]   = new TH1F("nbtksinvtx2","reconstructed tracks in vertex",40,0.,200.); 
00212   h["nbtksinvtxPU2"]   = new TH1F("nbtksinvtxPU2","reconstructed tracks in vertex",40,0.,200.); 
00213   h["nbtksinvtxTag2"]   = new TH1F("nbtksinvtxTag2","reconstructed tracks in vertex",40,0.,200.); 
00214 
00215   h["xrec"]         = new TH1F("xrec","reconstructed x",100,-0.1,0.1);
00216   h["yrec"]         = new TH1F("yrec","reconstructed y",100,-0.1,0.1);
00217   h["zrec"]         = new TH1F("zrec","reconstructed z",100,-20.,20.);
00218   h["err1"]         = new TH1F("err1","error 1",100,0.,0.1);
00219   h["err2"]         = new TH1F("err2","error 2",100,0.,0.1);
00220   h["errx"]         = new TH1F("errx","error x",100,0.,0.1);
00221   h["erry"]         = new TH1F("erry","error y",100,0.,0.1);
00222   h["errz"]         = new TH1F("errz","error z",100,0.,2.0);
00223   h["errz1"]        = new TH1F("errz1","error z",100,0.,0.2);
00224 
00225   h["zrecNt100"]         = new TH1F("zrecNt100","reconstructed z for high multiplicity events",80,-40.,40.);
00226   add(h, new TH2F("zrecvsnt","reconstructed z vs number of tracks",100,-50., 50., 20, 0., 200.));
00227   add(h, new TH2F("xyrec","reconstructed xy",100, -4., 4., 100, -4., 4.));
00228   h["xrecBeam"]     = new TH1F("xrecBeam","reconstructed x - beam x",100,-0.1,0.1);
00229   h["yrecBeam"]     = new TH1F("yrecBeam","reconstructed y - beam y",100,-0.1,0.1);
00230   h["zrecBeam"]     = new TH1F("zrecBeam","reconstructed z - beam z",100,-20.,20.);
00231   h["xrecBeamvsz"] = new TH2F("xrecBeamvsz","reconstructed x - beam x vs z", 20, -20., 20.,100,-0.1,0.1);
00232   h["yrecBeamvsz"] = new TH2F("yrecBeamvsz","reconstructed y - beam y vs z", 20, -20., 20.,100,-0.1,0.1);
00233   h["xrecBeamvszprof"] = new TProfile("xrecBeamvszprof","reconstructed x - beam x vs z-z0", 20, -20., 20.,-0.1,0.1);
00234   h["yrecBeamvszprof"] = new TProfile("yrecBeamvszprof","reconstructed y - beam y vs z-z0", 20, -20., 20.,-0.1,0.1);
00235   add(h, new TH2F("xrecBeamvsdxXBS","reconstructed x - beam x vs resolution",10,0., 0.02, 100, -0.1,0.1)); // just a test
00236   add(h, new TH2F("yrecBeamvsdyXBS","reconstructed z - beam z vs resolution",10,0., 0.02, 100, -0.1,0.1));
00237   add(h, new TH2F("xrecBeamvsdx","reconstructed x - beam x vs resolution",10,0., 0.02, 100, -0.1,0.1));
00238   add(h, new TH2F("yrecBeamvsdy","reconstructed z - beam z vs resolution",10,0., 0.02, 100, -0.1,0.1));
00239   add(h, new TH2F("xrecBeamvsdxR2","reconstructed x - beam x vs resolution",20,0., 0.04, 100, -0.1,0.1));
00240   add(h, new TH2F("yrecBeamvsdyR2","reconstructed z - beam z vs resolution",20,0., 0.04, 100, -0.1,0.1));
00241   //  add(h, new TH2F("xrecBeamvsdx","reconstructed x - beam x vs resolution",100,-0.1,0.1, 10, 0., 0.04));
00242   //  add(h, new TH2F("yrecBeamvsdy","reconstructed y - beam y vs resolution",100,-0.1,0.1, 10, 0., 0.04));
00243   h["xrecBeamvsdxprof"] = new TProfile("xrecBeamvsdxprof","reconstructed x - beam x vs resolution",10, 0., 0.04,-0.1,0.1 );
00244   h["yrecBeamvsdyprof"] = new TProfile("yrecBeamvsdyprof","reconstructed y - beam y vs resolution",10, 0., 0.04,-0.1,0.1 );
00245   add(h, new TProfile("xrecBeam2vsdx2prof","reconstructed x - beam x vs resolution",10,0., 0.002, 0., 0.01));
00246   add(h, new TProfile("yrecBeam2vsdy2prof","reconstructed y - beam y vs resolution",10,0., 0.002, 0., 0.01));
00247   add(h,new TH2F("xrecBeamvsdx2","reconstructed x - beam x vs resolution",10,0., 0.002, 100, -0.01, 0.01));
00248   add(h,new TH2F("yrecBeamvsdy2","reconstructed y - beam y vs resolution",10,0., 0.002, 100, -0.01, 0.01));
00249   h["xrecb"]        = new TH1F("xrecb","reconstructed x - beam x",100,-0.01,0.01);
00250   h["yrecb"]        = new TH1F("yrecb","reconstructed y - beam y",100,-0.01,0.01);
00251   h["zrecb"]        = new TH1F("zrecb","reconstructed z - beam z",100,-20.,20.);
00252   h["xrec1"]        = new TH1F("xrec1","reconstructed x",100,-4,4);
00253   h["yrec1"]        = new TH1F("yrec1","reconstructed y",100,-4,4);  // should match the sim histos
00254   h["zrec1"]        = new TH1F("zrec1","reconstructed z",100,-80.,80.);
00255   h["xrec2"]        = new TH1F("xrec2","reconstructed x",100,-1,1);
00256   h["yrec2"]        = new TH1F("yrec2","reconstructed y",100,-1,1);
00257   h["zrec2"]        = new TH1F("zrec2","reconstructed z",100,-40.,40.);
00258   h["xrec3"]        = new TH1F("xrec3","reconstructed x",100,-0.1,0.1);
00259   h["yrec3"]        = new TH1F("yrec3","reconstructed y",100,-0.1,0.1);
00260   h["zrec3"]        = new TH1F("zrec3","reconstructed z",100,-20.,20.);
00261   add(h, new TH1F("xrecBeamPull","normalized residuals reconstructed x - beam x",100,-20,20));
00262   add(h, new TH1F("yrecBeamPull","normalized residuals reconstructed y - beam y",100,-20,20));
00263   add(h, new TH1F("zdiffrec","z-distance between vertices",200,-20., 20.));
00264   add(h, new TH1F("zdiffrec2","z-distance between ndof>2 vertices",200,-20., 20.));
00265   add(h, new TH1F("zdiffrec4","z-distance between ndof>4 vertices",200,-20., 20.));
00266   add(h, new TH1F("zdiffrec8","z-distance between ndof>8 vertices",200,-20., 20.));
00267   add(h, new TH2F("zvszrec2","z positions of multiple vertices",200,-20., 20., 200,-20., 20.));
00268   add(h, new TH2F("pzvspz2","prob(z) of multiple vertices",100, 0.,1.,100,0., 1.));
00269   add(h, new TH2F("zvszrec4","z positions of multiple vertices",100,-20., 20., 100,-20., 20.));
00270   add(h, new TH2F("pzvspz4","prob(z) of multiple vertices",100, 0.,1.,100,0., 1.));
00271   add(h, new TH2F("zdiffvsz","z-distance vs z",100,-10.,10.,30,-15.,15.));
00272   add(h, new TH2F("zdiffvsz4","z-distance vs z (ndof>4)",100,-10.,10.,30,-15.,15.));
00273   add(h, new TProfile("eff0vsntrec","efficiency vs # reconstructed tracks",50, 0., 50., 0, 1.));
00274   add(h, new TProfile("eff0vsntsel","efficiency vs # selected tracks",50, 0., 50., 0, 1.));
00275   add(h, new TProfile("eff0ndof0vsntsel","efficiency (ndof>0) vs # selected tracks",50, 0., 50., 0, 1.));
00276   add(h, new TProfile("eff0ndof8vsntsel","efficiency (ndof>8) vs # selected tracks",50, 0., 50., 0, 1.));
00277   add(h, new TProfile("eff0ndof2vsntsel","efficiency (ndof>2) vs # selected tracks",50, 0., 50., 0, 1.));
00278   add(h, new TProfile("eff0ndof4vsntsel","efficiency (ndof>4) vs # selected tracks",50, 0., 50., 0, 1.));
00279   add(h, new TH1F("xbeamPUcand","x - beam of PU candidates (ndof>4)",100,-1., 1.));
00280   add(h, new TH1F("ybeamPUcand","y - beam of PU candidates (ndof>4)",100,-1., 1.));
00281   add(h, new TH1F("xbeamPullPUcand","x - beam pull of PU candidates (ndof>4)",100,-20., 20.));
00282   add(h, new TH1F("ybeamPullPUcand","y - beam pull of PU candidates (ndof>4)",100,-20., 20.));
00283   add(h, new TH1F("ndofOverNtk","ndof / ntk of ndidates (ndof>4)",100,0., 2.));
00284   //add(h, new TH1F("sumwOverNtk","sumw / ntk of ndidates (ndof>4)",100,0., 2.));
00285   add(h, new TH1F("ndofOverNtkPUcand","ndof / ntk of ndidates (ndof>4)",100,0., 2.));
00286   //add(h, new TH1F("sumwOverNtkPUcand","sumw / ntk of ndidates (ndof>4)",100,0., 2.));
00287   add(h, new TH1F("zPUcand","z positions of PU candidates (all)",100,-20., 20.));
00288   add(h, new TH1F("zPUcand2","z positions of PU candidates (ndof>2)",100,-20., 20.));
00289   add(h, new TH1F("zPUcand4","z positions of PU candidates (ndof>4)",100,-20., 20.));
00290   add(h, new TH1F("ndofPUcand","ndof of PU candidates (all)",50,0., 100.));
00291   add(h, new TH1F("ndofPUcand2","ndof of PU candidates (ndof>2)",50,0., 100.));
00292   add(h, new TH1F("ndofPUcand4","ndof of PU candidates (ndof>4)",50,0., 100.));
00293   add(h, new TH1F("ndofnr2","second highest ndof",500,0., 100.));
00294   add(h, new TH1F("ndofnr2d1cm","second highest ndof (dz>1cm)",500,0., 100.));
00295   add(h, new TH1F("ndofnr2d2cm","second highest ndof (dz>2cm)",500,0., 100.));
00296 
00297   h["nrecvtx"]      = new TH1F("nrecvtx","# of reconstructed vertices", 50, -0.5, 49.5);
00298   h["nrecvtx8"]      = new TH1F("nrecvtx8","# of reconstructed vertices with ndof>8", 50, -0.5, 49.5);
00299   h["nrecvtx2"]      = new TH1F("nrecvtx2","# of reconstructed vertices with ndof>2", 50, -0.5, 49.5);
00300   h["nrecvtx4"]      = new TH1F("nrecvtx4","# of reconstructed vertices with ndof>4", 50, -0.5, 49.5);
00301   //  h["nsimvtx"]      = new TH1F("nsimvtx","# of simulated vertices", 50, -0.5, 49.5);
00302   h["nrectrk"]      = new TH1F("nrectrk","# of reconstructed tracks", 100, -0.5, 99.5);
00303   add(h, new TH1F("nsimtrk","# of simulated tracks", 100, -0.5, 99.5));
00304   add(h, new TH1F("nsimtrkSignal","# of simulated tracks (Signal)", 100, -0.5, 99.5));
00305   add(h, new TH1F("nsimtrkPU","# of simulated tracks (PU)", 100, -0.5, 99.5));
00306   h["nsimtrk"]->StatOverflows(kTRUE);
00307   h["nsimtrkPU"]->StatOverflows(kTRUE);
00308   h["nsimtrkSignal"]->StatOverflows(kTRUE);
00309   h["xrectag"]      = new TH1F("xrectag","reconstructed x, signal vtx",100,-0.05,0.05);
00310   h["yrectag"]      = new TH1F("yrectag","reconstructed y, signal vtx",100,-0.05,0.05);
00311   h["zrectag"]      = new TH1F("zrectag","reconstructed z, signal vtx",100,-20.,20.);
00312   h["nrectrk0vtx"] = new TH1F("nrectrk0vtx","# rec tracks no vertex ",100,-0.5, 99.5);
00313   h["nseltrk0vtx"] = new TH1F("nseltrk0vtx","# rec tracks no vertex ",100,-0.5, 99.5);
00314   h["nrecsimtrk"] = new TH1F("nrecsimtrk","# rec tracks matched to sim tracks in vertex",100,-0.5, 99.5);
00315   h["nrecnosimtrk"] = new TH1F("nrecsimtrk","# rec tracks not matched to sim tracks in vertex",100,-0.5, 99.5);
00316   h["trackAssEffvsPt"] =  new TProfile("trackAssEffvsPt","track association efficiency vs pt",20, 0., 100., 0, 1.);
00317 
00318   // cluster stuff
00319   h["nseltrk"]         = new TH1F("nseltrk","# of reconstructed tracks selected for PV", 100, -0.5, 99.5);
00320   h["nclutrkall"]      = new TH1F("nclutrkall","# of reconstructed tracks in clusters", 100, -0.5, 99.5);
00321   h["nclutrkvtx"]      = new TH1F("nclutrkvtx","# of reconstructed tracks in clusters of reconstructed vertices", 100, -0.5, 99.5);
00322   h["nclu"]            = new TH1F("nclu","# of clusters", 100, -0.5, 99.5);
00323   h["nclu0vtx"]        = new TH1F("nclu0vtx","# of clusters in events with no PV", 100, -0.5, 99.5);
00324   h["zlost1"]           = new TH1F("zlost1","z of lost vertices (bad z)", 100, -20., 20.);
00325   h["zlost2"]           = new TH1F("zlost2","z of lost vertices (no matching cluster)", 100, -20., 20.);
00326   h["zlost3"]           = new TH1F("zlost3","z of lost vertices (vertex too far from beam)", 100, -20., 20.);
00327   h["zlost4"]           = new TH1F("zlost4","z of lost vertices (invalid vertex)", 100, -20., 20.);
00328   h["selstat"]     = new TH1F("selstat","selstat", 5, -2.5, 2.5);
00329   
00330 
00331   // properties of fake vertices  (MC only)_
00332   add(h, new TH1F("fakeVtxZNdofgt05","z of fake vertices with ndof>0.5", 100, -20., 20.));
00333   add(h, new TH1F("fakeVtxZNdofgt2","z of fake vertices with ndof>2", 100, -20., 20.));
00334   add(h, new TH1F("fakeVtxZ","z of fake vertices", 100, -20., 20.));
00335   add(h, new TH1F("fakeVtxNdof","ndof of fake vertices", 500,0., 100.));
00336   add(h,new TH1F("fakeVtxNtrk","number of tracks in fake vertex",20,-0.5, 19.5));
00337   add(h,new TH1F("matchedVtxNdof","ndof of matched vertices", 500,0., 100.));
00338 
00339 
00340   //  histograms of track quality (Data and MC)
00341   string types[] = {"all","sel","bachelor","sellost","wgt05","wlt05","M","tagged","untagged","ndof4","PUcand","PUfake"};
00342   for(int t=0; t<12; t++){
00343     add(h, new TH1F(("rapidity_"+types[t]).c_str(),"rapidity ",100,-3., 3.));
00344     h["z0_"+types[t]] = new TH1F(("z0_"+types[t]).c_str(),"z0 ",80,-40., 40.);
00345     h["phi_"+types[t]] = new TH1F(("phi_"+types[t]).c_str(),"phi ",80,-3.14159, 3.14159);
00346     h["eta_"+types[t]] = new TH1F(("eta_"+types[t]).c_str(),"eta ",80,-4., 4.);
00347     h["pt_"+types[t]] = new TH1F(("pt_"+types[t]).c_str(),"pt ",100,0., 20.);
00348     h["found_"+types[t]]     = new TH1F(("found_"+types[t]).c_str(),"found hits",20, 0., 20.);
00349     h["lost_"+types[t]]      = new TH1F(("lost_"+types[t]).c_str(),"lost hits",20, 0., 20.);
00350     h["nchi2_"+types[t]]     = new TH1F(("nchi2_"+types[t]).c_str(),"normalized track chi2",100, 0., 20.);
00351     h["rstart_"+types[t]]    = new TH1F(("rstart_"+types[t]).c_str(),"start radius",100, 0., 20.);
00352     h["tfom_"+types[t]]      = new TH1F(("tfom_"+types[t]).c_str(),"track figure of merit",100, 0., 100.);
00353     h["expectedInner_"+types[t]]      = new TH1F(("expectedInner_"+types[t]).c_str(),"expected inner hits ",10, 0., 10.);
00354     h["expectedOuter_"+types[t]]      = new TH1F(("expectedOuter_"+types[t]).c_str(),"expected outer hits ",10, 0., 10.);
00355     h["logtresxy_"+types[t]] = new TH1F(("logtresxy_"+types[t]).c_str(),"log10(track r-phi resolution/um)",100, 0., 5.);
00356     h["logtresz_"+types[t]] = new TH1F(("logtresz_"+types[t]).c_str(),"log10(track z resolution/um)",100, 0., 5.);
00357     h["tpullxy_"+types[t]]   = new TH1F(("tpullxy_"+types[t]).c_str(),"track r-phi pull",100, -10., 10.);
00358     add(h, new TH2F( ("lvseta_"+types[t]).c_str(),"cluster length vs eta",60,-3., 3., 20, 0., 20));
00359     add(h, new TH2F( ("lvstanlambda_"+types[t]).c_str(),"cluster length vs tan lambda",60,-6., 6., 20, 0., 20));
00360     add(h, new TH1F( ("restrkz_"+types[t]).c_str(),"z-residuals (track vs vertex)", 200, -5., 5.));
00361     add(h, new TH2F( ("restrkzvsphi_"+types[t]).c_str(),"z-residuals (track - vertex)", 12,-3.14159,3.14159,100, -5., 5.));
00362     add(h, new TH2F( ("restrkzvseta_"+types[t]).c_str(),"z-residuals (track - vertex)", 12,-3.,3.,200, -5., 5.));
00363     add(h, new TH2F( ("pulltrkzvsphi_"+types[t]).c_str(),"normalized z-residuals (track - vertex)", 12,-3.14159,3.14159,100, -5., 5.));
00364     add(h, new TH2F( ("pulltrkzvseta_"+types[t]).c_str(),"normalized z-residuals (track - vertex)", 12,-3.,3.,100, -5., 5.));
00365     add(h, new TH1F( ("pulltrkz_"+types[t]).c_str(),"normalized z-residuals (track vs vertex)", 100, -5., 5.));
00366     add(h, new TH1F( ("sigmatrkz0_"+types[t]).c_str(),"z-resolution (excluding beam)", 100, 0., 5.));
00367     add(h, new TH1F( ("sigmatrkz_"+types[t]).c_str(),"z-resolution (including beam)", 100,0., 5.));
00368     add(h, new TH1F( ("nbarrelhits_"+types[t]).c_str(),"number of pixel barrel hits", 10, 0., 10.));
00369     add(h, new TH1F( ("nbarrelLayers_"+types[t]).c_str(),"number of pixel barrel layers", 10, 0., 10.));
00370     add(h, new TH1F( ("nPxLayers_"+types[t]).c_str(),"number of pixel layers (barrel+endcap)", 10, 0., 10.));
00371     add(h, new TH1F( ("nSiLayers_"+types[t]).c_str(),"number of Tracker layers ", 20, 0., 20.));
00372     add(h, new TH1F( ("trackAlgo_"+types[t]).c_str(),"track algorithm ", 30, 0., 30.));
00373     add(h, new TH1F( ("trackQuality_"+types[t]).c_str(),"track quality ", 7, -1., 6.));
00374   }
00375   add(h, new TH1F("trackWt","track weight in vertex",100,0., 1.));
00376    
00377 
00378   h["nrectrk"]->StatOverflows(kTRUE);
00379   h["nrectrk"]->StatOverflows(kTRUE);
00380   h["nrectrk0vtx"]->StatOverflows(kTRUE);
00381   h["nseltrk0vtx"]->StatOverflows(kTRUE);
00382   h["nrecsimtrk"]->StatOverflows(kTRUE);
00383   h["nrecnosimtrk"]->StatOverflows(kTRUE);
00384   h["nseltrk"]->StatOverflows(kTRUE);
00385   h["nbtksinvtx"]->StatOverflows(kTRUE);
00386   h["nbtksinvtxPU"]->StatOverflows(kTRUE);
00387   h["nbtksinvtxTag"]->StatOverflows(kTRUE);
00388   h["nbtksinvtx2"]->StatOverflows(kTRUE);
00389   h["nbtksinvtxPU2"]->StatOverflows(kTRUE);
00390   h["nbtksinvtxTag2"]->StatOverflows(kTRUE);
00391 
00392   // pile-up and track assignment related histograms (MC)
00393   h["npu0"]       =new TH1F("npu0","Number of simulated vertices",40,0.,40.);
00394   h["npu1"]       =new TH1F("npu1","Number of simulated vertices with >0 track",40,0.,40.);
00395   h["npu2"]       =new TH1F("npu2","Number of simulated vertices with >1 track",40,0.,40.);
00396   h["nrecv"]      =new TH1F("nrecv","# of reconstructed vertices", 40, 0, 40);
00397   add(h,new TH2F("nrecvsnpu","#rec vertices vs number of sim vertices with >0 tracks", 40,  0., 40, 40,  0, 40));
00398   add(h,new TH2F("nrecvsnpu2","#rec vertices vs number of sim vertices with >1 tracks", 40,  0., 40, 40,  0, 40));
00399   add(h,new TH1F("sumpt","sumpt of simulated tracks",100,0.,100.));
00400   add(h,new TH1F("sumptSignal","sumpt of simulated tracks in Signal events",100,0.,200.));
00401   add(h,new TH1F("sumptPU","sumpt of simulated tracks in PU events",100,0.,200.));
00402   add(h,new TH1F("sumpt2rec","sumpt2 of reconstructed and matched tracks",100,0.,100.));
00403   add(h,new TH1F("sumpt2","sumpt2 of simulated tracks",100,0.,100.));
00404   add(h,new TH1F("sumpt2Signal","sumpt2 of simulated tracks in Signal events",100,0.,200.));
00405   add(h,new TH1F("sumpt2PU","sumpt2 of simulated tracks in PU events",100,0.,200.));
00406   add(h,new TH1F("sumpt2rec","sumpt2 of reconstructed and matched tracks",100,0.,100.));
00407   add(h,new TH1F("sumpt2recSignal","sumpt2 of reconstructed and matched tracks in Signal events",100,0.,200.));
00408   add(h,new TH1F("sumpt2recPU","sumpt2 of reconstructed and matched tracks in PU events",100,0.,200.));
00409   add(h,new TH1F("nRecTrkInSimVtx","number of reco tracks matched to sim-vertex", 101, 0., 100));
00410   add(h,new TH1F("nRecTrkInSimVtxSignal","number of reco tracks matched to signal sim-vertex", 101, 0., 100));
00411   add(h,new TH1F("nRecTrkInSimVtxPU","number of reco tracks matched to PU-vertex", 101, 0., 100));
00412   add(h,new TH1F("nPrimRecTrkInSimVtx","number of reco primary tracks matched to sim-vertex", 101, 0., 100));
00413   add(h,new TH1F("nPrimRecTrkInSimVtxSignal","number of reco primary tracks matched to signal sim-vertex", 101, 0., 100));
00414   add(h,new TH1F("nPrimRecTrkInSimVtxPU","number of reco primary tracks matched to PU-vertex", 101, 0., 100));
00415   // obsolete, scheduled for removal
00416   add(h,new TH1F("recPurity","track purity of reconstructed vertices", 101, 0., 1.01));
00417   add(h,new TH1F("recPuritySignal","track purity of reconstructed Signal vertices", 101, 0., 1.01));
00418   add(h,new TH1F("recPurityPU","track purity of reconstructed PU vertices", 101, 0., 1.01));
00419   // end of obsolete
00420   add(h,new TH1F("recmatchPurity","track purity of all vertices", 101, 0., 1.01));
00421   add(h,new TH1F("recmatchPurityTag","track purity of tagged vertices", 101, 0., 1.01));
00422   add(h,new TH1F("recmatchPurityTagSignal","track purity of tagged Signal vertices", 101, 0., 1.01));
00423   add(h,new TH1F("recmatchPurityTagPU","track purity of tagged PU vertices", 101, 0., 1.01));
00424   add(h,new TH1F("recmatchPuritynoTag","track purity of untagged vertices", 101, 0., 1.01));
00425   add(h,new TH1F("recmatchPuritynoTagSignal","track purity of untagged Signal vertices", 101, 0., 1.01));
00426   add(h,new TH1F("recmatchPuritynoTagPU","track purity of untagged PU vertices", 101, 0., 1.01));
00427   add(h,new TH1F("recmatchvtxs","number of sim vertices contributing to recvtx", 10, 0., 10.));
00428   add(h,new TH1F("recmatchvtxsTag","number of sim vertices contributing to recvtx", 10, 0., 10.));
00429   add(h,new TH1F("recmatchvtxsnoTag","number of sim vertices contributing to recvtx", 10, 0., 10.));
00430   //
00431   add(h,new TH1F("trkAssignmentEfficiency", "track to vertex assignment efficiency", 101, 0., 1.01) );
00432   add(h,new TH1F("trkAssignmentEfficiencySignal", "track to signal vertex assignment efficiency", 101, 0., 1.01) );
00433   add(h,new TH1F("trkAssignmentEfficiencyPU", "track to PU vertex assignment efficiency", 101, 0., 1.01) );
00434   add(h,new TH1F("primtrkAssignmentEfficiency", "track to vertex assignment efficiency", 101, 0., 1.01) );
00435   add(h,new TH1F("primtrkAssignmentEfficiencySignal", "track to signal vertex assignment efficiency", 101, 0., 1.01) );
00436   add(h,new TH1F("primtrkAssignmentEfficiencyPU", "track to PU vertex assignment efficiency", 101, 0., 1.01) );
00437   add(h,new TH1F("vtxMultiplicity", "number of rec vertices containg tracks from one true vertex", 10, 0., 10.) );
00438   add(h,new TH1F("vtxMultiplicitySignal", "number of rec vertices containg tracks from the Signal Vertex", 10, 0., 10.) );
00439   add(h,new TH1F("vtxMultiplicityPU", "number of rec vertices containg tracks from a PU Vertex", 10, 0., 10.) );
00440   
00441   add(h,new TProfile("vtxFindingEfficiencyVsNtrk","finding efficiency vs number of associated rec tracks",100, 0., 100., 0., 1.) );
00442   add(h,new TProfile("vtxFindingEfficiencyVsNtrkSignal","Signal vertex finding efficiency vs number of associated rec tracks",100, 0., 100., 0., 1.) );
00443   add(h,new TProfile("vtxFindingEfficiencyVsNtrkPU","PU vertex finding efficiency vs number of associated rec tracks",100, 0., 100., 0., 1.) );
00444 
00445   add(h,new TH1F("TagVtxTrkPurity","TagVtxTrkPurity",100,0.,1.01));
00446   add(h,new TH1F("TagVtxTrkEfficiency","TagVtxTrkEfficiency",100,0.,1.01));
00447   
00448   add(h,new TH1F("matchVtxFraction","fraction of sim vertex tracks found in a recvertex",101,0,1.01));
00449   add(h,new TH1F("matchVtxFractionSignal","fraction of sim vertex tracks found in a recvertex",101,0,1.01));
00450   add(h,new TH1F("matchVtxFractionPU","fraction of sim vertex tracks found in a recvertex",101,0,1.01));
00451   add(h,new TH1F("matchVtxFractionCum","fraction of sim vertex tracks found in a recvertex",101,0,1.01));
00452   add(h,new TH1F("matchVtxFractionCumSignal","fraction of sim vertexs track found in a recvertex",101,0,1.01));
00453   add(h,new TH1F("matchVtxFractionCumPU","fraction of sim vertex tracks found in a recvertex",101,0,1.01));
00454   add(h,new TH1F("matchVtxEfficiency","efficiency for finding matching rec vertex",2,-0.5,1.5));
00455   add(h,new TH1F("matchVtxEfficiencySignal","efficiency for finding matching rec vertex",2,-0.5,1.5));
00456   add(h,new TH1F("matchVtxEfficiencyPU","efficiency for finding matching rec vertex",2,-0.5,1.5));
00457   add(h,new TH1F("matchVtxEfficiency2","efficiency for finding matching rec vertex (nt>1)",2,-0.5,1.5));
00458   add(h,new TH1F("matchVtxEfficiency2Signal","efficiency for finding matching rec vertex (nt>1)",2,-0.5,1.5));
00459   add(h,new TH1F("matchVtxEfficiency2PU","efficiency for finding matching rec vertex (nt>1)",2,-0.5,1.5));
00460   add(h,new TH1F("matchVtxEfficiency5","efficiency for finding matching rec vertex (purity>0.5)",2,-0.5,1.5));
00461   add(h,new TH1F("matchVtxEfficiency5Signal","efficiency for finding matching rec vertex (purity>0.5)",2,-0.5,1.5));
00462   add(h,new TH1F("matchVtxEfficiency5PU","efficiency for finding matching rec vertex (purity>0.5)",2,-0.5,1.5));
00463 
00464 
00465   add(h,new TH1F("matchVtxEfficiencyZ","efficiency for finding matching rec vertex within 1 mm",2,-0.5,1.5));
00466   add(h,new TH1F("matchVtxEfficiencyZSignal","efficiency for finding matching rec vertex within 1 mm",2,-0.5,1.5));
00467   add(h,new TH1F("matchVtxEfficiencyZPU","efficiency for finding matching rec vertex within 1 mm",2,-0.5,1.5));
00468 
00469   add(h,new TH1F("matchVtxEfficiencyZ1","efficiency for finding matching rec vertex within 1 mm (nt>0)",2,-0.5,1.5));
00470   add(h,new TH1F("matchVtxEfficiencyZ1Signal","efficiency for finding matching rec vertex within 1 mm (nt>0)",2,-0.5,1.5));
00471   add(h,new TH1F("matchVtxEfficiencyZ1PU","efficiency for finding matching rec vertex within 1 mm (nt>0)",2,-0.5,1.5));
00472 
00473   add(h,new TH1F("matchVtxEfficiencyZ2","efficiency for finding matching rec vertex within 1 mm (nt>1)",2,-0.5,1.5));
00474   add(h,new TH1F("matchVtxEfficiencyZ2Signal","efficiency for finding matching rec vertex within 1 mm (nt>1)",2,-0.5,1.5));
00475   add(h,new TH1F("matchVtxEfficiencyZ2PU","efficiency for finding matching rec vertex within 1 mm (nt>1)",2,-0.5,1.5));
00476 
00477   add(h,new TH1F("matchVtxZ","z distance to matched recvtx",100, -0.1, 0.1));
00478   add(h,new TH1F("matchVtxZPU","z distance to matched recvtx",100, -0.1, 0.1));
00479   add(h,new TH1F("matchVtxZSignal","z distance to matched recvtx",100, -0.1, 0.1));
00480 
00481   add(h,new TH1F("matchVtxZCum","z distance to matched recvtx",1001,0, 1.01));
00482   add(h,new TH1F("matchVtxZCumSignal","z distance to matched recvtx",1001,0, 1.01));
00483   add(h,new TH1F("matchVtxZCumPU","z distance to matched recvtx",1001,0, 1.01));
00484 
00485   add(h, new TH1F("unmatchedVtx","number of unmatched rec vertices (fakes)",10,0.,10.));
00486   add(h, new TH1F("unmatchedVtxFrac","fraction of unmatched rec vertices (fakes)",1000,0.,1.0));
00487   add(h, new TH1F("unmatchedVtxZ","z of unmached rec  vertices (fakes)",100,-20., 20.));
00488   add(h, new TH1F("unmatchedVtxNdof","ndof of unmatched rec vertices (fakes)", 500,0., 100.));
00489   add(h,new TH2F("correctlyassigned","pt and eta of correctly assigned tracks", 60,  -3., 3., 100, 0, 10.));
00490   add(h,new TH2F("misassigned","pt and eta of mis assigned tracks", 60,  -3., 3., 100, 0, 10.));
00491 
00492   add(h,new TH1F("ptcat","pt of correctly assigned tracks", 100, 0, 10.));
00493   add(h,new TH1F("etacat","eta of correctly assigned tracks", 60, -3., 3.));
00494   add(h,new TH1F("phicat","phi of correctly assigned tracks", 100, -3.14159, 3.14159));
00495   add(h,new TH1F("dzcat","dz of correctly assigned tracks", 100, 0., 1.));
00496 
00497   add(h,new TH1F("ptmis","pt of mis-assigned tracks", 100, 0, 10.));
00498   add(h,new TH1F("etamis","eta of mis-assigned tracks", 60, -3., 3.));
00499   add(h,new TH1F("phimis","phi of mis-assigned tracks",100, -3.14159, 3.14159));
00500   add(h,new TH1F("dzmis","dz of mis-assigned tracks", 100, 0., 1.));
00501 
00502 
00503   add(h,new TH1F("Tc","Tc computed with Truth matched Reco Tracks",100,0.,20.));
00504   add(h,new TH1F("TcSignal","Tc of signal vertices computed with Truth matched Reco Tracks",100,0.,20.));
00505   add(h,new TH1F("TcPU","Tc of PU vertices computed with Truth matched Reco Tracks",100,0.,20.));
00506 
00507   add(h,new TH1F("logTc","log Tc computed with Truth matched Reco Tracks",100,-2.,8.));
00508   add(h,new TH1F("logTcSignal","log Tc of signal vertices computed with Truth matched Reco Tracks",100,-2.,8.));
00509   add(h,new TH1F("logTcPU","log Tc of PU vertices computed with Truth matched Reco Tracks",100,-2.,8.));
00510 
00511   add(h,new TH1F("xTc","Tc of merged clusters",100,0.,20.));
00512   add(h,new TH1F("xTcSignal","Tc of signal vertices merged with PU",100,0.,20.));
00513   add(h,new TH1F("xTcPU","Tc of merged PU vertices",100,0.,20.));
00514 
00515   add(h,new TH1F("logxTc","log Tc merged vertices",100,-2.,8.));
00516   add(h,new TH1F("logxTcSignal","log Tc of signal vertices merged with PU",100,-2.,8.));
00517   add(h,new TH1F("logxTcPU","log Tc of merged PU vertices ",100,-2.,8.));
00518 
00519   add(h,new TH1F("logChisq","Chisq/ntrk computed with Truth matched Reco Tracks",100,-2.,8.));
00520   add(h,new TH1F("logChisqSignal","Chisq/ntrk of signal vertices computed with Truth matched Reco Tracks",100,-2.,8.));
00521   add(h,new TH1F("logChisqPU","Chisq/ntrk of PU vertices computed with Truth matched Reco Tracks",100,-2.,8.));
00522 
00523   add(h,new TH1F("logxChisq","Chisq/ntrk of merged clusters",100,-2.,8.));
00524   add(h,new TH1F("logxChisqSignal","Chisq/ntrk of signal vertices merged with PU",100,-2.,8.));
00525   add(h,new TH1F("logxChisqPU","Chisq/ntrk of merged PU vertices",100,-2.,8.));
00526 
00527   add(h,new TH1F("Chisq","Chisq/ntrk computed with Truth matched Reco Tracks",100,0.,20.));
00528   add(h,new TH1F("ChisqSignal","Chisq/ntrk of signal vertices computed with Truth matched Reco Tracks",100,0.,20.));
00529   add(h,new TH1F("ChisqPU","Chisq/ntrk of PU vertices computed with Truth matched Reco Tracks",100,0.,20.));
00530 
00531   add(h,new TH1F("xChisq","Chisq/ntrk of merged clusters",100,0.,20.));
00532   add(h,new TH1F("xChisqSignal","Chisq/ntrk of signal vertices merged with PU",100,0.,20.));
00533   add(h,new TH1F("xChisqPU","Chisq/ntrk of merged PU vertices",100,0.,20.));
00534 
00535   add(h,new TH1F("dzmax","dzmax computed with Truth matched Reco Tracks",100,0.,2.));
00536   add(h,new TH1F("dzmaxSignal","dzmax of signal vertices computed with Truth matched Reco Tracks",100,0.,2.));
00537   add(h,new TH1F("dzmaxPU","dzmax of PU vertices computed with Truth matched Reco Tracks",100,0.,2.));
00538 
00539   add(h,new TH1F("xdzmax","dzmax of merged clusters",100,0.,2.));
00540   add(h,new TH1F("xdzmaxSignal","dzmax of signal vertices merged with PU",100,0.,2.));
00541   add(h,new TH1F("xdzmaxPU","dzmax of merged PU vertices",100,0.,2.));
00542 
00543   add(h,new TH1F("dztrim","dzmax computed with Truth matched Reco Tracks",100,0.,2.));
00544   add(h,new TH1F("dztrimSignal","dzmax of signal vertices computed with Truth matched Reco Tracks",100,0.,2.));
00545   add(h,new TH1F("dztrimPU","dzmax of PU vertices computed with Truth matched Reco Tracks",100,0.,2.));
00546 
00547   add(h,new TH1F("xdztrim","dzmax of merged clusters",100,0.,2.));
00548   add(h,new TH1F("xdztrimSignal","dzmax of signal vertices merged with PU",100,0.,2.));
00549   add(h,new TH1F("xdztrimPU","dzmax of merged PU vertices",100,0.,2.));
00550 
00551   add(h,new TH1F("m4m2","m4m2 computed with Truth matched Reco Tracks",100,0.,100.));
00552   add(h,new TH1F("m4m2Signal","m4m2 of signal vertices computed with Truth matched Reco Tracks",100,0.,100.));
00553   add(h,new TH1F("m4m2PU","m4m2 of PU vertices computed with Truth matched Reco Tracks",100,0.,100.));
00554 
00555   add(h,new TH1F("xm4m2","m4m2 of merged clusters",100,0.,100.));
00556   add(h,new TH1F("xm4m2Signal","m4m2 of signal vertices merged with PU",100,0.,100.));
00557   add(h,new TH1F("xm4m2PU","m4m2 of merged PU vertices",100,0.,100.));
00558 
00559   return h;
00560 }
00561 
00562 
00563 //
00564 // member functions
00565 //
00566 void PrimaryVertexAnalyzer4PU::beginJob(){
00567   std::cout << " PrimaryVertexAnalyzer4PU::beginJob  conversion from sim units to rec units is " << simUnit_ << std::endl;
00568 
00569 
00570   rootFile_->cd();
00571 
00572   TDirectory *noBS = rootFile_->mkdir("noBS");
00573   noBS->cd();
00574   hnoBS=bookVertexHistograms();
00575   for(std::map<std::string,TH1*>::const_iterator hist=hnoBS.begin(); hist!=hnoBS.end(); hist++){
00576     hist->second->SetDirectory(noBS);
00577   }
00578 
00579   TDirectory *withBS = rootFile_->mkdir("BS");
00580   withBS->cd();
00581   hBS=bookVertexHistograms();
00582   for(std::map<std::string,TH1*>::const_iterator hist=hBS.begin(); hist!=hBS.end(); hist++){
00583     hist->second->SetDirectory(withBS);
00584   }
00585 
00586   TDirectory *DA = rootFile_->mkdir("DA");
00587   DA->cd();
00588   hDA=bookVertexHistograms();
00589   for(std::map<std::string,TH1*>::const_iterator hist=hDA.begin(); hist!=hDA.end(); hist++){
00590     hist->second->SetDirectory(DA);
00591   }
00592 
00593 //   TDirectory *PIX = rootFile_->mkdir("PIX");
00594 //   PIX->cd();
00595 //   hPIX=bookVertexHistograms();
00596 //   for(std::map<std::string,TH1*>::const_iterator hist=hPIX.begin(); hist!=hPIX.end(); hist++){
00597 //     hist->second->SetDirectory(PIX);
00598 //   }
00599 
00600 //   TDirectory *MVF = rootFile_->mkdir("MVF");
00601 //   MVF->cd();
00602 //   hMVF=bookVertexHistograms();
00603 //   for(std::map<std::string,TH1*>::const_iterator hist=hMVF.begin(); hist!=hMVF.end(); hist++){
00604 //     hist->second->SetDirectory(MVF);
00605 //   }
00606 
00607   rootFile_->cd();
00608   hsimPV["rapidity"] = new TH1F("rapidity","rapidity ",100,-10., 10.);
00609   hsimPV["chRapidity"] = new TH1F("chRapidity","charged rapidity ",100,-10., 10.);
00610   hsimPV["recRapidity"] = new TH1F("recRapidity","reconstructed rapidity ",100,-10., 10.);
00611   hsimPV["pt"] = new TH1F("pt","pt ",100,0., 20.);
00612 
00613   hsimPV["xsim"]         = new TH1F("xsim","simulated x",100,-0.01,0.01); // 0.01cm = 100 um
00614   hsimPV["ysim"]         = new TH1F("ysim","simulated y",100,-0.01,0.01);
00615   hsimPV["zsim"]         = new TH1F("zsim","simulated z",100,-20.,20.);
00616 
00617   hsimPV["xsim1"]        = new TH1F("xsim1","simulated x",100,-4.,4.);
00618   hsimPV["ysim1"]        = new TH1F("ysim1","simulated y",100,-4.,4.);
00619   hsimPV["zsim1"]        = new TH1F("zsim1","simulated z",100,-40.,40.);
00620 
00621   add(hsimPV, new TH1F("xsim2PU","simulated x (Pile-up)",100,-1.,1.));
00622   add(hsimPV, new TH1F("ysim2PU","simulated y (Pile-up)",100,-1.,1.)); 
00623   add(hsimPV, new TH1F("zsim2PU","simulated z (Pile-up)",100,-20.,20.)); 
00624   add(hsimPV, new TH1F("xsim2Signal","simulated x (Signal)",100,-1.,1.));
00625   add(hsimPV, new TH1F("ysim2Signal","simulated y (Signal)",100,-1.,1.));
00626   add(hsimPV, new TH1F("zsim2Signal","simulated z (Signal)",100,-20.,20.));
00627 
00628   hsimPV["xsim2"]        = new TH1F("xsim2","simulated x",100,-1,1); // 0.01cm = 100 um
00629   hsimPV["ysim2"]        = new TH1F("ysim2","simulated y",100,-1,1);
00630   hsimPV["zsim2"]        = new TH1F("zsim2","simulated z",100,-20.,20.);
00631   hsimPV["xsim3"]        = new TH1F("xsim3","simulated x",100,-0.1,0.1); // 0.01cm = 100 um
00632   hsimPV["ysim3"]        = new TH1F("ysim3","simulated y",100,-0.1,0.1);
00633   hsimPV["zsim3"]        = new TH1F("zsim3","simulated z",100,-20.,20.);
00634   hsimPV["xsimb"]        = new TH1F("xsimb","simulated x",100,-0.01,0.01); // 0.01cm = 100 um
00635   hsimPV["ysimb"]        = new TH1F("ysimb","simulated y",100,-0.01,0.01);
00636   hsimPV["zsimb"]        = new TH1F("zsimb","simulated z",100,-20.,20.);
00637   hsimPV["xsimb1"]        = new TH1F("xsimb1","simulated x",100,-0.1,0.1); // 0.01cm = 100 um
00638   hsimPV["ysimb1"]        = new TH1F("ysimb1","simulated y",100,-0.1,0.1);
00639   hsimPV["zsimb1"]        = new TH1F("zsimb1","simulated z",100,-20.,20.);
00640   add(hsimPV, new TH1F("xbeam","beamspot x",100,-1.,1.));
00641   add(hsimPV, new TH1F("ybeam","beamspot y",100,-1.,1.));
00642   add(hsimPV, new TH1F("zbeam","beamspot z",100,-1.,1.));
00643   add(hsimPV, new TH1F("wxbeam","beamspot sigma x",100,-1.,1.));
00644   add(hsimPV, new TH1F("wybeam","beamspot sigma y",100,-1.,1.));
00645   add(hsimPV, new TH1F("wzbeam","beamspot sigma z",100,-1.,1.));
00646   hsimPV["xsim2"]->StatOverflows(kTRUE);
00647   hsimPV["ysim2"]->StatOverflows(kTRUE);
00648   hsimPV["zsim2"]->StatOverflows(kTRUE);
00649   hsimPV["xsimb"]->StatOverflows(kTRUE);
00650   hsimPV["ysimb"]->StatOverflows(kTRUE);
00651   hsimPV["zsimb"]->StatOverflows(kTRUE);
00652   hsimPV["nsimvtx"]      = new TH1F("nsimvtx","# of simulated vertices", 50, -0.5, 49.5);
00653   //  hsimPV["nsimtrk"]      = new TH1F("nsimtrk","# of simulated tracks", 100, -0.5, 99.5); //  not filled right now, also exists in hBS..
00654   //  hsimPV["nsimtrk"]->StatOverflows(kTRUE);
00655   hsimPV["nbsimtksinvtx"]= new TH1F("nbsimtksinvtx","simulated tracks in vertex",100,-0.5,99.5); 
00656   hsimPV["nbsimtksinvtx"]->StatOverflows(kTRUE);
00657 
00658 }
00659 
00660 
00661 void PrimaryVertexAnalyzer4PU::endJob() {
00662   std::cout << "this is void PrimaryVertexAnalyzer4PU::endJob() " << std::endl;
00663   //cumulate some histos
00664   double sumDA=0,sumBS=0,sumnoBS=0;
00665   // double sumPIX=0,sumMVF=0;
00666   for(int i=101; i>0; i--){
00667     sumDA+=hDA["matchVtxFractionSignal"]->GetBinContent(i)/hDA["matchVtxFractionSignal"]->Integral();
00668     hDA["matchVtxFractionCumSignal"]->SetBinContent(i,sumDA);
00669     sumBS+=hBS["matchVtxFractionSignal"]->GetBinContent(i)/hBS["matchVtxFractionSignal"]->Integral();
00670     hBS["matchVtxFractionCumSignal"]->SetBinContent(i,sumBS);
00671     sumnoBS+=hnoBS["matchVtxFractionSignal"]->GetBinContent(i)/hnoBS["matchVtxFractionSignal"]->Integral();
00672     hnoBS["matchVtxFractionCumSignal"]->SetBinContent(i,sumnoBS);
00673 //     sumPIX+=hPIX["matchVtxFractionSignal"]->GetBinContent(i)/hPIX["matchVtxFractionSignal"]->Integral();
00674 //     hPIX["matchVtxFractionCumSignal"]->SetBinContent(i,sumPIX);
00675 //     sumMVF+=hMVF["matchVtxFractionSignal"]->GetBinContent(i)/hMVF["matchVtxFractionSignal"]->Integral();
00676 //     hMVF["matchVtxFractionCumSignal"]->SetBinContent(i,sumMVF);
00677   }
00678   sumDA=0,sumBS=0,sumnoBS=0;
00679   //sumPIX=0,sumMVF=0;
00680   for(int i=1; i<1001; i++){
00681     sumDA+=hDA["abszdistancetag"]->GetBinContent(i);
00682     hDA["abszdistancetagcum"]->SetBinContent(i,sumDA/float(hDA["abszdistancetag"]->GetEntries()));
00683     sumBS+=hBS["abszdistancetag"]->GetBinContent(i);
00684     hBS["abszdistancetagcum"]->SetBinContent(i,sumBS/float(hBS["abszdistancetag"]->GetEntries()));
00685     sumnoBS+=hnoBS["abszdistancetag"]->GetBinContent(i);
00686     hnoBS["abszdistancetagcum"]->SetBinContent(i,sumnoBS/float(hnoBS["abszdistancetag"]->GetEntries()));
00687 //     sumPIX+=hPIX["abszdistancetag"]->GetBinContent(i);
00688 //     hPIX["abszdistancetagcum"]->SetBinContent(i,sumPIX/float(hPIX["abszdistancetag"]->GetEntries()));
00689 //     sumMVF+=hMVF["abszdistancetag"]->GetBinContent(i);
00690 //     hMVF["abszdistancetagcum"]->SetBinContent(i,sumMVF/float(hMVF["abszdistancetag"]->GetEntries()));
00691   }
00692 
00693   Cumulate(hBS["matchVtxZCum"]);   Cumulate(hBS["matchVtxZCumSignal"]);   Cumulate(hBS["matchVtxZCumPU"]); 
00694   Cumulate(hnoBS["matchVtxZCum"]);   Cumulate(hnoBS["matchVtxZCumSignal"]);   Cumulate(hnoBS["matchVtxZCumPU"]); 
00695   Cumulate(hDA["matchVtxZCum"]);   Cumulate(hDA["matchVtxZCumSignal"]);   Cumulate(hDA["matchVtxZCumPU"]); 
00696   /*
00697    h->ComputeIntegral();
00698    Double_t *integral = h->GetIntegral();
00699    h->SetContent(integral);
00700   */
00701 
00702   // make a reference for ndofnr2
00703   //hDA["vtxndof"]->ComputeIntegral();
00704   //Double_t *integral = hDA["vtxndf"]->GetIntegral();
00705   //   h->SetContent(integral);
00706   double p;
00707   for(int i=1; i<501; i++){
00708     if(hDA["vtxndf"]->GetEntries()>0){
00709       p=  hDA["vtxndf"]->Integral(i,501)/hDA["vtxndf"]->GetEntries();    hDA["vtxndfc"]->SetBinContent(i,p*hDA["vtxndf"]->GetBinContent(i));
00710     }
00711     if(hBS["vtxndf"]->GetEntries()>0){
00712       p=  hBS["vtxndf"]->Integral(i,501)/hBS["vtxndf"]->GetEntries();    hBS["vtxndfc"]->SetBinContent(i,p*hBS["vtxndf"]->GetBinContent(i));
00713     }
00714     if(hnoBS["vtxndf"]->GetEntries()>0){
00715       p=hnoBS["vtxndf"]->Integral(i,501)/hnoBS["vtxndf"]->GetEntries();  hnoBS["vtxndfc"]->SetBinContent(i,p*hnoBS["vtxndf"]->GetBinContent(i));
00716     }
00717 //     if(hPIX["vtxndf"]->GetEntries()>0){
00718 //       p=hPIX["vtxndf"]->Integral(i,501)/hPIX["vtxndf"]->GetEntries();  hPIX["vtxndfc"]->SetBinContent(i,p*hPIX["vtxndf"]->GetBinContent(i));
00719 //     }
00720   }
00721   
00722   rootFile_->cd();
00723   for(std::map<std::string,TH1*>::const_iterator hist=hsimPV.begin(); hist!=hsimPV.end(); hist++){
00724     std::cout << "writing " << hist->first << std::endl;
00725     hist->second->Write();
00726   }
00727   rootFile_->Write();
00728   std::cout << "PrimaryVertexAnalyzer4PU::endJob: done" << std::endl;
00729 }
00730 
00731 
00732 
00733 
00734 // helper functions
00735 std::vector<PrimaryVertexAnalyzer4PU::SimPart> PrimaryVertexAnalyzer4PU::getSimTrkParameters(
00736                                                                                              edm::Handle<edm::SimTrackContainer> & simTrks,
00737                                                                                              edm::Handle<edm::SimVertexContainer> & simVtcs,
00738                                                                                              double simUnit)
00739 {
00740    std::vector<SimPart > tsim;
00741    if(simVtcs->begin()==simVtcs->end()){
00742      if(verbose_){
00743        cout << "  PrimaryVertexAnalyzer4PU::getSimTrkParameters  no simvtcs" << endl;
00744      }
00745      return tsim;
00746    }
00747    if(verbose_){
00748      cout << "  PrimaryVertexAnalyzer4PU::getSimTrkParameters simVtcs n=" << simVtcs->size() << endl;
00749      cout << "  PrimaryVertexAnalyzer4PU::getSimTrkParameters 1st position" << setw(8) << setprecision(4) << simVtcs->begin()->position() << endl;
00750    }
00751    double t0=simVtcs->begin()->position().e();
00752 
00753    for(edm::SimTrackContainer::const_iterator t=simTrks->begin();
00754        t!=simTrks->end(); ++t){
00755      if (t->noVertex()){
00756        std::cout << "simtrk  has no vertex" << std::endl;
00757      }else{
00758        // get the vertex position
00759        //HepLorentzVector v=(*simVtcs)[t->vertIndex()].position();
00760        math::XYZTLorentzVectorD v((*simVtcs)[t->vertIndex()].position().x(),
00761                           (*simVtcs)[t->vertIndex()].position().y(),
00762                           (*simVtcs)[t->vertIndex()].position().z(),
00763                           (*simVtcs)[t->vertIndex()].position().e());
00764        int pdgCode=t->type();
00765 
00766        if( pdgCode==-99 ){
00767          // such entries cause crashes, no idea what they are
00768          std::cout << "funny particle skipped  , code="  << pdgCode << std::endl;
00769        }else{
00770          double Q=0; //double Q=HepPDT::theTable().getParticleData(pdgCode)->charge();
00771          if ((pdgCode==11)||(pdgCode==13)||(pdgCode==15)||(pdgCode==-211)||(pdgCode==-2212)||(pdgCode==-321)||(pdgCode==-3222)){Q=-1;}
00772          else if((pdgCode==-11)||(pdgCode==-13)||(pdgCode==-15)||(pdgCode==211)||(pdgCode==2212)||(pdgCode==321)||(pdgCode==3222)){Q=1;}
00773          else {
00774            //std::cout << pdgCode << " " <<std::endl;
00775          }
00776          math::XYZTLorentzVectorD p(t->momentum().x(),t->momentum().y(),t->momentum().z(),t->momentum().e());
00777          if ( (Q != 0) && (p.pt()>0.1)  && (fabs(t->momentum().eta())<3.0)
00778               && fabs(v.z()*simUnit<20) && (sqrt(v.x()*v.x()+v.y()*v.y())<10.)){
00779            double x0=v.x()*simUnit;
00780            double y0=v.y()*simUnit;
00781            double z0=v.z()*simUnit;
00782            double kappa=-Q*0.002998*fBfield_/p.pt();
00783            double D0=x0*sin(p.phi())-y0*cos(p.phi())-0.5*kappa*(x0*x0+y0*y0);
00784            double q=sqrt(1.-2.*kappa*D0);
00785            double s0=(x0*cos(p.phi())+y0*sin(p.phi()))/q;
00786            double s1;
00787            if (fabs(kappa*s0)>0.001){
00788              s1=asin(kappa*s0)/kappa;
00789            }else{
00790              double ks02=(kappa*s0)*(kappa*s0);
00791              s1=s0*(1.+ks02/6.+3./40.*ks02*ks02+5./112.*pow(ks02,3));
00792            }
00793            SimPart sp;//ParameterVector par;
00794            sp.par[reco::TrackBase::i_qoverp] = Q/p.P();
00795            sp.par[reco::TrackBase::i_lambda] = M_PI/2.-p.theta();
00796            sp.par[reco::TrackBase::i_phi] = p.phi()-asin(kappa*s0);
00797            sp.par[reco::TrackBase::i_dxy] = -2.*D0/(1.+q);
00798            sp.par[reco::TrackBase::i_dsz] = z0*sin(p.theta())-s1*cos(p.theta());
00799 
00800            sp.pdg=pdgCode;
00801            if (v.t()-t0<1e-15){
00802              sp.type=0;  // primary
00803            }else{
00804              sp.type=1;  //secondary
00805            }
00806 
00807            // now get zpca  (get perigee wrt beam)
00808            double x1=x0-0.033; double y1=y0-0.; // FIXME how do we get the simulated beam position?
00809            D0=x1*sin(p.phi())-y1*cos(p.phi())-0.5*kappa*(x1*x1+y1*y1);
00810            q=sqrt(1.-2.*kappa*D0);
00811            s0=(x1*cos(p.phi())+y1*sin(p.phi()))/q;
00812            if (fabs(kappa*s0)>0.001){
00813              s1=asin(kappa*s0)/kappa;
00814            }else{
00815              double ks02=(kappa*s0)*(kappa*s0);
00816              s1=s0*(1.+ks02/6.+3./40.*ks02*ks02+5./112.*pow(ks02,3));
00817            }
00818            sp.ddcap=-2.*D0/(1.+q);
00819            sp.zdcap=z0-s1/tan(p.theta());
00820            sp.zvtx=z0;
00821            sp.xvtx=x0;
00822            sp.yvtx=y0;
00823 
00824            tsim.push_back(sp);
00825          }
00826        }
00827      }// has vertex
00828    }//for loop
00829    return tsim;
00830 }
00831 
00832 
00833 int*  PrimaryVertexAnalyzer4PU::supf(std::vector<SimPart>& simtrks, const reco::TrackCollection & trks){
00834   int nsim=simtrks.size();
00835   int nrec=trks.size();
00836   int *rectosim=new int[nrec]; // pointer to associated simtrk
00837   double** pij=new double*[nrec];
00838   double mu=100.; // initial chi^2 cut-off  (5 dofs !)
00839   int nmatch=0;
00840   int i=0;
00841   for(reco::TrackCollection::const_iterator t=trks.begin(); t!=trks.end(); ++t){
00842     pij[i]=new double[nsim];
00843     rectosim[i]=-1;
00844     ParameterVector  par = t->parameters();
00845     //reco::TrackBase::CovarianceMatrix V = t->covariance();
00846     reco::TrackBase::CovarianceMatrix S = t->covariance();
00847     S.Invert();
00848     for(int j=0; j<nsim; j++){
00849       simtrks[j].rec=-1;
00850       SimPart s=simtrks[j];
00851       double c=0;
00852       for(int k=0; k<5; k++){
00853         for(int l=0; l<5; l++){
00854           c+=(par(k)-s.par[k])*(par(l)-s.par[l])*S(k,l);
00855         }
00856       }
00857       pij[i][j]=exp(-0.5*c);
00858 
00859 //       double c0=pow((par[0]-s.par[0])/t->qoverpError(),2)*0.1
00860 //      +pow((par[1]-s.par[1])/t->lambdaError(),2)
00861 //      +pow((par[2]-s.par[2])/t->phiError(),2)
00862 //      +pow((par[3]-s.par[3])/t->dxyError(),2)*0.1;
00863 //         +pow((par[4]-s.par[4])/t->dszError(),2)*0.1;
00864 //       pij[i][j]=exp(-0.5*c0);
00865 
00866 //       if( c0 <100 ){
00867 //       cout << setw(3) << i << " rec " << setw(6) << par << endl;
00868 //       cout << setw(3) << j << " sim " << setw(6) << s.par << " ---> C=" << c << endl;
00869 //       cout <<  "       "  << setw(6)
00870 //         << (par[0]-s.par[0])<< ","
00871 //         << (par[1]-s.par[1])<< ","
00872 //         << (par[2]-s.par[2])<< ","
00873 //         << (par[3]-s.par[3])<< ","
00874 //         << (par[4]-s.par[4])
00875 //         << " match=" << match(simtrks[j].par, trks.at(i).parameters())
00876 //         << endl;
00877 //       cout <<  "       "  << setw(6)
00878 //         << (par[0]-s.par[0])/t->qoverpError() << ","
00879 //         << (par[1]-s.par[1])/t->lambdaError() << ","
00880 //         << (par[2]-s.par[2])/t->phiError() << ","
00881 //         << (par[3]-s.par[3])/t->dxyError() << ","
00882 //         << (par[4]-s.par[4])/t->dszError() << " c0=" << c0
00883 //         << endl <<endl;
00884 //       }
00885 
00886     }
00887     i++;
00888   }
00889 
00890   for(int k=0; k<nrec; k++){
00891     int imatch=-1; int jmatch=-1;
00892     double pmatch=0;
00893     for(int j=0; j<nsim; j++){
00894       if ((simtrks[j].rec)<0){
00895         double psum=exp(-0.5*mu); //cutoff
00896         for(int i=0; i<nrec; i++){
00897           if (rectosim[i]<0){ psum+=pij[i][j];}
00898         }
00899         for(int i=0; i<nrec; i++){
00900           if ((rectosim[i]<0)&&(pij[i][j]/psum>pmatch)){
00901             pmatch=pij[i][j]/psum;
00902             imatch=i; jmatch=j;
00903           }
00904         }
00905       }
00906     }// sim loop
00907    if((jmatch>=0)||(imatch>=0)){
00908      //std::cout << pmatch << "    " << pij[imatch][jmatch] << "  match=" <<
00909      // match(simtrks[jmatch].par, trks.at(imatch).parameters()) <<std::endl;
00910       if (pmatch>0.01){
00911         rectosim[imatch]=jmatch;
00912         simtrks[jmatch].rec=imatch;
00913         nmatch++;
00914       }else if (match(simtrks[jmatch].par, trks.at(imatch).parameters())){
00915         // accept it anyway if it matches crudely and relax the cut-off
00916         rectosim[imatch]=jmatch;
00917         simtrks[jmatch].rec=imatch;
00918         nmatch++;
00919         mu=mu*2;
00920       }
00921     }
00922   }
00923 
00924 //   std::cout << ">>>>>>>>>>>>>>>--------------supf----------------------" << std::endl;
00925 //   std::cout <<"nsim=" << nsim   << "   nrec=" << nrec << "    nmatch=" << nmatch << std::endl;
00926 //   std::cout << "rec to sim " << std::endl;
00927 //   for(int i=0; i<nrec; i++){
00928 //     std::cout << i << " ---> " << rectosim[i] << std::endl;
00929 //   }
00930 //   std::cout << "sim to rec " << std::endl;
00931 //   for(int j=0; j<nsim; j++){
00932 //     std::cout << j << " ---> " << simtrks[j].rec << std::endl;
00933 //   }
00934 
00935    std::cout << "unmatched sim " << std::endl;
00936    for(int j=0; j<nsim; j++){
00937      if(simtrks[j].rec<0){
00938        double pt= 1./simtrks[j].par[0]/tan(simtrks[j].par[1]);
00939        if((fabs(pt))>1.){
00940          std::cout << setw(3) << j << setw(8) << simtrks[j].pdg 
00941                    << setw(8) << setprecision(4) << "  (" << simtrks[j].xvtx << "," << simtrks[j].yvtx <<  "," << simtrks[j].zvtx << ")" 
00942                    << " pt= " <<  pt
00943                    << " phi=" << simtrks[j].par[2] 
00944                    << " eta= " <<  -log(tan(0.5*(M_PI/2-simtrks[j].par[1]))) 
00945                    << std::endl; 
00946        }
00947      }
00948    }
00949 //   std::cout << "<<<<<<<<<<<<<<<--------------supf----------------------" << std::endl;
00950 
00951   //delete rectosim; // or return it?
00952   for(int i=0; i<nrec; i++){delete pij[i];}
00953   delete pij;
00954   return rectosim;  // caller must delete it
00955 }
00956 
00957 
00958 
00959 
00960 
00961 
00962 
00963 
00964 bool PrimaryVertexAnalyzer4PU::match(const ParameterVector  &a,
00965                                      const ParameterVector  &b){
00966   double dqoverp =a(0)-b(0);
00967   double dlambda =a(1)-b(1);
00968   double dphi    =a(2)-b(2);
00969   double dsz     =a(4)-b(4);
00970   if (dphi>M_PI){ dphi-=M_2_PI; }else if(dphi<-M_PI){dphi+=M_2_PI;}
00971   //  return ( (fabs(dqoverp)<0.2) && (fabs(dlambda)<0.02) && (fabs(dphi)<0.04) && (fabs(dsz)<0.1) );
00972   return ( (fabs(dqoverp)<0.2) && (fabs(dlambda)<0.02) && (fabs(dphi)<0.04) && (fabs(dsz)<1.0) );
00973 }
00974 
00975 
00976 bool PrimaryVertexAnalyzer4PU::matchVertex(const simPrimaryVertex  &vsim, 
00977                                        const reco::Vertex       &vrec){
00978   return (fabs(vsim.z*simUnit_-vrec.z())<zmatch_);
00979 }
00980 
00981 bool PrimaryVertexAnalyzer4PU::isResonance(const HepMC::GenParticle * p){
00982   double ctau=(pdt_->particle( abs(p->pdg_id()) ))->lifetime();
00983   //std::cout << "isResonance   " << p->pdg_id() << " " << ctau << std::endl;
00984   return  ctau >0 && ctau <1e-6;
00985 }
00986 
00987 bool PrimaryVertexAnalyzer4PU::isFinalstateParticle(const HepMC::GenParticle * p){
00988   return ( !p->end_vertex() && p->status()==1 );
00989 }
00990 
00991 
00992 bool PrimaryVertexAnalyzer4PU::isCharged(const HepMC::GenParticle * p){
00993   const ParticleData * part = pdt_->particle( p->pdg_id() );
00994   if (part){
00995     return part->charge()!=0;
00996   }else{
00997     // the new/improved particle table doesn't know anti-particles
00998     return  pdt_->particle( -p->pdg_id() )!=0;
00999   }
01000 }
01001 
01002 
01003 
01004 
01005 void PrimaryVertexAnalyzer4PU::fillTrackHistos(std::map<std::string, TH1*> & h, const std::string & ttype, const reco::Track & t, const reco::Vertex * v){
01006     Fill(h,"rapidity_"+ttype,t.eta());
01007     Fill(h,"z0_"+ttype,t.vz());
01008     Fill(h,"phi_"+ttype,t.phi());
01009     Fill(h,"eta_"+ttype,t.eta());
01010     Fill(h,"pt_"+ttype,t.pt());
01011     Fill(h,"found_"+ttype,t.found());
01012     Fill(h,"lost_"+ttype,t.lost());
01013     Fill(h,"nchi2_"+ttype,t.normalizedChi2());
01014     Fill(h,"rstart_"+ttype,(t.innerPosition()).Rho());
01015 
01016     double d0Error=t.d0Error();
01017     double d0=t.dxy(vertexBeamSpot_.position());
01018     if (d0Error>0){ 
01019       Fill(h,"logtresxy_"+ttype,log(d0Error/0.0001)/log(10.));
01020       Fill(h,"tpullxy_"+ttype,d0/d0Error);
01021     }
01022     //double z0=t.vz();
01023     double dzError=t.dzError();
01024     if(dzError>0){
01025       Fill(h,"logtresz_"+ttype,log(dzError/0.0001)/log(10.));
01026     }
01027 
01028     //
01029     Fill(h,"sigmatrkz_"+ttype,sqrt(pow(t.dzError(),2)+wxy2_/pow(tan(t.theta()),2)));
01030     Fill(h,"sigmatrkz0_"+ttype,t.dzError());
01031 
01032     // track vs vertex 
01033     if((! (v==NULL)) && (v->ndof()>10.)) {
01034       // emulate clusterizer input
01035       //const TransientTrack & tt = theB_->build(&t);    wrong !!!!
01036       TransientTrack tt = theB_->build(&t);    tt.setBeamSpot(vertexBeamSpot_); // need the setBeamSpot !
01037       double z=(tt.stateAtBeamLine().trackStateAtPCA()).position().z();
01038       double tantheta=tan((tt.stateAtBeamLine().trackStateAtPCA()).momentum().theta());
01039       double dz2= pow(tt.track().dzError(),2)+wxy2_/pow(tantheta,2);
01040       
01041       Fill(h,"restrkz_"+ttype,z-v->position().z());
01042       Fill(h,"restrkzvsphi_"+ttype,t.phi(), z-v->position().z());
01043       Fill(h,"restrkzvseta_"+ttype,t.eta(), z-v->position().z());
01044       Fill(h,"pulltrkzvsphi_"+ttype,t.phi(), (z-v->position().z())/sqrt(dz2));
01045       Fill(h,"pulltrkzvseta_"+ttype,t.eta(), (z-v->position().z())/sqrt(dz2));
01046 
01047       Fill(h,"pulltrkz_"+ttype,(z-v->position().z())/sqrt(dz2));
01048 
01049       double x1=t.vx()-vertexBeamSpot_.x0(); double y1=t.vy()-vertexBeamSpot_.y0();
01050       double kappa=-0.002998*fBfield_*t.qoverp()/cos(t.theta());
01051       double D0=x1*sin(t.phi())-y1*cos(t.phi())-0.5*kappa*(x1*x1+y1*y1);
01052       double q=sqrt(1.-2.*kappa*D0);
01053       double s0=(x1*cos(t.phi())+y1*sin(t.phi()))/q; 
01054       // double s1;
01055       if (fabs(kappa*s0)>0.001){
01056         //s1=asin(kappa*s0)/kappa;
01057       }else{
01058         //double ks02=(kappa*s0)*(kappa*s0);
01059         //s1=s0*(1.+ks02/6.+3./40.*ks02*ks02+5./112.*pow(ks02,3));
01060       }
01061       //     sp.ddcap=-2.*D0/(1.+q);
01062       //double zdcap=t.vz()-s1/tan(t.theta());
01063 
01064     }
01065     //
01066     
01067     // collect some info on hits and clusters
01068     Fill(h,"nbarrelLayers_"+ttype,t.hitPattern().pixelBarrelLayersWithMeasurement());
01069     Fill(h,"nPxLayers_"+ttype,t.hitPattern().pixelLayersWithMeasurement());
01070     Fill(h,"nSiLayers_"+ttype,t.hitPattern().trackerLayersWithMeasurement());
01071     Fill(h,"expectedInner_"+ttype,t.trackerExpectedHitsInner().numberOfHits());
01072     Fill(h,"expectedOuter_"+ttype,t.trackerExpectedHitsOuter().numberOfHits());
01073     Fill(h,"trackAlgo_"+ttype,t.algo());
01074     Fill(h,"trackQuality_"+ttype,t.qualityMask());
01075 
01076     //
01077     int longesthit=0, nbarrel=0;
01078     for(trackingRecHit_iterator hit=t.recHitsBegin(); hit!=t.recHitsEnd(); hit++){
01079       if ((**hit).isValid()   && (**hit).geographicalId().det() == DetId::Tracker ){
01080        bool barrel = DetId((**hit).geographicalId()).subdetId() == static_cast<int>(PixelSubdetector::PixelBarrel);
01081        //bool endcap = DetId::DetId((**hit).geographicalId()).subdetId() == static_cast<int>(PixelSubdetector::PixelEndcap);
01082        if (barrel){
01083          const SiPixelRecHit *pixhit = dynamic_cast<const SiPixelRecHit*>( &(**hit));
01084          edm::Ref<edmNew::DetSetVector<SiPixelCluster>, SiPixelCluster> const& clust = (*pixhit).cluster();
01085          if (clust.isNonnull()) {
01086            nbarrel++;
01087            if (clust->sizeY()-longesthit>0) longesthit=clust->sizeY();
01088            if (clust->sizeY()>20.){
01089              Fill(h,"lvseta_"+ttype,t.eta(), 19.9);
01090              Fill(h,"lvstanlambda_"+ttype,tan(t.lambda()), 19.9);
01091            }else{
01092              Fill(h,"lvseta_"+ttype,t.eta(), float(clust->sizeY()));
01093              Fill(h,"lvstanlambda_"+ttype,tan(t.lambda()), float(clust->sizeY()));
01094            }
01095          }
01096        }
01097       }
01098     }
01099     Fill(h,"nbarrelhits_"+ttype,float(nbarrel));
01100     //-------------------------------------------------------------------
01101 
01102 }
01103 
01104 void PrimaryVertexAnalyzer4PU::dumpHitInfo(const reco::Track & t){
01105     // collect some info on hits and clusters
01106   int longesthit=0, nbarrel=0;
01107   cout << Form("%5.2f  %5.2f  : ",t.pt(),t.eta());
01108   for(trackingRecHit_iterator hit=t.recHitsBegin(); hit!=t.recHitsEnd(); hit++){
01109     if ((**hit).isValid()   && (**hit).geographicalId().det() == DetId::Tracker ){
01110       bool barrel = DetId((**hit).geographicalId()).subdetId() == static_cast<int>(PixelSubdetector::PixelBarrel);
01111       //bool endcap = DetId::DetId((**hit).geographicalId()).subdetId() == static_cast<int>(PixelSubdetector::PixelEndcap);
01112       if (barrel){
01113         nbarrel++;
01114         const SiPixelRecHit *pixhit = dynamic_cast<const SiPixelRecHit*>( &(**hit));
01115         edm::Ref<edmNew::DetSetVector<SiPixelCluster>, SiPixelCluster> const& clust = (*pixhit).cluster();
01116         if (clust.isNonnull()) {
01117           cout << Form("%4d",clust->sizeY());
01118           if (clust->sizeY()-longesthit>0) longesthit=clust->sizeY();
01119         }
01120       }
01121     }
01122   }
01123   //cout << endl;
01124 }
01125 
01126 void PrimaryVertexAnalyzer4PU::printRecVtxs(const Handle<reco::VertexCollection> recVtxs, std::string title){
01127     int ivtx=0;
01128     std::cout << std::endl << title << std::endl;
01129     for(reco::VertexCollection::const_iterator v=recVtxs->begin(); 
01130         v!=recVtxs->end(); ++v){
01131       string vtype=" recvtx  ";
01132       if( v->isFake()){
01133         vtype=" fake   ";
01134       }else if (v->ndof()==-5){
01135         vtype=" cluster "; // pos=selector[iclu],cputime[iclu],clusterz[iclu]
01136       }else if(v->ndof()==-3){
01137         vtype=" event   ";
01138       }
01139       std::cout << "vtx "<< std::setw(3) << std::setfill(' ')<<ivtx++
01140                 << vtype
01141                 << " #trk " << std::fixed << std::setprecision(4) << std::setw(3) << v->tracksSize() 
01142                 << " chi2 " << std::fixed << std::setw(4) << std::setprecision(1) << v->chi2() 
01143                 << " ndof " << std::fixed << std::setw(5) << std::setprecision(2) << v->ndof()
01144                 << " x "  << std::setw(8) <<std::fixed << std::setprecision(4) << v->x() 
01145                 << " dx " << std::setw(8) << v->xError()// <<  std::endl 
01146                 << " y "  << std::setw(8) << v->y() 
01147                 << " dy " << std::setw(8) << v->yError()//<< std::endl
01148                 << " z "  << std::setw(8) << v->z() 
01149                 << " dz " << std::setw(8) << v->zError()
01150                 << std::endl;
01151     }
01152 }
01153 
01154 
01155 void PrimaryVertexAnalyzer4PU::printSimVtxs(const Handle<SimVertexContainer> simVtxs){
01156     int i=0;
01157     for(SimVertexContainer::const_iterator vsim=simVtxs->begin();
01158         vsim!=simVtxs->end(); ++vsim){
01159       if ( vsim->position().x()*vsim->position().x()+vsim->position().y()*vsim->position().y() < 1.){
01160         std::cout << i++ << ")" << std::scientific
01161                   << " evtid=" << vsim->eventId().event()  << ","  << vsim->eventId().bunchCrossing()
01162                   << " sim x=" << vsim->position().x()*simUnit_
01163                   << " sim y=" << vsim->position().y()*simUnit_
01164                   << " sim z=" << vsim->position().z()*simUnit_
01165                   << " sim t=" << vsim->position().t()
01166                   << " parent=" << vsim->parentIndex() 
01167                   << std::endl;
01168       }
01169     }
01170 }
01171 
01172 
01173 
01174 
01175 
01176 
01177 
01178 void PrimaryVertexAnalyzer4PU::printSimTrks(const Handle<SimTrackContainer> simTrks){
01179   std::cout <<  " simTrks   type, (momentum), vertIndex, genpartIndex"  << std::endl;
01180   int i=1;
01181   for(SimTrackContainer::const_iterator t=simTrks->begin();
01182       t!=simTrks->end(); ++t){
01183     //HepMC::GenParticle* gp=evtMC->GetEvent()->particle( (*t).genpartIndex() );
01184     std::cout << i++ << ")" 
01185               << t->eventId().event()  << ","  << t->eventId().bunchCrossing()
01186               << (*t)
01187               << " index="
01188               << (*t).genpartIndex();
01189     //if (gp) {
01190     //  HepMC::GenVertex *gv=gp->production_vertex();
01191     //  std::cout  <<  " genvertex =" << (*gv);
01192     //}
01193     std::cout << std::endl;
01194   }
01195 }
01196 
01197 
01198 
01199 void PrimaryVertexAnalyzer4PU::printRecTrks(const Handle<reco::TrackCollection> &recTrks  ){
01200 
01201   cout << "printRecTrks" << endl;
01202   int i =1;
01203   for(reco::TrackCollection::const_iterator t=recTrks->begin(); t!=recTrks->end(); ++t){
01204     //    reco::TrackBase::ParameterVector  par = t->parameters();
01205     
01206     cout << endl;
01207     cout << "Track "<<i << " " ; i++;
01208     //enum TrackQuality { undefQuality=-1, loose=0, tight=1, highPurity=2, confirmed=3, goodIterative=4, qualitySize=5};
01209     if( t->quality(reco::TrackBase::loose)){ cout << "loose ";};
01210     if( t->quality(reco::TrackBase::tight)){ cout << "tight ";};
01211     if( t->quality(reco::TrackBase::highPurity)){ cout << "highPurity ";};
01212     if( t->quality(reco::TrackBase::confirmed)){ cout << "confirmed  ";};
01213     if( t->quality(reco::TrackBase::goodIterative)){ cout << "goodIterative  ";};
01214     cout  << endl;
01215 
01216     TransientTrack  tk = theB_->build(&(*t)); tk.setBeamSpot(vertexBeamSpot_);   
01217     double ipsig=0;
01218     if (tk.stateAtBeamLine().isValid()){
01219       ipsig= tk.stateAtBeamLine().transverseImpactParameter().significance();
01220     }else{
01221       ipsig=-1;
01222     }
01223 
01224     cout << Form("pt=%8.3f phi=%6.3f eta=%6.3f z=%8.4f  dz=%6.4f, ipsig=%6.1f",t->pt(), t->phi(), t->eta(), t->vz(), t->dzError(),ipsig) << endl;
01225 
01226 
01227     cout << Form(" found=%6d  lost=%6d   chi2/ndof=%10.3f ",t->found(), t->lost(),t->normalizedChi2())<<endl;
01228     const reco::HitPattern & p= t->hitPattern();
01229     cout << "subdet layers valid lost" << endl;
01230     cout << Form(" barrel  %2d  %2d  %2d",p.pixelBarrelLayersWithMeasurement(),p.numberOfValidPixelBarrelHits(), p.numberOfLostPixelBarrelHits()) << endl;
01231     cout << Form(" fwd     %2d  %2d  %2d",p.pixelEndcapLayersWithMeasurement(),p.numberOfValidPixelEndcapHits(), p.numberOfLostPixelEndcapHits()) << endl;
01232     cout << Form(" pixel   %2d  %2d  %2d",p.pixelLayersWithMeasurement(), p.numberOfValidPixelHits(), p.numberOfLostPixelHits()) << endl;
01233     cout << Form(" tracker %2d  %2d  %2d",p.trackerLayersWithMeasurement(), p.numberOfValidTrackerHits(), p.numberOfLostTrackerHits()) << endl;
01234     cout << endl;
01235     const reco::HitPattern & pinner= t->trackerExpectedHitsInner();
01236     const reco::HitPattern & pouter= t->trackerExpectedHitsOuter();
01237     int ninner=pinner.numberOfHits();
01238     int nouter=pouter.numberOfHits();
01239 
01240     //    double d0Error=t.d0Error();
01241     //    double d0=t.dxy(myBeamSpot);
01242     
01243     //
01244     for(trackingRecHit_iterator hit=t->recHitsBegin(); hit!=t->recHitsEnd(); hit++){
01245       if ((**hit).isValid()   && (**hit).geographicalId().det() == DetId::Tracker ){
01246        bool barrel = DetId((**hit).geographicalId()).subdetId() == static_cast<int>(PixelSubdetector::PixelBarrel);
01247        bool endcap = DetId((**hit).geographicalId()).subdetId() == static_cast<int>(PixelSubdetector::PixelEndcap);
01248        if (barrel){
01249          const SiPixelRecHit *pixhit = dynamic_cast<const SiPixelRecHit*>( &(**hit));
01250          edm::Ref<edmNew::DetSetVector<SiPixelCluster>, SiPixelCluster> const& clust = (*pixhit).cluster();
01251          if (clust.isNonnull()) {
01252            cout << Form(" barrel cluster size=%2d   charge=%6.1f wx=%2d  wy=%2d, expected=%3.1f",clust->size(),clust->charge(),clust->sizeX(),clust->sizeY(),1.+2./fabs(tan(t->theta()))) << endl;
01253          }
01254        }else if(endcap){
01255          const SiPixelRecHit *pixhit = dynamic_cast<const SiPixelRecHit*>( &(**hit));
01256          edm::Ref<edmNew::DetSetVector<SiPixelCluster>, SiPixelCluster> const& clust = (*pixhit).cluster();
01257          if (clust.isNonnull()) {
01258            cout << Form(" endcap cluster size=%2d   charge=%6.1f wx=%2d  wy=%2d",clust->size(),clust->charge(),clust->sizeX(),clust->sizeY()) << endl;
01259          }
01260        }
01261       }
01262     }
01263     cout << "hitpattern" << endl;
01264     for(int i=0; i<p.numberOfHits(); i++){      p.printHitPattern(i,std::cout);    }
01265     cout << "expected inner " << ninner << endl;
01266     for(int i=0; i<pinner.numberOfHits(); i++){      pinner.printHitPattern(i,std::cout);    }
01267     cout << "expected outer " << nouter << endl;
01268     for(int i=0; i<pouter.numberOfHits(); i++){      pouter.printHitPattern(i,std::cout);    }
01269   }
01270 }
01271 
01272 namespace {
01273 
01274   bool recTrackLessZ(const reco::TransientTrack & tk1,
01275                      const reco::TransientTrack & tk2)
01276   {
01277     return tk1.stateAtBeamLine().trackStateAtPCA().position().z() < tk2.stateAtBeamLine().trackStateAtPCA().position().z();
01278   }
01279 
01280 }
01281 
01282 
01283 
01284 
01285 void PrimaryVertexAnalyzer4PU::printPVTrks(const Handle<reco::TrackCollection> &recTrks, 
01286                                            const Handle<reco::VertexCollection> &recVtxs,  
01287                                            std::vector<SimPart>& tsim,
01288                                            std::vector<SimEvent>& simEvt,
01289                                            bool selectedOnly){
01290   // make a printout of the tracks selected for PV reconstructions, show matching MC tracks, too
01291 
01292   vector<TransientTrack>  selTrks;
01293   for(reco::TrackCollection::const_iterator t=recTrks->begin();
01294       t!=recTrks->end(); ++t){
01295     TransientTrack  tt = theB_->build(&(*t));  tt.setBeamSpot(vertexBeamSpot_);
01296     if( (!selectedOnly) || (selectedOnly && theTrackFilter(tt))){     selTrks.push_back(tt);    }
01297   }
01298   if (selTrks.size()==0) return;
01299   stable_sort(selTrks.begin(), selTrks.end(), recTrackLessZ);
01300 
01301   // select tracks like for PV reconstruction and match them to sim tracks
01302   reco::TrackCollection selRecTrks;
01303 
01304   for(unsigned int i=0; i<selTrks.size(); i++){ selRecTrks.push_back(selTrks[i].track());} 
01305   int* rectosim=supf(tsim, selRecTrks);
01306 
01307 
01308 
01309   // now dump in a format similar to the clusterizer
01310   cout << "printPVTrks" << endl;
01311   cout << "----          z +/- dz     1bet-m     ip +/-dip         pt   phi   eta";
01312   if((tsim.size()>0)||(simEvt.size()>0)) {cout << " type     pdg    zvtx    zdca      dca    zvtx   zdca    dsz";}
01313   cout << endl;
01314 
01315   cout.precision(4);
01316   int isel=0;
01317   for(unsigned int i=0; i<selTrks.size(); i++){
01318     if  (selectedOnly || (theTrackFilter(selTrks[i]))) {
01319           cout <<  setw (3)<< isel;
01320           isel++;
01321     }else{
01322       cout <<  "   ";
01323     }
01324 
01325 
01326     // is this track in the tracklist of a recvtx ?
01327     int vmatch=-1;
01328     int iv=0;
01329     for(reco::VertexCollection::const_iterator v=recVtxs->begin(); 
01330         v!=recVtxs->end(); ++v){
01331       if ( (v->ndof()<-1) || (v->chi2()<=0) ) continue;  // skip clusters 
01332       for(trackit_t tv=v->tracks_begin(); tv!=v->tracks_end(); tv++){
01333         const reco::Track & RTv=*(tv->get());  
01334         if(selTrks[i].track().vz()==RTv.vz()) {vmatch=iv;}
01335       }
01336       iv++;
01337     }
01338 
01339     double tz=(selTrks[i].stateAtBeamLine().trackStateAtPCA()).position().z();
01340     double tantheta=tan((selTrks[i].stateAtBeamLine().trackStateAtPCA()).momentum().theta());
01341     double tdz0= selTrks[i].track().dzError();
01342     double tdz2= pow(selTrks[i].track().dzError(),2)+ (pow(vertexBeamSpot_.BeamWidthX(),2)+pow(vertexBeamSpot_.BeamWidthY(),2))/pow(tantheta,2);
01343     
01344     if(vmatch>-1){
01345       cout << "["<<setw(2)<<vmatch<<"]";
01346     }else{
01347       //int status=theTrackFilter.status(selTrks[i]);
01348       int status=0;
01349       if(status==0){
01350         cout <<"    ";
01351       }else{
01352         if(status&0x1){cout << "i";}else{cout << ".";};
01353         if(status&0x2){cout << "c";}else{cout << ".";};
01354         if(status&0x4){cout << "h";}else{cout << ".";};
01355         if(status&0x8){cout << "q";}else{cout << ".";};
01356       }
01357     }
01358     cout  <<  setw (8) << fixed << setprecision(4)<<  tz << " +/-" <<  setw (6)<< sqrt(tdz2);
01359     
01360 
01361     // track quality and hit information, see DataFormats/TrackReco/interface/HitPattern.h
01362     if(selTrks[i].track().quality(reco::TrackBase::highPurity)){ cout << " *";}else{cout <<"  ";}
01363     if(selTrks[i].track().hitPattern().hasValidHitInFirstPixelBarrel()){cout <<"+";}else{cout << "-";}
01364     cout << setw(1) << selTrks[i].track().hitPattern().pixelBarrelLayersWithMeasurement();
01365     cout << setw(1) << selTrks[i].track().hitPattern().pixelEndcapLayersWithMeasurement(); 
01366     cout << setw(1) << hex << selTrks[i].track().hitPattern().trackerLayersWithMeasurement()-selTrks[i].track().hitPattern().pixelLayersWithMeasurement()<<dec;
01367     cout << "-" << setw(1)<<hex <<selTrks[i].track().trackerExpectedHitsOuter().numberOfHits() << dec;
01368 
01369     
01370     Measurement1D IP=selTrks[i].stateAtBeamLine().transverseImpactParameter();
01371     cout << setw (8) << IP.value() << "+/-" << setw (6) << IP.error();
01372     if(selTrks[i].track().ptError()<1){
01373       cout << " " << setw(8) << setprecision(2)  << selTrks[i].track().pt()*selTrks[i].track().charge();
01374     }else{
01375       cout << " " << setw(7) << setprecision(1)  << selTrks[i].track().pt()*selTrks[i].track().charge() << "*";
01376       //cout << "+/-" << setw(6)<< setprecision(2) << selTrks[i].track().ptError();
01377     }
01378     cout << " " << setw(5) << setprecision(2) << selTrks[i].track().phi()
01379          << " " << setw(5) << setprecision(2) << selTrks[i].track().eta() ;
01380 
01381 
01382 
01383     // print MC info, if available
01384     if(simEvt.size()>0){
01385       reco::Track t=selTrks[i].track();
01386       try{
01387         TrackingParticleRef tpr = z2tp_[t.vz()];
01388         const TrackingVertex *parentVertex= tpr->parentVertex().get();
01389         //double vx=parentVertex->position().x(); // problems with tpr->vz()
01390         //double vy=parentVertex->position().y(); work in progress
01391         double vz=parentVertex->position().z();
01392         cout << " " << tpr->eventId().event();
01393         cout << " " << setw(5) << tpr->pdgId();
01394         cout << " " << setw(8) << setprecision(4) << vz;
01395       }catch (...){
01396         cout << " not matched";
01397       }
01398     }else{
01399       //    cout << "  " << rectosim[i];
01400       if(rectosim[i]>0){
01401         if(tsim[rectosim[i]].type==0){  cout << " prim " ;}else{cout << " sec  ";}
01402         cout << " " << setw(5) << tsim[rectosim[i]].pdg;
01403         cout << " " << setw(8) << setprecision(4) << tsim[rectosim[i]].zvtx;
01404         cout << " " << setw(8) << setprecision(4) << tsim[rectosim[i]].zdcap;
01405         cout << " " << setw(8) << setprecision(4) << tsim[rectosim[i]].ddcap;
01406         double zvtxpull=(tz-tsim[rectosim[i]].zvtx)/sqrt(tdz2);
01407         cout << setw(6) << setprecision(1) << zvtxpull;
01408         double zdcapull=(tz-tsim[rectosim[i]].zdcap)/tdz0;
01409         cout << setw(6) << setprecision(1) << zdcapull;
01410         double dszpull=(selTrks[i].track().dsz()-tsim[rectosim[i]].par[4])/selTrks[i].track().dszError();
01411         cout << setw(6) << setprecision(1) << dszpull;
01412       }
01413     }
01414     cout << endl;
01415   }
01416   delete rectosim;
01417 }
01418 
01419 
01420 void PrimaryVertexAnalyzer4PU::matchRecTracksToVertex(simPrimaryVertex & pv, 
01421                                                    const std::vector<SimPart > & tsim,
01422                                                    const edm::Handle<reco::TrackCollection> & recTrks)
01423 {
01424   // find all recTracks that belong to this simulated vertex (not just the ones that are used in
01425   // matching recVertex)
01426 
01427   std::cout << "dump rec tracks: " << std::endl;
01428   int irec=0;
01429   for(reco::TrackCollection::const_iterator t=recTrks->begin();
01430       t!=recTrks->end(); ++t){
01431     reco::TrackBase::ParameterVector  p = t->parameters();
01432     std::cout  << irec++ << ") " << p <<  std::endl;
01433   }
01434 
01435   std::cout << "match sim tracks: " << std::endl;
01436   pv.matchedRecTrackIndex.clear();
01437   pv.nMatchedTracks=0;
01438   int isim=0;
01439   for(std::vector<SimPart>::const_iterator s=tsim.begin();
01440       s!=tsim.end(); ++s){
01441     std::cout  << isim++ << " " << s->par;// << std::endl;
01442     int imatch=-1;
01443     int irec=0;
01444     for(reco::TrackCollection::const_iterator t=recTrks->begin();
01445         t!=recTrks->end(); ++t){
01446       reco::TrackBase::ParameterVector  p = t->parameters();
01447       if (match(s->par,p)){     imatch=irec; }
01448       irec++;
01449     }
01450     pv.matchedRecTrackIndex.push_back(imatch);
01451     if(imatch>-1){ 
01452       pv.nMatchedTracks++; 
01453       std::cout << " matched to rec trk" << imatch << std::endl;
01454     }else{
01455       std::cout << " not matched" << std::endl;
01456     }
01457   }
01458 }
01459 /********************************************************************************************************/
01460 
01461 
01462 
01463 
01464 
01465 
01466 /********************************************************************************************************/
01467 
01468 void PrimaryVertexAnalyzer4PU::getTc(const std::vector<reco::TransientTrack>& tracks, 
01469                                double & Tc, double & chsq, double & dzmax, double & dztrim, double & m4m2){
01470   if (tracks.size()<2){ Tc=-1; chsq=-1; dzmax=-1; dztrim=-1; m4m2=-1; return;}
01471 
01472   double sumw=0, sumwz=0, sumww=0,sumwwz=0,sumwwzz=0;
01473   double zmin=1e10, zmin1=1e10, zmax1=-1e10, zmax=-1e10;
01474   double m4=0,m3=0,m2=0,m1=0,m0=0;
01475   for(vector<reco::TransientTrack>::const_iterator it=tracks.begin(); it!=tracks.end(); it++){
01476      double tantheta=tan(((*it).stateAtBeamLine().trackStateAtPCA()).momentum().theta());
01477      reco::BeamSpot beamspot=(it->stateAtBeamLine()).beamSpot();
01478      double z=((*it).stateAtBeamLine().trackStateAtPCA()).position().z();
01479      double dz2= pow((*it).track().dzError(),2)+pow(beamspot.BeamWidthX()/tantheta,2);
01480    //    t.dz2= pow((*it).track().dzError(),2) + pow(wxy0/tantheta,2) +  1./(1.+exp(pow(t.ip/t.dip,2)-pow(2.)))*pow(ip/tantheta,2);
01481      double w=1./dz2;  // take p=1
01482      sumw    += w;
01483      sumwz   += w*z;
01484      sumwwz  += w*w*z;;
01485      sumwwzz += w*w*z*z;
01486      sumww   += w*w;
01487      m0      += w;
01488      m1      += w*z;
01489      m2      += w*z*z;
01490      m3      += w*z*z*z;
01491      m4      += w*z*z*z*z;
01492      if(dz2<pow(0.1,2)){
01493        if(z<zmin1){zmin1=z;}    if(z<zmin){zmin1=zmin; zmin=z;}
01494        if(z>zmax1){zmax1=z;}    if(z>zmax){zmax1=zmax; zmax=z;}
01495      }
01496   }
01497   double z=sumwz/sumw;
01498   double a=sumwwzz-2*z*sumwwz+z*z*sumww;
01499   double b=sumw;
01500   if(tracks.size()>1){
01501     chsq=(m2-m0*z*z)/(tracks.size()-1);
01502     Tc=2.*a/b;
01503     m4m2=sqrt((m4-4*m3*z+6*m2*z*z-3*m1*z*z*z+m0*z*z*z*z)/(m2-2*m1*z+z*z*m0));
01504   }else{
01505     chsq=0;
01506     Tc=0;
01507     m4m2=0;
01508   }
01509   dzmax=zmax-zmin;
01510   dztrim=zmax1-zmin1;// truncated
01511 }
01512 /********************************************************************************************************/
01513 
01514 
01515 
01516 
01517 
01518 /********************************************************************************************************/
01519 bool PrimaryVertexAnalyzer4PU::truthMatchedTrack( edm::RefToBase<reco::Track> track, TrackingParticleRef & tpr)
01520 
01521 /********************************************************************************************************/
01522 // for a reco track select the matching tracking particle, always use this function to make sure we
01523 // are consistent
01524 // to get the TrackingParticle form the TrackingParticleRef, use ->get();
01525 {
01526   double f=0;
01527   try{
01528     std::vector<std::pair<TrackingParticleRef, double> > tp = r2s_[track];
01529     for (std::vector<std::pair<TrackingParticleRef, double> >::const_iterator it = tp.begin(); 
01530          it != tp.end(); ++it) {
01531       
01532       if (it->second>f){
01533         tpr=it->first;
01534         f=it->second;
01535       }
01536     }
01537   } catch (Exception event) {
01538     // silly way of testing whether track is in r2s_
01539   }
01540   
01541   // sanity check on track parameters?
01542   
01543   return (f>0.5);
01544 }
01545 /********************************************************************************************************/
01546 
01547 
01548 
01549 
01550 
01551 
01552 /********************************************************************************************************/
01553 std::vector< edm::RefToBase<reco::Track> >  PrimaryVertexAnalyzer4PU::getTruthMatchedVertexTracks(
01554                                        const reco::Vertex& v
01555                                        )
01556 // for vertex v get a list of tracks for which truth matching is available 
01557 /********************************************************************************************************/
01558 {
01559   std::vector<  edm::RefToBase<reco::Track> > b;
01560   TrackingParticleRef tpr;
01561 
01562   for(trackit_t tv=v.tracks_begin(); tv!=v.tracks_end(); tv++){
01563     edm::RefToBase<reco::Track> track=*tv;
01564     if (truthMatchedTrack(track, tpr)){
01565       b.push_back(*tv);
01566     }
01567   }
01568 
01569 
01570   return b;
01571 }
01572 /********************************************************************************************************/
01573 
01574 
01575 
01576 
01577 
01578 /********************************************************************************************************/
01579 std::vector<PrimaryVertexAnalyzer4PU::SimEvent> PrimaryVertexAnalyzer4PU::getSimEvents
01580 (
01581  // const Event& iEvent, const EventSetup& iSetup,
01582  edm::Handle<TrackingParticleCollection>  TPCollectionH,
01583  edm::Handle<TrackingVertexCollection>  TVCollectionH,
01584  edm::Handle<View<Track> > trackCollectionH
01585  ){
01586 
01587   const TrackingParticleCollection* simTracks = TPCollectionH.product();
01588   const View<Track>  tC = *(trackCollectionH.product());
01589 
01590 
01591   vector<SimEvent> simEvt;
01592   map<EncodedEventId, unsigned int> eventIdToEventMap;
01593   map<EncodedEventId, unsigned int>::iterator id;
01594   bool dumpTP=false;
01595   for(TrackingParticleCollection::const_iterator it=simTracks->begin(); it!=simTracks->end(); it++){
01596     
01597     if( fabs(it->parentVertex().get()->position().z())>100.) continue; // skip funny entries @ -13900
01598 
01599     unsigned int event=0;  //note, this is no longer the same as eventId().event()
01600     id=eventIdToEventMap.find(it->eventId());
01601     if (id==eventIdToEventMap.end()){
01602 
01603       // new event here
01604       SimEvent e;
01605       e.eventId=it->eventId();
01606       event=simEvt.size();
01607       const TrackingVertex *parentVertex= it->parentVertex().get();
01608       if(DEBUG_){
01609         cout << "getSimEvents: ";
01610         cout << it->eventId().bunchCrossing() << "," <<  it->eventId().event() 
01611              << " z="<< it->vz() << " " 
01612              << parentVertex->eventId().bunchCrossing() << ","  <<parentVertex->eventId().event() 
01613              << " z=" << parentVertex->position().z() << endl;
01614       }
01615       if (it->eventId()==parentVertex->eventId()){
01616         //e.x=it->vx(); e.y=it->vy(); e.z=it->vz();// wrong ???
01617         e.x=parentVertex->position().x();
01618         e.y=parentVertex->position().y();
01619         e.z=parentVertex->position().z();
01620         if(e.z<-100){
01621           dumpTP=true;
01622         }
01623       }else{
01624         e.x=0; e.y=0; e.z=-88.;
01625       }
01626       simEvt.push_back(e);
01627       eventIdToEventMap[e.eventId]=event;
01628     }else{
01629       event=id->second;
01630     }
01631       
01632 
01633     simEvt[event].tp.push_back(&(*it));
01634     if( (abs(it->eta())<2.5) && (it->charge()!=0) ){
01635       simEvt[event].sumpt2+=pow(it->pt(),2); // should keep track of decays ?
01636       simEvt[event].sumpt+=it->pt(); 
01637     }
01638   }
01639 
01640   if(dumpTP){
01641     for(TrackingParticleCollection::const_iterator it=simTracks->begin(); it!=simTracks->end(); it++){
01642       std::cout << *it << std::endl;
01643     } 
01644   }
01645 
01646 
01647   for(View<Track>::size_type i=0; i<tC.size(); ++i) {
01648     RefToBase<Track> track(trackCollectionH, i);
01649     TrackingParticleRef tpr;
01650     if( truthMatchedTrack(track,tpr)){
01651 
01652       if( eventIdToEventMap.find(tpr->eventId())==eventIdToEventMap.end() ){ cout << "Bug in getSimEvents" << endl; break; }
01653 
01654       z2tp_[track.get()->vz()]=tpr;
01655 
01656       unsigned int event=eventIdToEventMap[tpr->eventId()];
01657       double ipsig=0,ipdist=0;
01658       const TrackingVertex *parentVertex= tpr->parentVertex().get();
01659       double vx=parentVertex->position().x(); // problems with tpr->vz()
01660       double vy=parentVertex->position().y();
01661       double vz=parentVertex->position().z();
01662       double d=sqrt(pow(simEvt[event].x-vx,2)+pow(simEvt[event].y-vy,2)+pow(simEvt[event].z-vz,2))*1.e4;
01663       ipdist=d;
01664       double dxy=track->dxy(vertexBeamSpot_.position());
01665       ipsig=dxy/track->dxyError();
01666 
01667 
01668       TransientTrack  t = theB_->build(tC[i]); 
01669       t.setBeamSpot(vertexBeamSpot_);   
01670       if (theTrackFilter(t)){
01671         simEvt[event].tk.push_back(t);
01672         if(ipdist<5){simEvt[event].tkprim.push_back(t);}
01673         if(ipsig<5){simEvt[event].tkprimsel.push_back(t);}
01674       }
01675       
01676     }
01677   }
01678 
01679 
01680   
01681   AdaptiveVertexFitter theFitter;
01682   cout << "SimEvents " << simEvt.size()  <<  endl;
01683   for(unsigned int i=0; i<simEvt.size(); i++){
01684 
01685     if(simEvt[i].tkprim.size()>0){
01686 
01687       getTc(simEvt[i].tkprimsel, simEvt[i].Tc, simEvt[i].chisq, simEvt[i].dzmax, simEvt[i].dztrim, simEvt[i].m4m2);
01688       TransientVertex v = theFitter.vertex(simEvt[i].tkprim, vertexBeamSpot_);
01689       if (v.isValid()){
01690         simEvt[i].xfit=v.position().x();
01691         simEvt[i].yfit=v.position().y();
01692         simEvt[i].zfit=v.position().z();
01693         //      if (simEvt[i].z<-80.){simEvt[i].z=v.position().z();} // for now
01694       }
01695     }
01696 
01697 
01698     if(DEBUG_){
01699       cout << i <<"  )   nTP="  << simEvt[i].tp.size()
01700            << "   z=" <<  simEvt[i].z
01701            << "    recTrks="  << simEvt[i].tk.size() 
01702            << "    recTrksPrim="  << simEvt[i].tkprim.size() 
01703            << "   zfit=" << simEvt[i].zfit
01704            << endl;
01705     }
01706   }
01707  
01708   return simEvt;
01709 }
01710 
01711 
01712 std::vector<PrimaryVertexAnalyzer4PU::simPrimaryVertex> PrimaryVertexAnalyzer4PU::getSimPVs(
01713                                       const Handle<HepMCProduct> evtMC)
01714 {
01715   if(DEBUG_){std::cout << "getSimPVs HepMC " << std::endl;}
01716 
01717   std::vector<PrimaryVertexAnalyzer4PU::simPrimaryVertex> simpv;
01718   const HepMC::GenEvent* evt=evtMC->GetEvent();
01719   if (evt) {
01720 //     std::cout << "process id " <<evt->signal_process_id()<<std::endl;
01721 //     std::cout <<"signal process vertex "<< ( evt->signal_process_vertex() ?
01722 //                                           evt->signal_process_vertex()->barcode() : 0 )   <<std::endl;
01723 //     std::cout <<"number of vertices " << evt->vertices_size() << std::endl;
01724 
01725 
01726     //int idx=0;
01727     for(HepMC::GenEvent::vertex_const_iterator vitr= evt->vertices_begin();
01728         vitr != evt->vertices_end(); ++vitr ) 
01729       { // loop for vertex ...
01730 
01731         HepMC::FourVector pos = (*vitr)->position();
01732         //      if (pos.t()>0) { continue;} // skip secondary vertices, doesn't work for some samples
01733 
01734         if (fabs(pos.z())>1000) continue;  // skip funny junk vertices
01735 
01736         bool hasMotherVertex=false;
01737         //std::cout << "mothers" << std::endl;
01738         for ( HepMC::GenVertex::particle_iterator
01739               mother  = (*vitr)->particles_begin(HepMC::parents);
01740               mother != (*vitr)->particles_end(HepMC::parents);
01741               ++mother ) {
01742           HepMC::GenVertex * mv=(*mother)->production_vertex();
01743           if (mv) {hasMotherVertex=true;}
01744           //std::cout << "\t"; (*mother)->print();
01745         }
01746         if(hasMotherVertex) {continue;}
01747 
01748 
01749         // could be a new vertex, check  all primaries found so far to avoid multiple entries
01750         const double mm=0.1;  
01751         simPrimaryVertex sv(pos.x()*mm,pos.y()*mm,pos.z()*mm);
01752         simPrimaryVertex *vp=NULL;  // will become non-NULL if a vertex is found and then point to it
01753         for(std::vector<simPrimaryVertex>::iterator v0=simpv.begin();
01754             v0!=simpv.end(); v0++){
01755           if( (fabs(sv.x-v0->x)<1e-5) && (fabs(sv.y-v0->y)<1e-5) && (fabs(sv.z-v0->z)<1e-5)){
01756             vp=&(*v0);
01757             break;
01758           }
01759         }
01760         if(!vp){
01761           // this is a new vertex
01762           //std::cout << "this is a new vertex" << sv.x << " " << sv.y << " " << sv.z <<std::endl;
01763           simpv.push_back(sv);
01764           vp=&simpv.back();
01765 //      }else{
01766 //        std::cout << "this is not a new vertex" << std::endl;
01767         }
01768 
01769         
01770         // store the gen vertex barcode with this simpv
01771         vp->genVertex.push_back((*vitr)->barcode());
01772 
01773 
01774         // collect final state descendants and sum up momenta etc
01775         for ( HepMC::GenVertex::particle_iterator
01776               daughter  = (*vitr)->particles_begin(HepMC::descendants);
01777               daughter != (*vitr)->particles_end(HepMC::descendants);
01778               ++daughter ) {
01779           //std::cout << "checking daughter  type " << (*daughter)->pdg_id() << " final :" <<isFinalstateParticle(*daughter) << std::endl;
01780           if (isFinalstateParticle(*daughter)){ 
01781             if ( find(vp->finalstateParticles.begin(), vp->finalstateParticles.end(),(*daughter)->barcode())
01782                  == vp->finalstateParticles.end()){
01783               vp->finalstateParticles.push_back((*daughter)->barcode());
01784               HepMC::FourVector m=(*daughter)->momentum();
01785               //std::cout << "adding particle to primary " << m.px()<< " "  << m.py() << " "  << m.pz() << std::endl; 
01786               vp->ptot.setPx(vp->ptot.px()+m.px());
01787               vp->ptot.setPy(vp->ptot.py()+m.py());
01788               vp->ptot.setPz(vp->ptot.pz()+m.pz());
01789               vp->ptot.setE(vp->ptot.e()+m.e());
01790               vp->ptsq+=(m.perp())*(m.perp());
01791               // count relevant particles
01792               if ( (m.perp()>0.2) && (fabs(m.pseudoRapidity())<2.5) && isCharged( *daughter ) ){
01793                 vp->nGenTrk++;
01794               }
01795               
01796               hsimPV["rapidity"]->Fill(m.pseudoRapidity());
01797               if( (m.perp()>0.8) &&  isCharged( *daughter ) ){
01798                 hsimPV["chRapidity"]->Fill(m.pseudoRapidity());
01799               }
01800               hsimPV["pt"]->Fill(m.perp());
01801             }//new final state particle for this vertex
01802           }//daughter is a final state particle
01803         }
01804 
01805 
01806         //idx++;
01807       }
01808   }
01809   if(verbose_){
01810     cout << "------- PrimaryVertexAnalyzer4PU simPVs -------" <<  endl;
01811     for(std::vector<simPrimaryVertex>::iterator v0=simpv.begin();
01812         v0!=simpv.end(); v0++){
01813       cout << "z=" << v0->z 
01814            << "  px=" << v0->ptot.px()
01815            << "  py=" << v0->ptot.py()
01816            << "  pz=" << v0->ptot.pz() 
01817            << "  pt2="<< v0->ptsq 
01818            << endl;
01819     }
01820     cout << "-----------------------------------------------" << endl;
01821   }
01822   return simpv;
01823 }
01824 
01825 
01826 
01827 
01828 
01829 
01830 
01831 
01832 /* get sim pv from TrackingParticles/TrackingVertex */
01833 std::vector<PrimaryVertexAnalyzer4PU::simPrimaryVertex> PrimaryVertexAnalyzer4PU::getSimPVs(
01834                                                                                           const edm::Handle<TrackingVertexCollection> tVC
01835                                                                                           )
01836 {
01837   std::vector<PrimaryVertexAnalyzer4PU::simPrimaryVertex> simpv;
01838   //std::cout <<"number of vertices " << tVC->size() << std::endl;
01839 
01840   if(DEBUG_){std::cout << "getSimPVs TrackingVertexCollection " << std::endl;}
01841 
01842   for (TrackingVertexCollection::const_iterator v = tVC -> begin(); v != tVC -> end(); ++v) {
01843 
01844     if(DEBUG_){
01845       std::cout << (v->eventId()).event() << v -> position() << v->g4Vertices().size() <<" "  <<v->genVertices().size() <<  "   t=" <<v->position().t()*1.e12 <<"    ==0:" <<(v->position().t()>0) << std::endl;
01846       for( TrackingVertex::g4v_iterator gv=v->g4Vertices_begin(); gv!=v->g4Vertices_end(); gv++){
01847         std::cout << *gv << std::endl;
01848       }
01849       std::cout << "----------" << std::endl;
01850     }
01851  
01852     //    bool hasMotherVertex=false;
01853     if ((unsigned int) v->eventId().event()<simpv.size()) continue;
01854         //if (v->position().t()>0) { continue;} // skip secondary vertices (obsolete + doesn't work)
01855     if (fabs(v->position().z())>1000) continue;  // skip funny junk vertices
01856     
01857     // could be a new vertex, check  all primaries found so far to avoid multiple entries
01858     const double mm=1.0; // for tracking vertices
01859     simPrimaryVertex sv(v->position().x()*mm,v->position().y()*mm,v->position().z()*mm);
01860 
01861     //cout << "sv: " << (v->eventId()).event() << endl;
01862     sv.eventId=v->eventId();
01863 
01864     for (TrackingParticleRefVector::iterator iTrack = v->daughterTracks_begin(); iTrack != v->daughterTracks_end(); ++iTrack){
01865       //cout <<((**iTrack).eventId()).event() << " ";  // an iterator of Refs, dereference twice. Cool eyh?
01866       sv.eventId=(**iTrack).eventId();
01867     }
01868     //cout <<endl;
01869     simPrimaryVertex *vp=NULL;  // will become non-NULL if a vertex is found and then point to it
01870     for(std::vector<simPrimaryVertex>::iterator v0=simpv.begin();
01871         v0!=simpv.end(); v0++){
01872       if( (sv.eventId==v0->eventId) && (fabs(sv.x-v0->x)<1e-5) && (fabs(sv.y-v0->y)<1e-5) && (fabs(sv.z-v0->z)<1e-5)){
01873         vp=&(*v0);
01874         break;
01875       }
01876     }
01877     if(!vp){
01878       // this is a new vertex
01879       if(DEBUG_){std::cout << "this is a new vertex " << sv.eventId.event() << "   "  << sv.x << " " << sv.y << " " << sv.z <<std::endl;}
01880       simpv.push_back(sv);
01881       vp=&simpv.back();
01882     }else{
01883       if(DEBUG_){std::cout << "this is not a new vertex"  << sv.x << " " << sv.y << " " << sv.z <<std::endl;}
01884     }
01885 
01886 
01887     // Loop over daughter track(s)
01888     if(DEBUG_){
01889       for (TrackingVertex::tp_iterator iTP = v -> daughterTracks_begin(); iTP != v -> daughterTracks_end(); ++iTP) {
01890         std::cout << "  Daughter momentum:      " << (*(*iTP)).momentum();
01891         std::cout << "  Daughter type     " << (*(*iTP)).pdgId();
01892         std::cout << std::endl;
01893       }
01894     }
01895   }
01896   if(DEBUG_){  
01897     cout << "------- PrimaryVertexAnalyzer4PU simPVs from TrackingVertices -------" <<  endl; 
01898     for(std::vector<simPrimaryVertex>::iterator v0=simpv.begin();
01899         v0!=simpv.end(); v0++){
01900       cout << "z=" << v0->z << "  event=" << v0->eventId.event() << endl;
01901     }
01902     cout << "-----------------------------------------------" << endl;
01903   }
01904   return simpv;
01905 }
01906 
01907 
01908 
01909 
01910 
01911 
01912 // ------------ method called to produce the data  ------------
01913 void
01914 PrimaryVertexAnalyzer4PU::analyze(const Event& iEvent, const EventSetup& iSetup)
01915 {
01916   
01917   std::vector<simPrimaryVertex> simpv;  //  a list of primary MC vertices
01918   std::vector<SimPart> tsim;
01919   std::string mcproduct="generator";  // starting with 3_1_0 pre something
01920 
01921   eventcounter_++;
01922   run_             = iEvent.id().run();
01923   luminosityBlock_ = iEvent.luminosityBlock();
01924   event_           = iEvent.id().event();
01925   bunchCrossing_   = iEvent.bunchCrossing();
01926   orbitNumber_     = iEvent.orbitNumber();
01927 
01928   dumpThisEvent_ = false;
01929 
01930 
01931 
01932   if(verbose_){
01933     std::cout << endl 
01934               << "PrimaryVertexAnalyzer4PU::analyze   event counter=" << eventcounter_
01935               << " Run=" << run_ << "  LumiBlock " << luminosityBlock_ << "  event  " << event_
01936               << " bx=" << bunchCrossing_ <<  " orbit=" << orbitNumber_ 
01937       //<< " selected = " << good
01938               << std::endl;
01939   }
01940 
01941 
01942    try{
01943     iSetup.getData(pdt_);
01944   }catch(const Exception&){
01945     std::cout << "Some problem occurred with the particle data table. This may not work !" <<std::endl;
01946   }
01947 
01948   Handle<reco::VertexCollection> recVtxs;
01949   bool bnoBS=iEvent.getByLabel("offlinePrimaryVertices", recVtxs);
01950   
01951   Handle<reco::VertexCollection> recVtxsBS;
01952   bool bBS=iEvent.getByLabel("offlinePrimaryVerticesWithBS", recVtxsBS);
01953   
01954   Handle<reco::VertexCollection> recVtxsDA;
01955   bool bDA=iEvent.getByLabel("offlinePrimaryVerticesDA", recVtxsDA);
01956 
01957 //   Handle<reco::VertexCollection> recVtxsPIX;
01958 //   bool bPIX=iEvent.getByLabel("pixelVertices", recVtxsPIX);
01959 //   bPIX=false;
01960 
01961 //   Handle<reco::VertexCollection> recVtxsMVF;
01962 //   bool bMVF=iEvent.getByLabel("offlinePrimaryVerticesMVF", recVtxsMVF);
01963 
01964   Handle<reco::TrackCollection> recTrks;
01965   iEvent.getByLabel(recoTrackProducer_, recTrks);
01966 
01967 
01968   int nhighpurity=0, ntot=0;
01969   for(reco::TrackCollection::const_iterator t=recTrks->begin(); t!=recTrks->end(); ++t){  
01970     ntot++;
01971     if(t->quality(reco::TrackBase::highPurity)) nhighpurity++;
01972   } 
01973   if(ntot>10)  hnoBS["highpurityTrackFraction"]->Fill(float(nhighpurity)/float(ntot));
01974   if((recoTrackProducer_=="generalTracks")&&(nhighpurity<0.25*ntot)){
01975     if(verbose_){ cout << "rejected, " << nhighpurity << " highpurity  out of  " << ntot << "  total tracks "<< endl<< endl;}
01976     return;
01977   }
01978 
01979 
01980 
01981   
01982 
01983   if(iEvent.getByLabel(beamSpot_, recoBeamSpotHandle_)){
01984     vertexBeamSpot_= *recoBeamSpotHandle_;
01985     wxy2_=pow(vertexBeamSpot_.BeamWidthX(),2)+pow(vertexBeamSpot_.BeamWidthY(),2);
01986     Fill(hsimPV, "xbeam",vertexBeamSpot_.x0()); Fill(hsimPV, "wxbeam",vertexBeamSpot_.BeamWidthX());
01987     Fill(hsimPV, "ybeam",vertexBeamSpot_.y0()); Fill(hsimPV, "wybeam",vertexBeamSpot_.BeamWidthY());
01988     Fill(hsimPV, "zbeam",vertexBeamSpot_.z0());// Fill("wzbeam",vertexBeamSpot_.BeamWidthZ());
01989   }else{
01990     cout << " beamspot not found, using dummy " << endl;
01991     vertexBeamSpot_=reco::BeamSpot();// dummy
01992   }
01993 
01994 
01995   if(bnoBS){
01996     if((recVtxs->begin()->isValid())&&(recVtxs->begin()->ndof()>1)&&(recVtxs->begin()->ndof()>(0.0*recVtxs->begin()->tracksSize()))){  // was 5 and 0.2
01997       Fill(hnoBS,"xrecBeamvsdxXBS",recVtxs->begin()->xError(),recVtxs->begin()->x()-vertexBeamSpot_.x0());
01998       Fill(hnoBS,"yrecBeamvsdyXBS",recVtxs->begin()->yError(),recVtxs->begin()->y()-vertexBeamSpot_.y0());
01999 
02000       if(printXBS_) {
02001         cout << Form("XBS %10d %5d %10d  %4d   %lu %5.2f    %8f %8f       %8f %8f      %8f %8f",
02002                       run_,luminosityBlock_,event_,bunchCrossing_,
02003                       (unsigned long)(recVtxs->begin()->tracksSize()), recVtxs->begin()->ndof(),
02004                       recVtxs->begin()->x(),               recVtxs->begin()->xError(), 
02005                       recVtxs->begin()->y(),               recVtxs->begin()->yError(), 
02006                       recVtxs->begin()->z(),               recVtxs->begin()->zError()
02007                      ) << endl; 
02008       }
02009 
02010     }
02011   }
02012 
02013  
02014   // for the associator
02015   Handle<View<Track> > trackCollectionH;
02016   iEvent.getByLabel(recoTrackProducer_,trackCollectionH);
02017 
02018   Handle<HepMCProduct> evtMC;
02019 
02020   Handle<SimVertexContainer> simVtxs;
02021   iEvent.getByLabel( simG4_, simVtxs);
02022   
02023   Handle<SimTrackContainer> simTrks;
02024   iEvent.getByLabel( simG4_, simTrks);
02025 
02026 
02027 
02028 
02029 
02030   edm::Handle<TrackingParticleCollection>  TPCollectionH ;
02031   edm::Handle<TrackingVertexCollection>    TVCollectionH ;
02032   bool gotTP=iEvent.getByLabel("mergedtruth","MergedTrackTruth",TPCollectionH);
02033   bool gotTV=iEvent.getByLabel("mergedtruth","MergedTrackTruth",TVCollectionH);
02034 
02035 
02036   iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder",theB_);
02037   fBfield_=((*theB_).field()->inTesla(GlobalPoint(0.,0.,0.))).z();
02038 
02039  
02040   vector<SimEvent> simEvt;
02041   if (gotTP && gotTV ){
02042 
02043     edm::ESHandle<TrackAssociatorBase> theHitsAssociator;
02044     iSetup.get<TrackAssociatorRecord>().get("TrackAssociatorByHits",theHitsAssociator);
02045     associatorByHits_ = (TrackAssociatorBase *) theHitsAssociator.product();
02046     r2s_ =   associatorByHits_->associateRecoToSim (trackCollectionH,TPCollectionH, &iEvent ); 
02047     //simEvt=getSimEvents(iEvent, TPCollectionH, TVCollectionH, trackCollectionH);
02048     simEvt=getSimEvents(TPCollectionH, TVCollectionH, trackCollectionH);
02049 
02050     if (simEvt.size()==0){
02051       cout << " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
02052       cout << " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
02053       cout << " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
02054       cout << " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
02055       cout << " !!!!!!!!!!!!!!!!!!!!!!   got TrackingParticles but no simEvt   !!!!!!!!!!!!!!!!!" << endl;
02056       cout << " dumping Tracking particles " << endl;
02057       const TrackingParticleCollection* simTracks = TPCollectionH.product();
02058       for(TrackingParticleCollection::const_iterator it=simTracks->begin(); it!=simTracks->end(); it++){
02059         cout << *it << endl;
02060       }
02061       cout << " dumping Tracking Vertices " << endl;
02062       const TrackingVertexCollection* tpVtxs = TVCollectionH.product();
02063       for(TrackingVertexCollection::const_iterator iv=tpVtxs->begin(); iv!=tpVtxs->end(); iv++){
02064         cout << *iv << endl;
02065       }
02066       if(iEvent.getByLabel(mcproduct,evtMC)){
02067         cout << "dumping simTracks" << endl;
02068         for(SimTrackContainer::const_iterator t=simTrks->begin();  t!=simTrks->end(); ++t){
02069           cout << *t << endl;
02070         }
02071         cout << "dumping simVertexes" << endl;
02072         for(SimVertexContainer::const_iterator vv=simVtxs->begin();  
02073             vv!=simVtxs->end(); 
02074             ++vv){
02075           cout << *vv << endl;
02076         }
02077       }else{
02078         cout << "no hepMC" << endl;
02079       }
02080       cout << " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
02081 
02082       const HepMC::GenEvent* evt=evtMC->GetEvent();
02083       if(evt){
02084         std::cout << "process id " <<evt->signal_process_id()<<std::endl;
02085         std::cout <<"signal process vertex "<< ( evt->signal_process_vertex() ?
02086                                                  evt->signal_process_vertex()->barcode() : 0 )   <<std::endl;
02087         std::cout <<"number of vertices " << evt->vertices_size() << std::endl;
02088         evt->print();
02089       }else{
02090         cout << "no event in HepMC" << endl;
02091       }
02092       cout << " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
02093 
02094     }
02095   }
02096 
02097 
02098   
02099 
02100   if(gotTV){
02101 
02102     if(verbose_){
02103       cout << "Found Tracking Vertices " << endl;
02104     }
02105     simpv=getSimPVs(TVCollectionH);
02106     
02107 
02108   }else if(iEvent.getByLabel(mcproduct,evtMC)){
02109 
02110     simpv=getSimPVs(evtMC);
02111 
02112     if(verbose_){
02113       cout << "Using HepMCProduct " << endl;
02114       std::cout << "simtrks " << simTrks->size() << std::endl;
02115     }
02116     tsim = PrimaryVertexAnalyzer4PU::getSimTrkParameters(simTrks, simVtxs, simUnit_);
02117     
02118   }else{
02119     // if(verbose_({cout << "No MC info at all" << endl;}
02120   }
02121 
02122 
02123 
02124 
02125   // get the beam spot from the appropriate dummy vertex, if available
02126   for(reco::VertexCollection::const_iterator v=recVtxs->begin(); 
02127       v!=recVtxs->end(); ++v){
02128     if ((v->ndof()==-3) && (v->chi2()==0) ){ 
02129       myBeamSpot=math::XYZPoint(v->x(), v->y(), v->z());
02130     }
02131   }
02132 
02133   
02134 
02135 
02136   hsimPV["nsimvtx"]->Fill(simpv.size());
02137   for(std::vector<simPrimaryVertex>::iterator vsim=simpv.begin();
02138        vsim!=simpv.end(); vsim++){
02139     if(doMatching_){  
02140       matchRecTracksToVertex(*vsim, tsim, recTrks); // hepmc, based on track parameters
02141      }
02142 
02143      hsimPV["nbsimtksinvtx"]->Fill(vsim->nGenTrk);
02144      hsimPV["xsim"]->Fill(vsim->x*simUnit_);
02145      hsimPV["ysim"]->Fill(vsim->y*simUnit_);
02146      hsimPV["zsim"]->Fill(vsim->z*simUnit_);
02147      hsimPV["xsim1"]->Fill(vsim->x*simUnit_);
02148      hsimPV["ysim1"]->Fill(vsim->y*simUnit_);
02149      hsimPV["zsim1"]->Fill(vsim->z*simUnit_);
02150      Fill(hsimPV,"xsim2",vsim->x*simUnit_,vsim==simpv.begin());
02151      Fill(hsimPV,"ysim2",vsim->y*simUnit_,vsim==simpv.begin());
02152      Fill(hsimPV,"zsim2",vsim->z*simUnit_,vsim==simpv.begin());
02153      hsimPV["xsim2"]->Fill(vsim->x*simUnit_);
02154      hsimPV["ysim2"]->Fill(vsim->y*simUnit_);
02155      hsimPV["zsim2"]->Fill(vsim->z*simUnit_);
02156      hsimPV["xsim3"]->Fill(vsim->x*simUnit_);
02157      hsimPV["ysim3"]->Fill(vsim->y*simUnit_);
02158      hsimPV["zsim3"]->Fill(vsim->z*simUnit_);
02159      hsimPV["xsimb"]->Fill(vsim->x*simUnit_-vertexBeamSpot_.x0());
02160      hsimPV["ysimb"]->Fill(vsim->y*simUnit_-vertexBeamSpot_.y0());
02161      hsimPV["zsimb"]->Fill(vsim->z*simUnit_-vertexBeamSpot_.z0());
02162      hsimPV["xsimb1"]->Fill(vsim->x*simUnit_-vertexBeamSpot_.x0());
02163      hsimPV["ysimb1"]->Fill(vsim->y*simUnit_-vertexBeamSpot_.y0());
02164      hsimPV["zsimb1"]->Fill(vsim->z*simUnit_-vertexBeamSpot_.z0());
02165   }
02166 
02167 
02168 
02169 
02170    
02171    if(bnoBS){
02172      analyzeVertexCollection(hnoBS, recVtxs, recTrks, simpv,"noBS");
02173      analyzeVertexCollectionTP(hnoBS, recVtxs, recTrks, simEvt,"noBS");
02174    }
02175    if(bBS){
02176      analyzeVertexCollection(hBS, recVtxsBS, recTrks, simpv,"BS");
02177      analyzeVertexCollectionTP(hBS, recVtxsBS, recTrks, simEvt,"BS");
02178    }
02179    if(bDA){
02180      analyzeVertexCollection(hDA, recVtxsDA, recTrks, simpv,"DA");
02181      analyzeVertexCollectionTP(hDA, recVtxsDA, recTrks, simEvt,"DA");
02182    }
02183 //    if(bPIX){
02184 //      analyzeVertexCollection(hPIX, recVtxsPIX, recTrks, simpv,"PIX");
02185 //      analyzeVertexCollectionTP(hPIX, recVtxsPIX, recTrks, simEvt,"PIX");
02186 //    }
02187 
02188 
02189 
02190    if((dumpThisEvent_&& (dumpcounter_<100)) ||(verbose_ && (eventcounter_<ndump_))){
02191      cout << endl << "Event dump" << endl
02192           << "event counter=" << eventcounter_
02193           << " Run=" << run_ << "  LumiBlock " << luminosityBlock_ << "  event  " << event_
02194           << " bx=" << bunchCrossing_ <<  " orbit=" << orbitNumber_ 
02195           << std::endl;
02196      dumpcounter_++;
02197 
02198      //evtMC->GetEvent()->print();
02199      //printRecTrks(recTrks);  // very verbose !!
02200      
02201 //      if (bPIX) printRecVtxs(recVtxsPIX,"pixel vertices");
02202      if (bnoBS) {printRecVtxs(recVtxs,"Offline without Beamspot");}
02203      if (bnoBS && (!bDA)){ printPVTrks(recTrks, recVtxs, tsim, simEvt, false);}
02204      if (bBS) printRecVtxs(recVtxsBS,"Offline with Beamspot");
02205      if (bDA) {
02206        printRecVtxs(recVtxsDA,"Offline DA");
02207        printPVTrks(recTrks, recVtxsDA, tsim, simEvt, false);
02208      }
02209      if (dumpcounter_<2){cout << "beamspot " << vertexBeamSpot_ << endl;}
02210    }
02211 
02212   if(verbose_){
02213     std::cout << std::endl;
02214   }
02215 }
02216 
02217 namespace {
02218 bool lt(const std::pair<double,unsigned int>& a,const std::pair<double,unsigned int>& b ){
02219   return a.first<b.first;
02220 }
02221 }
02222 
02223 /***************************************************************************************/
02224 void PrimaryVertexAnalyzer4PU::printEventSummary(std::map<std::string, TH1*> & h,
02225                                                  const edm::Handle<reco::VertexCollection> recVtxs,
02226                                                  const edm::Handle<reco::TrackCollection> recTrks, 
02227                                                  vector<SimEvent> & simEvt,
02228                                                  const string message){
02229   // make a readable summary of the vertex finding if the TrackingParticles are availabe
02230   if (simEvt.size()==0){return;}
02231 
02232 
02233   // sort vertices in z ... for nicer printout
02234 
02235   vector< pair<double,unsigned int> >  zrecv;
02236   for(unsigned int idx=0; idx<recVtxs->size(); idx++){
02237     if ( (recVtxs->at(idx).ndof()<0) || (recVtxs->at(idx).chi2()<=0) ) continue;  // skip clusters 
02238     zrecv.push_back( make_pair(recVtxs->at(idx).z(),idx) );
02239   }
02240   stable_sort(zrecv.begin(),zrecv.end(),lt);
02241 
02242   // same for simulated vertices
02243   vector< pair<double,unsigned int> >  zsimv;
02244   for(unsigned int idx=0; idx<simEvt.size(); idx++){
02245     zsimv.push_back(make_pair(simEvt[idx].z, idx));
02246   }
02247   stable_sort(zsimv.begin(), zsimv.end(),lt);
02248 
02249 
02250 
02251 
02252   cout << "---------------------------" << endl;
02253   cout << "event counter = " << eventcounter_ << "   " << message << endl;
02254   cout << "---------------------------" << endl;
02255   cout << " z[cm]       rec -->    ";
02256   cout.precision(4);
02257   for(vector< pair<double,unsigned int> >::iterator itrec=zrecv.begin(); itrec!=zrecv.end(); itrec++){
02258     cout << setw(7) << fixed << itrec->first;
02259     if (itrec->second==0){cout << "*" ;}else{cout << " " ;}
02260   }
02261   cout << endl;
02262   cout << "                        ";
02263   for(vector< pair<double,unsigned int> >::iterator itrec=zrecv.begin(); itrec!=zrecv.end(); itrec++){
02264     cout << setw(7) << fixed << recVtxs->at(itrec->second).tracksSize();
02265     if (itrec->second==0){cout << "*" ;}else{cout << " " ;}
02266   }
02267   cout << "   rec tracks" << endl;
02268   cout << "                        ";
02269   map<unsigned int, int> truthMatchedVertexTracks;
02270   for(vector< pair<double,unsigned int> >::iterator itrec=zrecv.begin(); itrec!=zrecv.end(); itrec++){
02271     truthMatchedVertexTracks[itrec->second]=getTruthMatchedVertexTracks(recVtxs->at(itrec->second)).size();
02272     cout << setw(7) << fixed << truthMatchedVertexTracks[itrec->second];
02273     if (itrec->second==0){cout << "*" ;}else{cout << " " ;}
02274   }
02275   cout << "   truth matched " << endl;
02276 
02277   cout << "sim ------- trk  prim ----" << endl;
02278 
02279 
02280 
02281   map<unsigned int, unsigned int> rvmatch; // reco vertex matched to sim vertex  (sim to rec)
02282   map<unsigned int, double > nmatch;  // highest number of truth-matched tracks of ev found in a recvtx
02283   map<unsigned int, double > purity;  // highest purity of a rec vtx (i.e. highest number of tracks from the same simvtx)
02284   map<unsigned int, double > wpurity;  // same for the sum of weights
02285 
02286   for(vector< pair<double,unsigned int> >::iterator itrec=zrecv.begin(); itrec!=zrecv.end(); itrec++){
02287     purity[itrec->second]=0.;
02288     wpurity[itrec->second]=0.;
02289   }
02290 
02291   for(vector< pair<double,unsigned int> >::iterator itsim=zsimv.begin(); itsim!=zsimv.end(); itsim++){
02292     SimEvent* ev =&(simEvt[itsim->second]);
02293 
02294 
02295     cout.precision(4);
02296     if (itsim->second==0){
02297       cout << setw(8) << fixed << ev->z << ")*" << setw(5) << ev->tk.size() << setw(5) << ev->tkprim.size() << "  | ";
02298     }else{
02299       cout << setw(8) << fixed << ev->z << ") " << setw(5) << ev->tk.size() << setw(5) << ev->tkprim.size() << "  | ";
02300     }
02301 
02302     nmatch[itsim->second]=0;  // highest number of truth-matched tracks of ev found in a recvtx
02303     double matchpurity=0,matchwpurity=0;
02304 
02305     for(vector< pair<double,unsigned int> >::iterator itrec=zrecv.begin(); itrec!=zrecv.end(); itrec++){
02306       const reco::Vertex *v = &(recVtxs->at(itrec->second));
02307 
02308       // count tracks found in both, sim and rec
02309       double n=0,wt=0;
02310       for(vector<TransientTrack>::iterator te=ev->tk.begin(); te!=ev->tk.end(); te++){
02311         const reco::Track&  RTe=te->track();
02312          for(trackit_t tv=v->tracks_begin(); tv!=v->tracks_end(); tv++){
02313            const reco::Track & RTv=*(tv->get());  
02314            if(RTe.vz()==RTv.vz()) {n++; wt+=v->trackWeight(*tv);}
02315         }
02316       }
02317       cout << setw(7) << int(n)<< " ";
02318 
02319       if (n > nmatch[itsim->second]){
02320         nmatch[itsim->second]=n;
02321         rvmatch[itsim->second]=itrec->second;
02322         matchpurity=n/truthMatchedVertexTracks[itrec->second];
02323         matchwpurity=wt/truthMatchedVertexTracks[itrec->second];
02324       }
02325 
02326       if(n > purity[itrec->second]){
02327         purity[itrec->second]=n;
02328       }
02329 
02330       if(wt > wpurity[itrec->second]){
02331         wpurity[itrec->second]=wt;
02332       }
02333 
02334     }// end of reco vertex loop
02335 
02336     cout << "  | ";
02337     if  (nmatch[itsim->second]>0 ){
02338       if(matchpurity>0.5){
02339         cout << "found  ";
02340       }else{
02341         cout << "merged ";
02342       } 
02343       cout << "  max eff. = "  << setw(8) << nmatch[itsim->second]/ev->tk.size() << " p=" << matchpurity << " w=" << matchwpurity <<  endl;
02344     }else{
02345       if(ev->tk.size()==0){
02346         cout  << " invisible" << endl;
02347       }else if (ev->tk.size()==1){
02348         cout << "single track " << endl;
02349       }else{
02350         cout << "lost " << endl;
02351       }
02352     }
02353   }
02354   cout << "---------------------------" << endl;
02355 
02356   //  the purity of the reconstructed vertex
02357   cout << "               purity   ";
02358   for(vector< pair<double,unsigned int> >::iterator itrec=zrecv.begin(); itrec!=zrecv.end(); itrec++){
02359     cout << setw(7) << fixed << purity[itrec->second]/truthMatchedVertexTracks[itrec->second];
02360     if (itrec->second==0){cout << "*" ;}else{cout << " " ;}
02361   }
02362   cout << endl;
02363 
02364 //   //  classification of reconstructed vertex fake/real
02365 //   cout << "                        ";
02366 //   for(vector< pair<double,unsigned int> >::iterator itrec=zrecv.begin(); itrec!=zrecv.end(); itrec++){
02367 //     cout << setw(7) << fixed << purity[itrec->second]/truthMatchedVertexTracks[itrec->second];
02368 //     if (itrec->second==0){cout << "*" ;}else{cout << " " ;}
02369 //   }
02370 //   cout << endl;
02371   cout << "---------------------------" << endl;
02372 
02373 
02374 
02375 
02376   // list problematic tracks
02377   for(vector< pair<double,unsigned int> >::iterator itsim=zsimv.begin(); itsim!=zsimv.end(); itsim++){
02378     SimEvent* ev =&(simEvt[itsim->second]);
02379 
02380     for(vector<TransientTrack>::iterator te=ev->tk.begin(); te!=ev->tk.end(); te++){
02381       const reco::Track&  RTe=te->track();
02382       
02383       int ivassign=-1;  // will become the index of the vertex to which a track was assigned
02384       
02385       for(vector< pair<double,unsigned int> >::iterator itrec=zrecv.begin(); itrec!=zrecv.end(); itrec++){
02386         const reco::Vertex *v = &(recVtxs->at(itrec->second));
02387 
02388         for(trackit_t tv=v->tracks_begin(); tv!=v->tracks_end(); tv++){
02389           const reco::Track & RTv=*(tv->get());  
02390           if(RTe.vz()==RTv.vz()) {ivassign=itrec->second;}
02391         }
02392       }
02393       double tantheta=tan((te->stateAtBeamLine().trackStateAtPCA()).momentum().theta());
02394       reco::BeamSpot beamspot=(te->stateAtBeamLine()).beamSpot();
02395       //double z=(te->stateAtBeamLine().trackStateAtPCA()).position().z();
02396       double dz2= pow(RTe.dzError(),2)+pow(beamspot.BeamWidthX()/tantheta,2);
02397       
02398       if(ivassign==(int)rvmatch[itsim->second]){
02399         Fill(h,"correctlyassigned",RTe.eta(),RTe.pt());
02400         Fill(h,"ptcat",RTe.pt());
02401         Fill(h,"etacat",RTe.eta());
02402         Fill(h,"phicat",RTe.phi());
02403         Fill(h,"dzcat",sqrt(dz2));
02404       }else{
02405         Fill(h,"misassigned",RTe.eta(),RTe.pt());
02406         Fill(h,"ptmis",RTe.pt());
02407         Fill(h,"etamis",RTe.eta());
02408         Fill(h,"phimis",RTe.phi());
02409         Fill(h,"dzmis",sqrt(dz2));
02410         cout << "vertex " << setw(8) << fixed << ev->z;
02411 
02412         if (ivassign<0){
02413           cout << " track lost                ";
02414           // for some clusterizers there shouldn't be any lost tracks,
02415           // are there differences in the track selection?
02416         }else{
02417           cout << " track misassigned " << setw(8) << fixed << recVtxs->at(ivassign).z();
02418         }
02419 
02420         cout << "  track z=" << setw(8) << fixed  << RTe.vz() << "+/-" << RTe.dzError() << "  pt=" <<  setw(8) << fixed<< RTe.pt() << "  eta=" << setw(8) << fixed << RTe.eta()<< " sel=" <<theTrackFilter(*te);
02421 
02422         //
02423         //cout << " ztrack=" << te->track().vz();
02424         TrackingParticleRef tpr = z2tp_[te->track().vz()];
02425         double zparent=tpr->parentVertex().get()->position().z();
02426         if(zparent==ev->z) {
02427           cout << " prim";
02428         }else{
02429           cout << " sec ";
02430         }
02431         cout << "  id=" << tpr->pdgId();
02432         cout << endl;
02433 
02434         //
02435       }
02436     }// next simvertex-track
02437 
02438   }//next simvertex
02439 
02440   cout << "---------------------------" << endl;
02441 
02442 }
02443 /***************************************************************************************/
02444 
02445 
02446 
02447 
02448 /***************************************************************************************/
02449 void PrimaryVertexAnalyzer4PU::analyzeVertexCollectionTP(std::map<std::string, TH1*> & h,
02450                                const edm::Handle<reco::VertexCollection> recVtxs,
02451                                const edm::Handle<reco::TrackCollection> recTrks, 
02452                                                         vector<SimEvent> & simEvt,
02453                                                         const string message){
02454   
02455   //  cout <<"PrimaryVertexAnalyzer4PU::analyzeVertexCollectionTP size=" << simEvt.size() << endl;
02456   if(simEvt.size()==0)return;
02457 
02458   printEventSummary(h, recVtxs,recTrks,simEvt,message);
02459 
02460   //const int iSignal=0;  
02461   EncodedEventId iSignal=simEvt[0].eventId;
02462   Fill(h,"npu0",simEvt.size());
02463 
02464 
02465   for(vector<SimEvent>::iterator ev=simEvt.begin(); ev!=simEvt.end(); ev++){
02466     Fill(h,"Tc",    ev->Tc,    ev==simEvt.begin());
02467     Fill(h,"Chisq", ev->chisq, ev==simEvt.begin());
02468     if(ev->chisq>0)Fill(h,"logChisq", log(ev->chisq), ev==simEvt.begin());
02469     Fill(h,"dzmax", ev->dzmax, ev==simEvt.begin());
02470     Fill(h,"dztrim",ev->dztrim,ev==simEvt.begin());
02471     Fill(h,"m4m2",  ev->m4m2,  ev==simEvt.begin());
02472     if(ev->Tc>0){  Fill(h,"logTc",log(ev->Tc)/log(10.),ev==simEvt.begin());}
02473     
02474 
02475     for(vector<SimEvent>::iterator ev2=ev+1; ev2!=simEvt.end(); ev2++){
02476       vector<TransientTrack> xt;
02477       if((ev->tkprimsel.size()>0)&&(ev2->tkprimsel.size()>0)&&(ev->tkprimsel.size()+ev2->tkprimsel.size())>1){
02478         xt.insert (xt.end() ,ev->tkprimsel.begin(),ev->tkprimsel.end());
02479         xt.insert (xt.end() ,ev2->tkprimsel.begin(),ev2->tkprimsel.end());
02480         double xTc,xChsq,xDzmax,xDztrim,xm4m2;
02481         getTc(xt, xTc, xChsq, xDzmax, xDztrim,xm4m2);
02482         if(xTc>0){
02483           Fill(h,"xTc",xTc,ev==simEvt.begin());
02484           Fill(h,"logxTc",   log(xTc)/log(10),ev==simEvt.begin());
02485           Fill(h,"xChisq",   xChsq,ev==simEvt.begin());
02486           if(xChsq>0){Fill(h,"logxChisq",   log(xChsq),ev==simEvt.begin());};
02487           Fill(h,"xdzmax",   xDzmax,ev==simEvt.begin());
02488           Fill(h,"xdztrim",  xDztrim,ev==simEvt.begin());
02489           Fill(h,"xm4m2",    xm4m2,ev==simEvt.begin());
02490           
02491         }
02492       }
02493     }
02494   }
02495   
02496   // --------------------------------------- count actual rec vtxs ----------------------
02497   int nrecvtxs=0;//, nrecvtxs1=0, nrecvtxs2=0;
02498   for(reco::VertexCollection::const_iterator v=recVtxs->begin(); 
02499       v!=recVtxs->end(); ++v){
02500     if ( (v->isFake()) || (v->ndof()<0) || (v->chi2()<=0) ) continue;  // skip clusters 
02501     nrecvtxs++;
02502   }
02503 
02504   // --------------------------------------- fill the track assignment matrix ----------------------
02505   for(vector<SimEvent>::iterator ev=simEvt.begin(); ev!=simEvt.end(); ev++){
02506     ev->ntInRecVz.clear();  // just in case
02507     ev->zmatch=-99.;
02508     ev->nmatch=0;
02509     for(reco::VertexCollection::const_iterator v=recVtxs->begin(); 
02510         v!=recVtxs->end(); ++v){
02511       double n=0, wt=0;
02512       for(vector<TransientTrack>::iterator te=ev->tk.begin(); te!=ev->tk.end(); te++){
02513         const reco::Track&  RTe=te->track();
02514         for(trackit_t tv=v->tracks_begin(); tv!=v->tracks_end(); tv++){
02515           const reco::Track & RTv=*(tv->get());  
02516           if(RTe.vz()==RTv.vz()) {n++; wt+=v->trackWeight(*tv);}
02517         }
02518       }
02519       ev->ntInRecVz[v->z()]=n;
02520       if (n > ev->nmatch){ ev->nmatch=n; ev->zmatch=v->z(); ev->zmatch=v->z(); }
02521     }
02522   }
02523   
02524     // call a vertex a fake if for every sim vertex there is another recvertex containing more tracks
02525     // from that sim vertex than the current recvertex
02526   double nfake=0;
02527   for(reco::VertexCollection::const_iterator v=recVtxs->begin(); 
02528       v!=recVtxs->end(); ++v){
02529     bool matched=false;
02530     for(vector<SimEvent>::iterator ev=simEvt.begin(); ev!=simEvt.end(); ev++){
02531       if ((ev->nmatch>0)&&(ev->zmatch==v->z())){
02532         matched=true;
02533       }
02534     }
02535     if(!matched && !v->isFake()) {
02536       nfake++;
02537       cout << " fake rec vertex at z=" << v->z() << endl;
02538       // some histograms of fake vertex properties here
02539       Fill(h,"unmatchedVtxZ",v->z());
02540       Fill(h,"unmatchedVtxNdof",v->ndof());
02541     }
02542   }
02543   if(nrecvtxs>0){
02544     Fill(h,"unmatchedVtx",nfake);
02545     Fill(h,"unmatchedVtxFrac",nfake/nrecvtxs);
02546   }
02547 
02548   // --------------------------------------- match rec to sim ---------------------------------------
02549   for(reco::VertexCollection::const_iterator v=recVtxs->begin(); 
02550       v!=recVtxs->end(); ++v){
02551 
02552     if ( (v->ndof()<0) || (v->chi2()<=0) ) continue;  // skip clusters 
02553     double  nmatch=-1;      // highest number of tracks in recvtx v found in any event
02554     EncodedEventId evmatch;
02555     bool matchFound=false;
02556     double nmatchvtx=0;     // number of simvtcs contributing to recvtx v
02557 
02558     for(vector<SimEvent>::iterator ev=simEvt.begin(); ev!=simEvt.end(); ev++){
02559 
02560       double n=0;  // number of tracks that are in both, the recvtx v and the event ev
02561       for(vector<TransientTrack>::iterator te=ev->tk.begin(); te!=ev->tk.end(); te++){
02562 
02563         const reco::Track&  RTe=te->track();
02564          for(trackit_t tv=v->tracks_begin(); tv!=v->tracks_end(); tv++){
02565            const reco::Track & RTv=*(tv->get());  
02566            if(RTe.vz()==RTv.vz()){ n++;}
02567         }
02568       }     
02569 
02570       // find the best match in terms of the highest number of tracks 
02571       // from a simvertex in this rec vertex
02572       if (n > nmatch){
02573         nmatch=n;
02574         evmatch=ev->eventId;
02575         matchFound=true;
02576       }
02577       if(n>0){
02578         nmatchvtx++;
02579       }
02580     }
02581 
02582     double nmatchany=getTruthMatchedVertexTracks(*v).size();  
02583     if (matchFound && (nmatchany>0)){
02584       //           highest number of tracks in recvtx matched to (the same) sim vertex
02585       // purity := -----------------------------------------------------------------
02586       //                  number of truth matched tracks in this recvtx
02587       double purity =nmatch/nmatchany; 
02588       Fill(h,"recmatchPurity",purity);
02589       if(v==recVtxs->begin()){
02590         Fill(h,"recmatchPurityTag",purity, (bool)(evmatch==iSignal));
02591       }else{
02592         Fill(h,"recmatchPuritynoTag",purity,(bool)(evmatch==iSignal));
02593       }
02594     }
02595     Fill(h,"recmatchvtxs",nmatchvtx);
02596     if(v==recVtxs->begin()){
02597       Fill(h,"recmatchvtxsTag",nmatchvtx);
02598     }else{
02599       Fill(h,"recmatchvtxsnoTag",nmatchvtx);
02600     }
02601 
02602 
02603      
02604   } // recvtx loop
02605   Fill(h,"nrecv",nrecvtxs);
02606 
02607 
02608   // --------------------------------------- match sim to rec  ---------------------------------------
02609 
02610   int npu1=0, npu2=0;
02611 
02612   for(vector<SimEvent>::iterator ev=simEvt.begin(); ev!=simEvt.end(); ev++){
02613 
02614     if(ev->tk.size()>0) npu1++;
02615     if(ev->tk.size()>1) npu2++;
02616 
02617     bool isSignal= ev->eventId==iSignal;
02618     
02619     Fill(h,"nRecTrkInSimVtx",(double) ev->tk.size(),isSignal);
02620     Fill(h,"nPrimRecTrkInSimVtx",(double) ev->tkprim.size(),isSignal);
02621     Fill(h,"sumpt2rec",sqrt(ev->sumpt2rec),isSignal);
02622     Fill(h,"sumpt2",sqrt(ev->sumpt2),isSignal);
02623     Fill(h,"sumpt",sqrt(ev->sumpt),isSignal);
02624 
02625     double nRecVWithTrk=0;  // vertices with tracks from this simvertex
02626     double  nmatch=0, ntmatch=0, zmatch=-99;
02627 
02628     for(reco::VertexCollection::const_iterator v=recVtxs->begin(); 
02629         v!=recVtxs->end(); ++v){
02630       if ( (v->ndof()<-1) || (v->chi2()<=0) ) continue;  // skip clusters 
02631       // count tracks found in both, sim and rec
02632       double n=0, wt=0;
02633       for(vector<TransientTrack>::iterator te=ev->tk.begin(); te!=ev->tk.end(); te++){
02634         const reco::Track&  RTe=te->track();
02635         for(trackit_t tv=v->tracks_begin(); tv!=v->tracks_end(); tv++){
02636            const reco::Track & RTv=*(tv->get());  
02637            if(RTe.vz()==RTv.vz()) {n++; wt+=v->trackWeight(*tv);}
02638         }
02639       }
02640 
02641       if(n>0){  nRecVWithTrk++; }
02642       if (n > nmatch){
02643         nmatch=n; ntmatch=v->tracksSize(); zmatch=v->position().z();
02644       }
02645       
02646     }// end of reco vertex loop
02647 
02648 
02649     // nmatch is the highest number of tracks from this sim vertex found in a single reco-vertex
02650     if(ev->tk.size()>0){ Fill(h,"trkAssignmentEfficiency", nmatch/ev->tk.size(), isSignal); };
02651     if(ev->tkprim.size()>0){ Fill(h,"primtrkAssignmentEfficiency", nmatch/ev->tkprim.size(), isSignal); };
02652 
02653     // matched efficiency = efficiency for finding a reco vertex with > 50% of the simvertexs reconstructed tracks
02654 
02655     double ntsim=ev->tk.size(); // may be better to use the number of primary tracks here ?
02656     double matchpurity=nmatch/ntmatch;
02657 
02658     if(ntsim>0){
02659 
02660       Fill(h,"matchVtxFraction",nmatch/ntsim,isSignal);
02661       if(nmatch/ntsim>=0.5){
02662         Fill(h,"matchVtxEfficiency",1.,isSignal);
02663         if(ntsim>1){Fill(h,"matchVtxEfficiency2",1.,isSignal);}
02664         if(matchpurity>0.5){Fill(h,"matchVtxEfficiency5",1.,isSignal);}
02665       }else{
02666         Fill(h,"matchVtxEfficiency",0.,isSignal);
02667         if(ntsim>1){Fill(h,"matchVtxEfficiency2",0.,isSignal);}
02668         Fill(h,"matchVtxEfficiency5",0.,isSignal);  // no (matchpurity>5) here !!
02669         if(isSignal){
02670         cout << "Signal vertex not matched " <<  message << "  event=" << eventcounter_ << " nmatch=" << nmatch << "  ntsim=" << ntsim << endl;
02671         }
02672       }
02673     } // ntsim >0
02674 
02675 
02676     if(zmatch>-99){
02677       Fill(h,"matchVtxZ",zmatch-ev->z);
02678       Fill(h,"matchVtxZ",zmatch-ev->z,isSignal);
02679       Fill(h,"matchVtxZCum",fabs(zmatch-ev->z));
02680       Fill(h,"matchVtxZCum",fabs(zmatch-ev->z),isSignal);
02681     }else{
02682       Fill(h,"matchVtxZCum",1.0);
02683       Fill(h,"matchVtxZCum",1.0,isSignal);
02684     }
02685     if(fabs(zmatch-ev->z)<zmatch_){
02686       Fill(h,"matchVtxEfficiencyZ",1.,isSignal);
02687     }else{
02688       Fill(h,"matchVtxEfficiencyZ",0.,isSignal);
02689     }   
02690     
02691     if(ntsim>0) Fill(h, "matchVtxEfficiencyZ1", fabs(zmatch-ev->z)<zmatch_ , isSignal);
02692     if(ntsim>1) Fill(h, "matchVtxEfficiencyZ2", fabs(zmatch-ev->z)<zmatch_ , isSignal);
02693 
02694 
02695     Fill(h,"vtxMultiplicity",nRecVWithTrk,isSignal);
02696 
02697     // efficiency vs number of tracks, use your favorite definition of efficiency here
02698     //if(nmatch>=0.5*ntmatch){  // purity
02699     if(fabs(zmatch-ev->z)<zmatch_){  //  zmatch
02700       Fill(h,"vtxFindingEfficiencyVsNtrk",(double) ev->tk.size(),1.);
02701        if(isSignal){
02702          Fill(h,"vtxFindingEfficiencyVsNtrkSignal",ev->tk.size(),1.);
02703       }else{
02704         Fill(h,"vtxFindingEfficiencyVsNtrkPU",(double) ev->tk.size(),1.);
02705       }
02706     }else{
02707       Fill(h,"vtxFindingEfficiencyVsNtrk",(double) ev->tk.size(),0.);
02708       if(isSignal){
02709         Fill(h,"vtxFindingEfficiencyVsNtrkSignal",(double) ev->tk.size(),1.);
02710       }else{
02711         Fill(h,"vtxFindingEfficiencyVsNtrkPU",(double) ev->tk.size(),1.);
02712       }
02713     }
02714 
02715     
02716   }
02717   
02718   Fill(h,"npu1",npu1);
02719   Fill(h,"npu2",npu2);
02720 
02721   Fill(h,"nrecvsnpu",npu1,float(nrecvtxs));
02722   Fill(h,"nrecvsnpu2",npu2,float(nrecvtxs));
02723 
02724   // ---------------------------------------  sim-signal vs rec-tag  ---------------------------------------
02725   SimEvent* ev=&(simEvt[0]);
02726   const reco::Vertex* v=&(*recVtxs->begin());
02727 
02728   double n=0;
02729   for(vector<TransientTrack>::iterator te=ev->tk.begin(); te!=ev->tk.end(); te++){
02730     const reco::Track&  RTe=te->track();
02731     for(trackit_t tv=v->tracks_begin(); tv!=v->tracks_end(); tv++){
02732       const reco::Track & RTv=*(tv->get());  
02733       if(RTe.vz()==RTv.vz()) {n++;}
02734     }
02735   }
02736   
02737   cout << "Number of tracks in reco tagvtx " << v->tracksSize() << endl;
02738   cout << "Number of selected tracks in sim event vtx " << ev->tk.size() << "    (prim=" << ev->tkprim.size() << ")"<<endl;
02739   cout << "Number of tracks in both         " << n << endl;
02740   double ntruthmatched=getTruthMatchedVertexTracks(*v).size();
02741   if (ntruthmatched>0){
02742     cout << "TrackPurity = "<< n/ntruthmatched <<endl;
02743     Fill(h,"TagVtxTrkPurity",n/ntruthmatched);
02744   }
02745   if (ev->tk.size()>0){
02746     cout << "TrackEfficiency = "<< n/ev->tk.size() <<endl;
02747     Fill(h,"TagVtxTrkEfficiency",n/ev->tk.size());
02748   }
02749 }
02750 
02751 /***************************************************************************************/
02752 
02753 
02754 
02755 
02756 
02757 
02758 /***************************************************************************************/
02759 
02760 void PrimaryVertexAnalyzer4PU::analyzeVertexCollection(std::map<std::string, TH1*> & h,
02761                                                  const Handle<reco::VertexCollection> recVtxs,
02762                                                  const Handle<reco::TrackCollection> recTrks, 
02763                                                  std::vector<simPrimaryVertex> & simpv,
02764                                                        const std::string message)
02765 {
02766   //cout <<"PrimaryVertexAnalyzer4PU::analyzeVertexCollection (HepMC), simpvs=" << simpv.size() << endl;
02767   int nrectrks=recTrks->size();
02768   int nrecvtxs=recVtxs->size();
02769   int nseltrks=-1; 
02770   reco::TrackCollection selTrks;   // selected tracks
02771   reco::TrackCollection lostTrks;  // selected but lost tracks (part of dropped clusters)
02772 
02773   // extract dummy vertices representing clusters
02774   reco::VertexCollection clusters;
02775   reco::Vertex allSelected;
02776   double cpufit=0;
02777   double cpuclu=0;
02778   for(reco::VertexCollection::const_iterator v=recVtxs->begin(); 
02779       v!=recVtxs->end(); ++v){
02780     if ( (fabs(v->ndof()+3.)<0.0001) && (v->chi2()<=0) ){ 
02781       // this dummy vertex is for the full event
02782       allSelected=(*v);
02783       nseltrks=(allSelected.tracksSize());
02784       nrecvtxs--;
02785       cpuclu=-v->chi2();
02786       continue;
02787     }else if( (fabs(v->ndof()+2.)<0.0001) && (v->chi2()==0) ){
02788       // this is a cluster, not a vertex
02789       clusters.push_back(*v);
02790       Fill(h,"cpuvsntrk",(double) v->tracksSize(),fabs(v->y()));
02791       cpufit+=fabs(v->y());
02792       Fill(h,"nclutrkall",(double) v->tracksSize());
02793       Fill(h,"selstat",v->x());
02794       //Fill(h,"nclutrkvtx",);// see below
02795       nrecvtxs--;
02796     }
02797   }
02798   Fill(h,"cpuclu",cpuclu);
02799   Fill(h,"cpufit",cpufit);
02800   Fill(h,"cpucluvsntrk",nrectrks, cpuclu);
02801   
02802 
02803   
02804   if(simpv.size()>0){//this is mc
02805     double dsimrecx=0.;
02806     double dsimrecy=0.;//0.0011;
02807     double dsimrecz=0.;//0.0012;
02808     
02809     // vertex matching and efficiency bookkeeping
02810     int nsimtrk=0;
02811     for(std::vector<simPrimaryVertex>::iterator vsim=simpv.begin();
02812         vsim!=simpv.end(); vsim++){
02813       
02814       
02815       nsimtrk+=vsim->nGenTrk;
02816       // look for a matching reconstructed vertex
02817       vsim->recVtx=NULL;
02818       vsim->cluster=-1;
02819       
02820       for(reco::VertexCollection::const_iterator vrec=recVtxs->begin();  vrec!=recVtxs->end(); ++vrec){
02821 
02822         if( vrec->isFake() ) {
02823           continue;  // skip fake vertices (=beamspot)
02824           cout << "fake vertex" << endl;
02825         }
02826 
02827         if( vrec->ndof()<0. )continue;  // skip dummy clusters, if any
02828         //        if ( matchVertex(*vsim,*vrec) ){
02829 
02830         // if the matching critera are fulfilled, accept the rec-vertex that is closest in z
02831         if(    ((vsim->recVtx) && (fabs(vsim->recVtx->position().z()-vsim->z-dsimrecz)>fabs(vrec->z()-vsim->z-dsimrecz)))
02832                || (!vsim->recVtx) )
02833           {
02834             vsim->recVtx=&(*vrec);
02835 
02836             // find the corresponding cluster
02837             for(unsigned int iclu=0; iclu<clusters.size(); iclu++){
02838               if( fabs(clusters[iclu].position().z()-vrec->position().z()) < 0.001 ){
02839                 vsim->cluster=iclu;
02840                 vsim->nclutrk=clusters[iclu].position().y();
02841               }
02842             }
02843           }
02844 
02845         // the following only works in MC samples without pile-up
02846         if ((simpv.size()==1) && ( fabs(vsim->recVtx->position().z()-vsim->z-dsimrecz)>zmatch_ )){
02847             // now we have a recvertex without a matching simvertex, I would call this fake 
02848             // however, the G4 info does not contain pile-up
02849             Fill(h,"fakeVtxZ",vrec->z());
02850             if (vrec->ndof()>=0.5) Fill(h,"fakeVtxZNdofgt05",vrec->z());
02851             if (vrec->ndof()>=2.0) Fill(h,"fakeVtxZNdofgt2",vrec->z());
02852             Fill(h,"fakeVtxNdof",vrec->ndof());
02853             //Fill(h,"fakeVtxNdof1",vrec->ndof());
02854             Fill(h,"fakeVtxNtrk",vrec->tracksSize());
02855             if(vrec->tracksSize()==2){  Fill(h,"fake2trkchi2vsndof",vrec->ndof(),vrec->chi2());   }
02856             if(vrec->tracksSize()==3){  Fill(h,"fake3trkchi2vsndof",vrec->ndof(),vrec->chi2());   }
02857             if(vrec->tracksSize()==4){  Fill(h,"fake4trkchi2vsndof",vrec->ndof(),vrec->chi2());   }
02858             if(vrec->tracksSize()==5){  Fill(h,"fake5trkchi2vsndof",vrec->ndof(),vrec->chi2());   }
02859           }
02860       }
02861       
02862 
02863       Fill(h,"nsimtrk",float(nsimtrk));
02864       Fill(h,"nsimtrk",float(nsimtrk),vsim==simpv.begin());
02865       Fill(h,"nrecsimtrk",float(vsim->nMatchedTracks));
02866       Fill(h,"nrecnosimtrk",float(nsimtrk-vsim->nMatchedTracks));
02867       
02868       // histogram properties of matched vertices
02869       if (vsim->recVtx && ( fabs(vsim->recVtx->z()-vsim->z*simUnit_)<zmatch_ )){
02870         
02871         if(verbose_){std::cout <<"primary matched " << message << " " << setw(8) << setprecision(4) << vsim->x << " " << vsim->y << " " << vsim->z << std:: endl;}
02872         Fill(h,"matchedVtxNdof", vsim->recVtx->ndof());
02873         // residuals an pulls with respect to simulated vertex
02874         Fill(h,"resx", vsim->recVtx->x()-vsim->x*simUnit_ );
02875         Fill(h,"resy", vsim->recVtx->y()-vsim->y*simUnit_ );
02876         Fill(h,"resz", vsim->recVtx->z()-vsim->z*simUnit_ );
02877         Fill(h,"resz10", vsim->recVtx->z()-vsim->z*simUnit_ );
02878         Fill(h,"pullx", (vsim->recVtx->x()-vsim->x*simUnit_)/vsim->recVtx->xError() );
02879         Fill(h,"pully", (vsim->recVtx->y()-vsim->y*simUnit_)/vsim->recVtx->yError() );
02880         Fill(h,"pullz", (vsim->recVtx->z()-vsim->z*simUnit_)/vsim->recVtx->zError() );
02881         Fill(h,"resxr", vsim->recVtx->x()-vsim->x*simUnit_-dsimrecx);
02882         Fill(h,"resyr", vsim->recVtx->y()-vsim->y*simUnit_-dsimrecy );
02883         Fill(h,"reszr", vsim->recVtx->z()-vsim->z*simUnit_-dsimrecz);
02884         Fill(h,"pullxr", (vsim->recVtx->x()-vsim->x*simUnit_-dsimrecx)/vsim->recVtx->xError() );
02885         Fill(h,"pullyr", (vsim->recVtx->y()-vsim->y*simUnit_-dsimrecy)/vsim->recVtx->yError() );
02886         Fill(h,"pullzr", (vsim->recVtx->z()-vsim->z*simUnit_-dsimrecz)/vsim->recVtx->zError() );
02887 
02888 
02889 
02890         // efficiency with zmatch within 500 um (or whatever zmatch is)
02891         Fill(h,"eff", 1.);
02892         if(simpv.size()==1){
02893           if (vsim->recVtx==&(*recVtxs->begin())){
02894             Fill(h,"efftag", 1.); 
02895           }else{
02896             Fill(h,"efftag", 0.); 
02897             cout << "signal vertex not tagged " << message << " " << eventcounter_ << endl;
02898             // call XXClusterizerInZ.vertices(seltrks,3)
02899             
02900           }
02901         }
02902         
02903         Fill(h,"effvsptsq",vsim->ptsq,1.);
02904         Fill(h,"effvsnsimtrk",vsim->nGenTrk,1.);
02905         Fill(h,"effvsnrectrk",nrectrks,1.);
02906         Fill(h,"effvsnseltrk",nseltrks,1.);
02907         Fill(h,"effvsz",vsim->z*simUnit_,1.);
02908         Fill(h,"effvsz2",vsim->z*simUnit_,1.);
02909         Fill(h,"effvsr",sqrt(vsim->x*vsim->x+vsim->y*vsim->y)*simUnit_,1.);
02910         
02911 
02912       }else{  // no matching rec vertex found for this simvertex
02913         
02914         bool plapper=verbose_ && vsim->nGenTrk;
02915         if(plapper){
02916           // be quiet about invisble vertices
02917           std::cout << "primary not found "  << message << " " << eventcounter_ << "  x=" <<vsim->x*simUnit_ << "  y=" << vsim->y*simUnit_  << " z=" << vsim->z*simUnit_  << " nGenTrk=" << vsim->nGenTrk << std::endl;
02918         }
02919         int mistype=0;
02920         if (vsim->recVtx){
02921           if(plapper){
02922             std::cout << "nearest recvertex at " << vsim->recVtx->z() << "   dz=" << vsim->recVtx->z()-vsim->z*simUnit_ << std::endl;
02923           }
02924           
02925           if (fabs(vsim->recVtx->z()-vsim->z*simUnit_)<0.2 ){
02926             Fill(h,"effvsz2",vsim->z*simUnit_,1.);
02927           }
02928           
02929           if (fabs(vsim->recVtx->z()-vsim->z*simUnit_)<0.5 ){
02930             if(verbose_){std::cout << "type 1, lousy z vertex" << std::endl;}
02931             Fill(h,"zlost1", vsim->z*simUnit_,1.);
02932             mistype=1;
02933           }else{
02934             if(plapper){std::cout << "type 2a no vertex anywhere near" << std::endl;}
02935             mistype=2;
02936           }
02937         }else{// no recVtx at all
02938           mistype=2;
02939           if(plapper){std::cout << "type 2b, no vertex at all" << std::endl;}
02940         }
02941         
02942         if(mistype==2){
02943           int selstat=-3;
02944           // no matching vertex found, is there a cluster?
02945           for(unsigned int iclu=0; iclu<clusters.size(); iclu++){
02946             if( fabs(clusters[iclu].position().z()-vsim->z*simUnit_) < 0.1 ){
02947               selstat=int(clusters[iclu].position().x()+0.1);
02948               if(verbose_){std::cout << "matching cluster found with selstat=" << clusters[iclu].position().x() << std::endl;}
02949             }
02950           }
02951           if (selstat==0){
02952             if(plapper){std::cout << "vertex rejected (distance to beam)" << std::endl;}
02953             Fill(h,"zlost3", vsim->z*simUnit_,1.);
02954           }else if(selstat==-1){
02955             if(plapper) {std::cout << "vertex invalid" << std::endl;}
02956             Fill(h,"zlost4", vsim->z*simUnit_,1.);
02957           }else if(selstat==1){
02958             if(plapper){std::cout << "vertex accepted, this cannot be right!!!!!!!!!!" << std::endl;}
02959           }else if(selstat==-2){
02960             if(plapper){std::cout << "dont know what this means !!!!!!!!!!" << std::endl;}
02961           }else if(selstat==-3){
02962             if(plapper){std::cout << "no matching cluster found " << std::endl;}
02963             Fill(h,"zlost2", vsim->z*simUnit_,1.);
02964           }else{
02965             if(plapper){std::cout << "dont know what this means either !!!!!!!!!!" << selstat << std::endl;}
02966           }
02967         }//
02968         
02969         
02970         Fill(h,"eff", 0.);
02971         if(simpv.size()==1){ Fill(h,"efftag", 0.); }
02972         
02973         Fill(h,"effvsptsq",vsim->ptsq,0.);
02974         Fill(h,"effvsnsimtrk",float(vsim->nGenTrk),0.);
02975         Fill(h,"effvsnrectrk",nrectrks,0.);
02976         Fill(h,"effvsnseltrk",nseltrks,0.);
02977         Fill(h,"effvsz",vsim->z*simUnit_,0.);
02978         Fill(h,"effvsr",sqrt(vsim->x*vsim->x+vsim->y*vsim->y)*simUnit_,0.);
02979         
02980       } // no recvertex for this simvertex
02981 
02982     }
02983 
02984     // end of sim/rec matching
02985    
02986      
02987    // purity of event vertex tags
02988     if (recVtxs->size()>0){
02989       Double_t dz=(*recVtxs->begin()).z() - (*simpv.begin()).z*simUnit_;
02990       Fill(h,"zdistancetag",dz);
02991       Fill(h,"abszdistancetag",fabs(dz));
02992       if( fabs(dz)<zmatch_){
02993         Fill(h,"puritytag",1.);
02994       }else{
02995         // bad tag: the true primary was more than 500 um (or zmatch) away from the tagged primary
02996         Fill(h,"puritytag",0.);
02997       }
02998     }
02999     
03000   }else{
03001     //if(verbose_) cout << "PrimaryVertexAnalyzer4PU::analyzeVertexCollection:  simPV is empty!" << endl;
03002   }
03003 
03004 
03005   //******* the following code does not require MC and will/should work for data **********
03006 
03007 
03008   Fill(h,"bunchCrossing",bunchCrossing_);
03009   if(recTrks->size()>0)  Fill(h,"bunchCrossingLogNtk",bunchCrossing_,log(recTrks->size())/log(10.));
03010   
03011   // -----------------  reconstructed tracks  ------------------------
03012   // the list of selected tracks can only be correct if the selection parameterset  and track collection
03013   // is the same that was used for the reconstruction
03014 
03015   int nt=0;
03016   for(reco::TrackCollection::const_iterator t=recTrks->begin();
03017       t!=recTrks->end(); ++t){
03018     if((recVtxs->size()>0) && (recVtxs->begin()->isValid())){
03019       fillTrackHistos(h,"all",*t,&(*recVtxs->begin()));
03020     }else{
03021       fillTrackHistos(h,"all",*t);
03022     }
03023     if(recTrks->size()>100)    fillTrackHistos(h,"M",*t);
03024 
03025 
03026 
03027     TransientTrack  tt = theB_->build(&(*t));  tt.setBeamSpot(vertexBeamSpot_);
03028     if  (theTrackFilter(tt)){
03029       selTrks.push_back(*t);
03030       fillTrackHistos(h,"sel",*t);
03031       int foundinvtx=0;
03032       int nvtemp=-1;
03033       for(reco::VertexCollection::const_iterator v=recVtxs->begin(); 
03034           v!=recVtxs->end(); ++v){
03035         nvtemp++;
03036         if(( v->isFake()) || (v->ndof()<-2) ) break;
03037         for(trackit_t tv=v->tracks_begin(); tv!=v->tracks_end(); tv++ ){
03038           if( ((**tv).vz()==t->vz()&&((**tv).phi()==t->phi())) ) {
03039             foundinvtx++;
03040           }
03041         }
03042         
03043       }
03044       if(foundinvtx==0){
03045         fillTrackHistos(h,"sellost",*t);
03046       }else if(foundinvtx>1){
03047         cout << "hmmmm " << foundinvtx << endl;
03048       }
03049     }
03050     nt++;
03051   }
03052 
03053 
03054   if (nseltrks<0){
03055     nseltrks=selTrks.size();
03056   }else if( ! (nseltrks==(int)selTrks.size()) ){
03057     std::cout << "Warning: inconsistent track selection !" << std::endl;
03058   }
03059 
03060 
03061 
03062   // fill track histograms of vertex tracks
03063   int nrec=0,  nrec0=0, nrec8=0, nrec2=0, nrec4=0;
03064   for(reco::VertexCollection::const_iterator v=recVtxs->begin(); 
03065       v!=recVtxs->end(); ++v){
03066     
03067     if (! (v->isFake()) && v->ndof()>0 && v->chi2()>0 ){
03068       nrec++;
03069       if (v->ndof()>0) nrec0++;
03070       if (v->ndof()>8) nrec8++;
03071       if (v->ndof()>2) nrec2++;
03072       if (v->ndof()>4) nrec4++;
03073       for(trackit_t t=v->tracks_begin(); t!=v->tracks_end(); t++){
03074         if(v==recVtxs->begin()){
03075           fillTrackHistos(h,"tagged",**t,  &(*v));
03076         }else{
03077           fillTrackHistos(h,"untagged",**t,  &(*v));
03078         }
03079 
03080         Float_t wt=v->trackWeight(*t);
03081         //dumpHitInfo(**t); cout << "  w=" << wt << endl;
03082         Fill(h,"trackWt",wt);
03083         if(wt>0.5){
03084           fillTrackHistos(h,"wgt05",**t, &(*v));
03085           if(v->ndof()>4) fillTrackHistos(h,"ndof4",**t, &(*v));
03086         }else{
03087           fillTrackHistos(h,"wlt05",**t, &(*v));
03088         }
03089       }
03090     }
03091   }
03092 
03093 
03094   // bachelor tracks (only available through clusters right now)
03095   for(unsigned int iclu=0; iclu<clusters.size(); iclu++){
03096     if (clusters[iclu].tracksSize()==1){
03097       for(trackit_t t = clusters[iclu].tracks_begin(); 
03098           t!=clusters[iclu].tracks_end(); t++){
03099         fillTrackHistos(h,"bachelor",**t);
03100       }
03101     }
03102   }
03103 
03104 
03105   // -----------------  reconstructed vertices  ------------------------
03106 
03107   // event 
03108   Fill(h,"szRecVtx",recVtxs->size());
03109   Fill(h,"nclu",clusters.size());
03110   Fill(h,"nseltrk",nseltrks);
03111   Fill(h,"nrectrk",nrectrks);
03112   Fill(h,"nrecvtx",nrec);
03113   Fill(h,"nrecvtx2",nrec2);
03114   Fill(h,"nrecvtx4",nrec4);
03115   Fill(h,"nrecvtx8",nrec8);
03116 
03117   if(nrec>0){
03118     Fill(h,"eff0vsntrec",nrectrks,1.);
03119     Fill(h,"eff0vsntsel",nseltrks,1.);
03120   }else{
03121     Fill(h,"eff0vsntrec",nrectrks,0.);
03122     Fill(h,"eff0vsntsel",nseltrks,0.);
03123     if((nseltrks>1)&&(verbose_)){
03124       cout << Form("PrimaryVertexAnalyzer4PU: %s may have lost a vertex  %10d  %10d     %4d / %4d ",message.c_str(),run_, event_, nrectrks,nseltrks) << endl;
03125       dumpThisEvent_=true;
03126     }
03127   }
03128   if(nrec0>0) { Fill(h,"eff0ndof0vsntsel",nseltrks,1.);}else{ Fill(h,"eff0ndof0vsntsel",nseltrks,0.);}
03129   if(nrec2>0) { Fill(h,"eff0ndof2vsntsel",nseltrks,1.);}else{ Fill(h,"eff0ndof2vsntsel",nseltrks,0.);}
03130   if(nrec4>0) { Fill(h,"eff0ndof4vsntsel",nseltrks,1.);}else{ Fill(h,"eff0ndof4vsntsel",nseltrks,0.);}
03131   if(nrec8>0) { Fill(h,"eff0ndof8vsntsel",nseltrks,1.);}else{ Fill(h,"eff0ndof8vsntsel",nseltrks,0.);}
03132 
03133   if((nrec>1)&&(DEBUG_)) {
03134     cout << "multivertex event" << endl;
03135     dumpThisEvent_=true;
03136   }
03137 
03138   if((nrectrks>10)&&(nseltrks<3)){
03139     cout << "small fraction of selected tracks "  << endl;
03140     dumpThisEvent_=true;
03141   }
03142 
03143   // properties of events without a vertex
03144   if((nrec==0)||(recVtxs->begin()->isFake())){
03145     Fill(h,"nrectrk0vtx",nrectrks);
03146     Fill(h,"nseltrk0vtx",nseltrks);
03147     Fill(h,"nclu0vtx",clusters.size());
03148   }
03149 
03150 
03151   //  properties of (valid) vertices
03152   double ndof2=-10,ndof1=-10, zndof1=0, zndof2=0;
03153   for(reco::VertexCollection::const_iterator v=recVtxs->begin(); 
03154       v!=recVtxs->end(); ++v){
03155     if(v->isFake()){ Fill(h,"isFake",1.);}else{ Fill(h,"isFake",0.);}
03156     if(v->isFake()||((v->ndof()<0)&&(v->ndof()>-3))){ Fill(h,"isFake1",1.);}else{ Fill(h,"isFake1",0.);}
03157 
03158     if((v->isFake())||(v->ndof()<0)) continue;
03159     if(v->ndof()>ndof1){ ndof2=ndof1; zndof2=zndof1; ndof1=v->ndof(); zndof1=v->position().z();}
03160     else if(v->ndof()>ndof2){ ndof2=v->ndof(); zndof2=v->position().z();}
03161 
03162 
03163     // some special histogram for two track vertices
03164     if(v->tracksSize()==2){
03165       const TrackBaseRef& t1= *(v->tracks_begin());
03166       const TrackBaseRef& t2=*(v->tracks_begin()+1);
03167       bool os=(t1->charge()*t2->charge()<0);
03168       double dphi=t1->phi()-t2->phi(); if (dphi<0) dphi+=2*M_PI;
03169       double m12=sqrt(pow( sqrt(pow(0.139,2)+pow( t1->p(),2)) +sqrt(pow(0.139,2)+pow( t2->p(),2)) ,2)
03170                              -pow(t1->px()+t2->px(),2)
03171                              -pow(t1->py()+t2->py(),2)
03172                              -pow(t1->pz()+t2->pz(),2)
03173                     );
03174       if(os){
03175         Fill(h,"2trkdetaOS",t1->eta()-t2->eta());
03176         Fill(h,"2trkmassOS",m12);
03177       }else{
03178         Fill(h,"2trkdetaSS",t1->eta()-t2->eta());
03179         Fill(h,"2trkmassSS",m12);
03180       }
03181       Fill(h,"2trkdphi",dphi);
03182       Fill(h,"2trkseta",t1->eta()+t2->eta());
03183       if(fabs(dphi-M_PI)<0.1)      Fill(h,"2trksetacurl",t1->eta()+t2->eta());
03184       if(fabs(t1->eta()+t2->eta())<0.1) Fill(h,"2trkdphicurl",dphi);
03185       // fill separately for extra vertices
03186       if(v!=recVtxs->begin()){
03187         if(os){
03188           Fill(h,"2trkdetaOSPU",t1->eta()-t2->eta());
03189           Fill(h,"2trkmassOSPU",m12);
03190         }else{
03191           Fill(h,"2trkdetaSSPU",t1->eta()-t2->eta());
03192           Fill(h,"2trkmassSSPU",m12);
03193         }
03194         Fill(h,"2trkdphiPU",dphi);
03195         Fill(h,"2trksetaPU",t1->eta()+t2->eta());
03196         if(fabs(dphi-M_PI)<0.1)      Fill(h,"2trksetacurlPU",t1->eta()+t2->eta());
03197         if(fabs(t1->eta()+t2->eta())<0.1) Fill(h,"2trkdphicurlPU",dphi);
03198       }
03199     }
03200 
03201 
03202     Fill(h,"trkchi2vsndof",v->ndof(),v->chi2());
03203     if(v->ndof()>0){    Fill(h,"trkchi2overndof",v->chi2()/v->ndof()); }
03204     if(v->tracksSize()==2){  Fill(h,"2trkchi2vsndof",v->ndof(),v->chi2());   }
03205     if(v->tracksSize()==3){  Fill(h,"3trkchi2vsndof",v->ndof(),v->chi2());   }
03206     if(v->tracksSize()==4){  Fill(h,"4trkchi2vsndof",v->ndof(),v->chi2());   }
03207     if(v->tracksSize()==5){  Fill(h,"5trkchi2vsndof",v->ndof(),v->chi2());   }
03208 
03209     Fill(h,"nbtksinvtx",v->tracksSize());
03210     Fill(h,"nbtksinvtx2",v->tracksSize());
03211     Fill(h,"vtxchi2",v->chi2());
03212     Fill(h,"vtxndf",v->ndof());
03213     Fill(h,"vtxprob",ChiSquaredProbability(v->chi2() ,v->ndof()));
03214     Fill(h,"vtxndfvsntk",v->tracksSize(), v->ndof());
03215     Fill(h,"vtxndfoverntk",v->ndof()/v->tracksSize());
03216     Fill(h,"vtxndf2overntk",(v->ndof()+2)/v->tracksSize());
03217     Fill(h,"zrecvsnt",v->position().z(),float(nrectrks));
03218     if(nrectrks>100){
03219       Fill(h,"zrecNt100",v->position().z());
03220     }
03221 
03222     if(v->ndof()>2.0){  // enter only vertices that really contain tracks
03223       Fill(h,"xrec",v->position().x());
03224       Fill(h,"yrec",v->position().y());
03225       Fill(h,"zrec",v->position().z());
03226       Fill(h,"xrec1",v->position().x());
03227       Fill(h,"yrec1",v->position().y());
03228       Fill(h,"zrec1",v->position().z());
03229       Fill(h,"xrec2",v->position().x());
03230       Fill(h,"yrec2",v->position().y());
03231       Fill(h,"zrec2",v->position().z());
03232       Fill(h,"xrec3",v->position().x());
03233       Fill(h,"yrec3",v->position().y());
03234       Fill(h,"zrec3",v->position().z());
03235       Fill(h,"xrecb",v->position().x()-vertexBeamSpot_.x0());
03236       Fill(h,"yrecb",v->position().y()-vertexBeamSpot_.y0());
03237       Fill(h,"zrecb",v->position().z()-vertexBeamSpot_.z0());
03238       Fill(h,"xrecBeam",v->position().x()-vertexBeamSpot_.x0());
03239       Fill(h,"yrecBeam",v->position().y()-vertexBeamSpot_.y0());
03240       Fill(h,"zrecBeam",v->position().z()-vertexBeamSpot_.z0());
03241       Fill(h,"xrecBeamPull",(v->position().x()-vertexBeamSpot_.x0())/sqrt(pow(v->xError(),2)+pow(vertexBeamSpot_.BeamWidthX(),2)));
03242       Fill(h,"yrecBeamPull",(v->position().y()-vertexBeamSpot_.y0())/sqrt(pow(v->yError(),2)+pow(vertexBeamSpot_.BeamWidthY(),2)));
03243       
03244       Fill(h,"xrecBeamvsdx",v->xError(),v->position().x()-vertexBeamSpot_.x0());
03245       Fill(h,"yrecBeamvsdy",v->yError(),v->position().y()-vertexBeamSpot_.y0());
03246       Fill(h,"xrecBeamvsdxR2",v->position().x()-vertexBeamSpot_.x0(),v->xError());
03247       Fill(h,"yrecBeamvsdyR2",v->position().y()-vertexBeamSpot_.y0(),v->yError());
03248       Fill(h,"xrecBeam2vsdx2prof",pow(v->xError(),2),pow(v->position().x()-vertexBeamSpot_.x0(),2));
03249       Fill(h,"yrecBeam2vsdy2prof",pow(v->yError(),2),pow(v->position().y()-vertexBeamSpot_.y0(),2));
03250       Fill(h,"xrecBeamvsdx2",pow(v->xError(),2),pow(v->position().x()-vertexBeamSpot_.x0(),2));
03251       Fill(h,"yrecBeamvsdy2",pow(v->yError(),2),pow(v->position().y()-vertexBeamSpot_.y0(),2));
03252       Fill(h,"xrecBeamvsz",v->position().z(),v->position().x()-vertexBeamSpot_.x0());
03253       Fill(h,"yrecBeamvsz",v->position().z(),v->position().y()-vertexBeamSpot_.y0());
03254       Fill(h,"xrecBeamvszprof",v->position().z(),v->position().x()-vertexBeamSpot_.x0());
03255       Fill(h,"yrecBeamvszprof",v->position().z(),v->position().y()-vertexBeamSpot_.y0());
03256       Fill(h,"xrecBeamvsdxprof",v->xError(),v->position().x()-vertexBeamSpot_.x0());
03257       Fill(h,"yrecBeamvsdyprof",v->yError(),v->position().y()-vertexBeamSpot_.y0());
03258       
03259       
03260       Fill(h,"errx",v->xError());
03261       Fill(h,"erry",v->yError());
03262       Fill(h,"errz",v->zError());
03263       double vxx=v->covariance(0,0);
03264       double vyy=v->covariance(1,1);
03265       double vxy=v->covariance(1,0);
03266       double dv=0.25*(vxx+vyy)*(vxx+vyy-(vxx*vyy-vxy*vxy));
03267       if(dv>0){
03268         double l1=0.5*(vxx+vyy)+sqrt(dv);
03269         Fill(h,"err1",sqrt(l1));
03270         double l2=sqrt(0.5*(vxx+vyy)-sqrt(dv));
03271         if(l2>0) Fill(h,"err2",sqrt(l2));
03272       }
03273       
03274       
03275       // look at the tagged vertex separately
03276       if (v==recVtxs->begin()){
03277         Fill(h,"nbtksinvtxTag",v->tracksSize());
03278         Fill(h,"nbtksinvtxTag2",v->tracksSize());
03279         Fill(h,"xrectag",v->position().x());
03280         Fill(h,"yrectag",v->position().y());
03281         Fill(h,"zrectag",v->position().z());
03282       }else{
03283         Fill(h,"nbtksinvtxPU",v->tracksSize());
03284         Fill(h,"nbtksinvtxPU2",v->tracksSize());
03285       }
03286         
03287       // vertex resolution vs number of tracks
03288       Fill(h,"xresvsntrk",v->tracksSize(),v->xError());
03289       Fill(h,"yresvsntrk",v->tracksSize(),v->yError());
03290       Fill(h,"zresvsntrk",v->tracksSize(),v->zError());
03291       
03292     }
03293     
03294     // cluster properties (if available)
03295     for(unsigned int iclu=0; iclu<clusters.size(); iclu++){
03296       if( fabs(clusters[iclu].position().z()-v->position().z()) < 0.0001 ){
03297         Fill(h,"nclutrkvtx",clusters[iclu].tracksSize());
03298       }
03299     }
03300     
03301 
03302         
03303     //  properties of (valid) neighbour vertices
03304     reco::VertexCollection::const_iterator v1=v;     v1++;
03305     for(; v1!=recVtxs->end(); ++v1){
03306       if((v1->isFake())||(v1->ndof()<0)) continue;
03307       Fill(h,"zdiffrec",v->position().z()-v1->position().z());
03308 //       if(fabs(v->position().z()-v1->position().z())>1){
03309 //      cout << message << " zdiffrec=" << v->position().z()-v1->position().z() << " " << v->ndof() << " " << v1->ndof() << endl;
03310 //      dumpThisEvent_=true;
03311 //       }
03312 
03313       double z0=v->position().z()-vertexBeamSpot_.z0();
03314       double z1=v1->position().z()-vertexBeamSpot_.z0();
03315       Fill(h,"zPUcand",z0);     Fill(h,"zPUcand",z1);
03316       Fill(h,"ndofPUcand",v->ndof()); Fill(h,"ndofPUcand",v1->ndof());
03317       
03318       Fill(h,"zdiffvsz",z1-z0,0.5*(z1+z0));
03319 
03320       if ((v->ndof()>2) && (v1->ndof()>2)){
03321         Fill(h,"zdiffrec2",v->position().z()-v1->position().z());
03322         Fill(h,"zPUcand2",z0);
03323         Fill(h,"zPUcand2",z1);
03324         Fill(h,"ndofPUcand2",v->ndof());
03325         Fill(h,"ndofPUcand2",v1->ndof());
03326         Fill(h,"zvszrec2",z0, z1);
03327         Fill(h,"pzvspz2",TMath::Freq(z0/2.16),TMath::Freq(z1/2.16) );
03328       }
03329       
03330       if ((v->ndof()>4) && (v1->ndof()>4)){
03331         Fill(h,"zdiffvsz4",z1-z0,0.5*(z1+z0));
03332         Fill(h,"zdiffrec4",v->position().z()-v1->position().z());
03333         Fill(h,"zvszrec4",z0, z1);
03334         Fill(h,"pzvspz4",TMath::Freq(z0/2.16),TMath::Freq(z1/2.16) );
03335         //cout << "ndof4 pu-candidate " << run_ << " " << event_ << endl ;
03336         if(fabs(z0-z1)>1.0){
03337           Fill(h,"xbeamPUcand",v->position().x()-vertexBeamSpot_.x0());
03338           Fill(h,"ybeamPUcand",v->position().y()-vertexBeamSpot_.y0());
03339           Fill(h,"xbeamPullPUcand",(v->position().x()-vertexBeamSpot_.x0())/v->xError());
03340           Fill(h,"ybeamPullPUcand",(v->position().y()-vertexBeamSpot_.y0())/v->yError());
03341           //Fill(h,"sumwOverNtkPUcand",sumw/v->tracksSize());
03342           //Fill(h,"sumwOverNtkPUcand",sumw/v1->tracksSize());
03343           Fill(h,"ndofOverNtkPUcand",v->ndof()/v->tracksSize());
03344           Fill(h,"ndofOverNtkPUcand",v1->ndof()/v1->tracksSize());
03345           Fill(h,"xbeamPUcand",v1->position().x()-vertexBeamSpot_.x0());
03346           Fill(h,"ybeamPUcand",v1->position().y()-vertexBeamSpot_.y0());
03347           Fill(h,"xbeamPullPUcand",(v1->position().x()-vertexBeamSpot_.x0())/v1->xError());
03348           Fill(h,"ybeamPullPUcand",(v1->position().y()-vertexBeamSpot_.y0())/v1->yError());
03349           Fill(h,"zPUcand4",z0);
03350           Fill(h,"zPUcand4",z1);
03351           Fill(h,"ndofPUcand4",v->ndof());
03352           Fill(h,"ndofPUcand4",v1->ndof());
03353           for(trackit_t t=v->tracks_begin(); t!=v->tracks_end(); t++){ if(v->trackWeight(*t)>0.5) fillTrackHistos(h,"PUcand",**t, &(*v));  }
03354           for(trackit_t t=v1->tracks_begin(); t!=v1->tracks_end(); t++){ if(v1->trackWeight(*t)>0.5) fillTrackHistos(h,"PUcand",**t, &(*v1));   }
03355         }
03356         }
03357       
03358       if ((v->ndof()>4) && (v1->ndof()>2) && (v1->ndof()<4)){
03359         for(trackit_t t=v1->tracks_begin(); t!=v1->tracks_end(); t++){ if(v1->trackWeight(*t)>0.5) fillTrackHistos(h,"PUfake",**t, &(*v1));   }
03360       }
03361       
03362       if ((v->ndof()>8) && (v1->ndof()>8)){
03363         Fill(h,"zdiffrec8",v->position().z()-v1->position().z());
03364         if(dumpPUcandidates_ && fabs(z0-z1)>1.0){
03365           cout << "PU candidate " << run_ << " " << event_ << " " << message <<  " zdiff=" <<z0-z1 << endl;
03366 //      cerr << "PU candidate " << run_ << " "<<  event_ << " " << message <<  endl;
03367           dumpThisEvent_=true;
03368         }
03369       }
03370 
03371     }
03372     
03373     // test track links, use reconstructed vertices
03374       bool problem = false;
03375       Fill(h,"nans",1.,std::isnan(v->position().x())*1.);
03376       Fill(h,"nans",2.,std::isnan(v->position().y())*1.);
03377       Fill(h,"nans",3.,std::isnan(v->position().z())*1.);
03378       
03379       int index = 3;
03380       for (int i = 0; i != 3; i++) {
03381         for (int j = i; j != 3; j++) {
03382           index++;
03383           Fill(h,"nans",index*1., std::isnan(v->covariance(i, j))*1.);
03384           if (std::isnan(v->covariance(i, j))) problem = true;
03385           // in addition, diagonal element must be positive
03386           if (j == i && v->covariance(i, j) < 0) {
03387             Fill(h,"nans",index*1., 1.);
03388             problem = true;
03389           }
03390         }
03391       }
03392       
03393       try {
03394         for(trackit_t t = v->tracks_begin(); 
03395             t!=v->tracks_end(); t++) {
03396           // illegal charge
03397           if ( (**t).charge() < -1 || (**t).charge() > 1 ) {
03398             Fill(h,"tklinks",0.);
03399           }
03400           else {
03401             Fill(h,"tklinks",1.);
03402           }
03403         }
03404       } catch (...) {
03405         // exception thrown when trying to use linked track
03406         Fill(h,"tklinks",0.);
03407       }
03408 
03409       if (problem) {
03410         // analyze track parameter covariance definiteness
03411         double data[25];
03412         try {
03413           int itk = 0;
03414           for(trackit_t t = v->tracks_begin(); 
03415               t!=v->tracks_end(); t++) {
03416             std::cout << "Track " << itk++ << std::endl;
03417             int i2 = 0;
03418             for (int i = 0; i != 5; i++) {
03419               for (int j = 0; j != 5; j++) {
03420                 data[i2] = (**t).covariance(i, j);
03421                 std::cout << std:: scientific << data[i2] << " ";
03422                 i2++;
03423               }
03424               std::cout << std::endl;
03425             }
03426             gsl_matrix_view m 
03427               = gsl_matrix_view_array (data, 5, 5);
03428             
03429             gsl_vector *eval = gsl_vector_alloc (5);
03430             gsl_matrix *evec = gsl_matrix_alloc (5, 5);
03431             
03432             gsl_eigen_symmv_workspace * w = 
03433               gsl_eigen_symmv_alloc (5);
03434             
03435             gsl_eigen_symmv (&m.matrix, eval, evec, w);
03436             
03437             gsl_eigen_symmv_free (w);
03438             
03439             gsl_eigen_symmv_sort (eval, evec, 
03440                                   GSL_EIGEN_SORT_ABS_ASC);
03441             
03442             // print sorted eigenvalues
03443           {
03444             int i;
03445             for (i = 0; i < 5; i++) {
03446               double eval_i 
03447                 = gsl_vector_get (eval, i);
03448               //gsl_vector_view evec_i 
03449               //        = gsl_matrix_column (evec, i);
03450               
03451               printf ("eigenvalue = %g\n", eval_i);
03452               //              printf ("eigenvector = \n");
03453               //              gsl_vector_fprintf (stdout, 
03454               //                                  &evec_i.vector, "%g");
03455             }
03456           }
03457           }
03458         }
03459       catch (...) {
03460         // exception thrown when trying to use linked track
03461         break;
03462       }// catch()
03463       }// if (problem)
03464 
03465 
03466     
03467   }  // vertex loop (v)
03468 
03469 
03470   // 2nd highest ndof
03471   if (ndof2>0){
03472       Fill(h,"ndofnr2",ndof2); 
03473       if(fabs(zndof1-zndof2)>1) Fill(h,"ndofnr2d1cm",ndof2); 
03474       if(fabs(zndof1-zndof2)>2) Fill(h,"ndofnr2d2cm",ndof2); 
03475   }
03476 
03477 
03478 }
03479