File indexing completed on 2024-09-07 04:37:53
0001 #include "CommonTools/Statistics/interface/ChiSquaredProbability.h"
0002 #include "DataFormats/Common/interface/RefToBase.h"
0003 #include "DataFormats/ParticleFlowReco/interface/PFConversion.h"
0004 #include "DataFormats/VertexReco/interface/Vertex.h"
0005 #include "FWCore/Framework/interface/ESHandle.h"
0006 #include "FWCore/Framework/interface/Event.h"
0007 #include "FWCore/Framework/interface/stream/EDProducer.h"
0008 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0009 #include "MagneticField/Engine/interface/MagneticField.h"
0010 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0011 #include "RecoParticleFlow/PFTracking/interface/PFTrackTransformer.h"
0012 #include "TrackingTools/IPTools/interface/IPTools.h"
0013 #include "TrackingTools/PatternTools/interface/Trajectory.h"
0014 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
0015 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
0016
0017 class PFConversionProducer : public edm::stream::EDProducer<> {
0018 public:
0019
0020 explicit PFConversionProducer(const edm::ParameterSet&);
0021
0022
0023 ~PFConversionProducer() override;
0024
0025 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0026
0027 private:
0028 void beginRun(const edm::Run&, const edm::EventSetup&) override;
0029 void endRun(const edm::Run&, const edm::EventSetup&) override;
0030
0031
0032 void produce(edm::Event&, const edm::EventSetup&) override;
0033
0034
0035 PFTrackTransformer* pfTransformer_;
0036 edm::EDGetTokenT<reco::ConversionCollection> pfConversionContainer_;
0037 edm::EDGetTokenT<reco::VertexCollection> vtx_h;
0038
0039 const edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> transientTrackToken_;
0040 const edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> magneticFieldToken_;
0041 };
0042
0043 #include "FWCore/Framework/interface/MakerMacros.h"
0044 DEFINE_FWK_MODULE(PFConversionProducer);
0045
0046 void PFConversionProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0047 edm::ParameterSetDescription desc;
0048 desc.add<edm::InputTag>("conversionCollection", {"allConversions", ""});
0049 desc.add<edm::InputTag>("PrimaryVertexLabel", {"offlinePrimaryVertices"});
0050 descriptions.add("pfConversions", desc);
0051 }
0052
0053 typedef std::multimap<unsigned, std::vector<unsigned> > BlockMap;
0054 using namespace std;
0055 using namespace edm;
0056
0057 PFConversionProducer::PFConversionProducer(const ParameterSet& iConfig)
0058 : pfTransformer_(nullptr),
0059 transientTrackToken_(esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))),
0060 magneticFieldToken_(esConsumes<edm::Transition::BeginRun>()) {
0061 produces<reco::PFRecTrackCollection>();
0062 produces<reco::PFConversionCollection>();
0063
0064 pfConversionContainer_ = consumes<reco::ConversionCollection>(iConfig.getParameter<InputTag>("conversionCollection"));
0065
0066 vtx_h = consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("PrimaryVertexLabel"));
0067 }
0068
0069 PFConversionProducer::~PFConversionProducer() { delete pfTransformer_; }
0070
0071 void PFConversionProducer::produce(Event& iEvent, const EventSetup& iSetup) {
0072
0073 auto pfConversionColl = std::make_unique<reco::PFConversionCollection>();
0074 auto pfRecTrackColl = std::make_unique<reco::PFRecTrackCollection>();
0075
0076 TransientTrackBuilder const& thebuilder = iSetup.getData(transientTrackToken_);
0077
0078 reco::PFRecTrackRefProd pfTrackRefProd = iEvent.getRefBeforePut<reco::PFRecTrackCollection>();
0079 Handle<reco::ConversionCollection> convCollH;
0080 iEvent.getByToken(pfConversionContainer_, convCollH);
0081
0082 const reco::ConversionCollection& convColl = *(convCollH.product());
0083
0084 Handle<reco::VertexCollection> vertex;
0085 iEvent.getByToken(vtx_h, vertex);
0086
0087 reco::Vertex dummy;
0088 const reco::Vertex* pv = &dummy;
0089 if (vertex.isValid()) {
0090 pv = &*vertex->begin();
0091 } else {
0092 reco::Vertex::Error e;
0093 e(0, 0) = 0.0015 * 0.0015;
0094 e(1, 1) = 0.0015 * 0.0015;
0095 e(2, 2) = 15. * 15.;
0096 reco::Vertex::Point p(0, 0, 0);
0097 dummy = reco::Vertex(p, e, 0, 0, 0);
0098 }
0099
0100 int idx = 0;
0101 multimap<unsigned int, unsigned int> trackmap;
0102 std::vector<unsigned int> conv_coll(0);
0103
0104
0105 for (unsigned int icoll1 = 0; icoll1 < convColl.size(); icoll1++) {
0106 if ((!convColl[icoll1].quality(reco::Conversion::arbitratedMergedEcalGeneral)) ||
0107 (!convColl[icoll1].quality(reco::Conversion::highPurity)))
0108 continue;
0109
0110 bool greater_prob = false;
0111 std::vector<edm::RefToBase<reco::Track> > tracksRefColl1 = convColl[icoll1].tracks();
0112 for (unsigned it1 = 0; it1 < tracksRefColl1.size(); it1++) {
0113 reco::TrackRef trackRef1 = (tracksRefColl1[it1]).castTo<reco::TrackRef>();
0114
0115 for (unsigned int icoll2 = 0; icoll2 < convColl.size(); icoll2++) {
0116 if (icoll1 == icoll2)
0117 continue;
0118 if ((!convColl[icoll2].quality(reco::Conversion::arbitratedMergedEcalGeneral)) ||
0119 (!convColl[icoll2].quality(reco::Conversion::highPurity)))
0120 continue;
0121 std::vector<edm::RefToBase<reco::Track> > tracksRefColl2 = convColl[icoll2].tracks();
0122 for (unsigned it2 = 0; it2 < tracksRefColl2.size(); it2++) {
0123 reco::TrackRef trackRef2 = (tracksRefColl2[it2]).castTo<reco::TrackRef>();
0124 double like1 = -999;
0125 double like2 = -999;
0126
0127 int shared = 0;
0128 for (auto const& hit1 : trackRef1->recHits())
0129 if (hit1->isValid()) {
0130
0131 for (auto const& hit2 : trackRef2->recHits()) {
0132 if (hit2->isValid() && hit1->sharesInput(hit2, TrackingRecHit::some))
0133 shared++;
0134 }
0135 }
0136 float frac = 0;
0137
0138 float size1 = trackRef1->found();
0139 float size2 = trackRef2->found();
0140
0141 if (size1 > size2)
0142 frac = (double)shared / size2;
0143 else
0144 frac = (double)shared / size1;
0145 if (frac > 0.9) {
0146 like1 = ChiSquaredProbability(convColl[icoll1].conversionVertex().chi2(),
0147 convColl[icoll1].conversionVertex().ndof());
0148 like2 = ChiSquaredProbability(convColl[icoll2].conversionVertex().chi2(),
0149 convColl[icoll2].conversionVertex().ndof());
0150 }
0151 if (like2 > like1) {
0152 greater_prob = true;
0153 break;
0154 }
0155 }
0156
0157 if (greater_prob)
0158 break;
0159 }
0160 if (greater_prob)
0161 break;
0162 }
0163 if (!greater_prob)
0164 conv_coll.push_back(icoll1);
0165 }
0166
0167
0168 for (unsigned iColl = 0; iColl < conv_coll.size(); iColl++) {
0169 unsigned int collindex = conv_coll[iColl];
0170
0171 std::vector<reco::PFRecTrackRef> pfRecTkcoll;
0172
0173 std::vector<edm::RefToBase<reco::Track> > tracksRefColl = convColl[collindex].tracks();
0174
0175 for (unsigned it = 0; it < tracksRefColl.size(); it++) {
0176 reco::TrackRef trackRef = (tracksRefColl[it]).castTo<reco::TrackRef>();
0177 reco::PFRecTrack pfRecTrack(trackRef->charge(), reco::PFRecTrack::KF, trackRef.key(), trackRef);
0178
0179 Trajectory FakeTraj;
0180 bool valid = pfTransformer_->addPoints(pfRecTrack, *trackRef, FakeTraj);
0181 if (valid) {
0182 double stip = -999;
0183 const reco::PFTrajectoryPoint& atECAL = pfRecTrack.extrapolatedPoint(reco::PFTrajectoryPoint::ECALEntrance);
0184
0185 if (atECAL.isValid()) {
0186 GlobalVector direction(pfRecTrack.extrapolatedPoint(reco::PFTrajectoryPoint::ECALEntrance).position().x(),
0187 pfRecTrack.extrapolatedPoint(reco::PFTrajectoryPoint::ECALEntrance).position().y(),
0188 pfRecTrack.extrapolatedPoint(reco::PFTrajectoryPoint::ECALEntrance).position().z());
0189 stip = IPTools::signedTransverseImpactParameter(thebuilder.build(*trackRef), direction, *pv)
0190 .second.significance();
0191 }
0192 pfRecTrack.setSTIP(stip);
0193 pfRecTkcoll.push_back(reco::PFRecTrackRef(pfTrackRefProd, idx++));
0194 pfRecTrackColl->push_back(pfRecTrack);
0195 }
0196 }
0197
0198 reco::ConversionRef niRef(convCollH, collindex);
0199 pfConversionColl->push_back(reco::PFConversion(niRef, pfRecTkcoll));
0200 }
0201 iEvent.put(std::move(pfRecTrackColl));
0202 iEvent.put(std::move(pfConversionColl));
0203 }
0204
0205
0206 void PFConversionProducer::beginRun(const edm::Run& run, const EventSetup& iSetup) {
0207 auto const& magneticField = &iSetup.getData(magneticFieldToken_);
0208 pfTransformer_ = new PFTrackTransformer(math::XYZVector(magneticField->inTesla(GlobalPoint(0, 0, 0))));
0209 pfTransformer_->OnlyProp();
0210 }
0211
0212
0213 void PFConversionProducer::endRun(const edm::Run& run, const EventSetup& iSetup) {
0214 delete pfTransformer_;
0215 pfTransformer_ = nullptr;
0216 }