49 return (Ref_L1A->pt() > Ref_L1B->pt());
57 if (Ref_L1A->hwQual() > Ref_L1B->hwQual())
59 if (Ref_L1A->hwQual() < Ref_L1B->hwQual())
63 return (Ref_L1A->pt() > Ref_L1B->pt());
69 theL1GMTReadoutCollection(iConfig.getParameter<
InputTag>(
"GMTReadoutCollection")),
71 theL1MinPt(iConfig.getParameter<double>(
"L1MinPt")),
72 theL1MaxEta(iConfig.getParameter<double>(
"L1MaxEta")),
73 theL1MinQuality(iConfig.getParameter<unsigned
int>(
"L1MinQuality")),
74 theMinPtBarrel(iConfig.getParameter<double>(
"SetMinPtBarrelTo")),
75 theMinPtEndcap(iConfig.getParameter<double>(
"SetMinPtEndcapTo")),
76 useOfflineSeed(iConfig.getUntrackedParameter<
bool>(
"UseOfflineSeed",
false)),
77 useUnassociatedL1(iConfig.getParameter<
bool>(
"UseUnassociatedL1")),
78 matchingDR(iConfig.getParameter<
std::vector<double>>(
"MatchDR")),
79 etaBins(iConfig.getParameter<
std::vector<double>>(
"EtaMatchingBins")),
80 centralBxOnly_(iConfig.getParameter<
bool>(
"CentralBxOnly")),
81 matchType(iConfig.getParameter<unsigned
int>(
"MatchType")),
82 sortType(iConfig.getParameter<unsigned
int>(
"SortType")) {
92 <<
"does not match number of eta bins." << endl;
97 throw cms::Exception(
"Configuration") <<
"Wrong MatchType or SortType" << endl;
109 produces<L2MuonTrajectorySeedCollection>();
124 desc.
add<
string>(
"Propagator",
"");
125 desc.
add<
double>(
"L1MinPt", -1.);
126 desc.
add<
double>(
"L1MaxEta", 5.0);
127 desc.
add<
unsigned int>(
"L1MinQuality", 0);
128 desc.
add<
double>(
"SetMinPtBarrelTo", 3.5);
129 desc.
add<
double>(
"SetMinPtEndcapTo", 1.0);
131 desc.
add<
bool>(
"UseUnassociatedL1",
true);
132 desc.
add<std::vector<double>>(
"MatchDR", {0.3});
133 desc.
add<std::vector<double>>(
"EtaMatchingBins", {0., 2.5});
134 desc.
add<
bool>(
"CentralBxOnly",
true);
135 desc.
add<
unsigned int>(
"MatchType", 0)
137 "MatchType : 0 Old matching, 1 L1 Order(1to1), 2 Min dR(1to1), 3 Higher Q(1to1), 4 All matched L1");
138 desc.
add<
unsigned int>(
"SortType", 0)->setComment(
"SortType : 0 not sort, 1 Pt, 2 Q and Pt");
142 psd0.
addUntracked<std::vector<std::string>>(
"Propagators", {
"SteppingHelixPropagatorAny"});
143 psd0.add<
bool>(
"RPCLayers",
true);
144 psd0.addUntracked<
bool>(
"UseMuonNavigation",
true);
146 descriptions.
add(
"L2MuonSeedGeneratorFromL1T", desc);
153 auto output = std::make_unique<L2MuonTrajectorySeedCollection>();
157 LogDebug(metname) <<
"Number of muons " << muColl->size() << endl;
162 vector<int> offlineSeedMap;
165 LogDebug(metname) <<
"Number of offline seeds " << offlineSeedHandle->size() << endl;
166 offlineSeedMap = vector<int>(offlineSeedHandle->size(), 0);
169 for (
int ibx = muColl->getFirstBX(); ibx <= muColl->getLastBX(); ++ibx) {
172 for (
auto it = muColl->begin(ibx); it != muColl->end(ibx); it++) {
173 unsigned int quality = it->hwQual();
174 int valid_charge = it->hwChargeValid();
177 float eta = it->eta();
179 float phi = it->phi();
180 int charge = it->charge();
187 int link = 36 + (
int)(it->tfMuonIndex() / 3.);
189 if ((link >= 36 && link <= 41) || (link >= 66 && link <= 71))
195 LogDebug(metname) <<
"New L2 Muon Seed";
196 LogDebug(metname) <<
"Pt = " << pt <<
" GeV/c";
198 LogDebug(metname) <<
"theta = " << theta <<
" rad";
199 LogDebug(metname) <<
"phi = " << phi <<
" rad";
213 CLHEP::Hep3Vector vec(0., 1., 0.);
220 LogDebug(metname) <<
"The seed is in the barrel";
224 detLayer =
theService->detLayerGeometry()->idToLayer(theid);
230 radius = fabs(bc->radius() /
sin(theta));
237 LogDebug(metname) <<
"The seed is in the endcap";
242 detLayer =
theService->detLayerGeometry()->idToLayer(theid);
260 mat[0][0] = (0.25 /
pt) * (0.25 / pt);
262 mat[0][0] = (0.4 /
pt) * (0.4 / pt);
266 mat[0][0] = (1. /
pt) * (1. / pt);
268 mat[1][1] = 0.05 * 0.05;
269 mat[2][2] = 0.2 * 0.2;
270 mat[3][3] = 20. * 20.;
271 mat[4][4] = 20. * 20.;
277 LogDebug(metname) <<
"Free trajectory State from the parameters";
284 LogDebug(metname) <<
"State after the propagation on the layer";
289 if (fabs(eta) <
etaBins.back()) {
290 std::vector<double>::iterator lowEdge = std::upper_bound(
etaBins.begin(),
etaBins.end(), fabs(eta));
301 if (assoOffseed !=
nullptr) {
304 for (; tsci != tscie; ++tsci) {
325 std::vector<pair<const GeomDet *, TrajectoryStateOnSurface>> detsWithStates =
328 if (detsWithStates.empty() &&
barrel) {
339 if (!detsWithStates.empty()) {
341 const GeomDet *newTSOSDet = detsWithStates.front().first;
343 LogDebug(metname) <<
"Most compatible det";
357 if (assoOffseed !=
nullptr) {
360 tscie = assoOffseed->
recHits().second;
361 for (; tsci != tscie; ++tsci) {
397 unsigned int nMuColl = muColl->size();
399 vector<vector<double>> dRmtx;
400 vector<vector<const TrajectorySeed *>> selOffseeds;
405 unsigned int nOfflineSeed = offlineSeedHandle->size();
406 LogDebug(metname) <<
"Number of offline seeds " << nOfflineSeed << endl;
409 dRmtx = vector<vector<double>>(nMuColl, vector<double>(nOfflineSeed, 999.0));
411 vector<vector<const TrajectorySeed *>>(nMuColl, vector<const TrajectorySeed *>(nOfflineSeed,
nullptr));
418 for (
int ibx = muColl->getFirstBX(); ibx <= muColl->getLastBX(); ++ibx) {
421 for (
auto it = muColl->begin(ibx); it != muColl->end(ibx); it++) {
423 unsigned int imu =
distance(muColl->begin(muColl->getFirstBX()), it);
425 unsigned int quality = it->hwQual();
426 int valid_charge = it->hwChargeValid();
429 float eta = it->eta();
431 float phi = it->phi();
432 int charge = it->charge();
439 int link = 36 + (
int)(it->tfMuonIndex() / 3.);
441 if ((link >= 36 && link <= 41) || (link >= 66 && link <= 71))
447 LogDebug(metname) <<
"New L2 Muon Seed";
448 LogDebug(metname) <<
"Pt = " << pt <<
" GeV/c";
450 LogDebug(metname) <<
"theta = " << theta <<
" rad";
451 LogDebug(metname) <<
"phi = " << phi <<
" rad";
465 CLHEP::Hep3Vector vec(0., 1., 0.);
472 LogDebug(metname) <<
"The seed is in the barrel";
476 detLayer =
theService->detLayerGeometry()->idToLayer(theid);
482 radius = fabs(bc->radius() /
sin(theta));
489 LogDebug(metname) <<
"The seed is in the endcap";
494 detLayer =
theService->detLayerGeometry()->idToLayer(theid);
512 mat[0][0] = (0.25 /
pt) * (0.25 / pt);
514 mat[0][0] = (0.4 /
pt) * (0.4 / pt);
518 mat[0][0] = (1. /
pt) * (1. / pt);
520 mat[1][1] = 0.05 * 0.05;
521 mat[2][2] = 0.2 * 0.2;
522 mat[3][3] = 20. * 20.;
523 mat[4][4] = 20. * 20.;
529 LogDebug(metname) <<
"Free trajectory State from the parameters";
536 LogDebug(metname) <<
"State after the propagation on the layer";
541 if (fabs(eta) <
etaBins.back()) {
542 std::vector<double>::iterator lowEdge = std::upper_bound(
etaBins.begin(),
etaBins.end(), fabs(eta));
550 if ((!valid_charge || charge == 0)) {
573 else if (valid_charge) {
575 std::vector<pair<const GeomDet *, TrajectoryStateOnSurface>> detsWithStates =
578 if (detsWithStates.empty() &&
barrel) {
589 if (!detsWithStates.empty()) {
591 const GeomDet *newTSOSDet = detsWithStates.front().first;
593 LogDebug(metname) <<
"Most compatible det";
641 unsigned int nOfflineSeed1 = offlineSeedHandle->size();
646 vector<bool> removed_col = vector<bool>(nOfflineSeed1,
false);
648 for (nL1 = 0; nL1 < nMuColl; ++nL1) {
650 unsigned int theOffs = 0;
652 for (j = 0; j < nOfflineSeed1; ++
j) {
655 if (tempDR > dRmtx[nL1][j]) {
656 tempDR = dRmtx[nL1][
j];
661 auto it = muColl->begin(muColl->getFirstBX()) + nL1;
664 if (fabs(it->eta()) <
etaBins.back()) {
665 std::vector<double>::iterator lowEdge = std::upper_bound(
etaBins.begin(),
etaBins.end(), fabs(it->eta()));
669 if (!(tempDR < newDRcone))
673 removed_col[theOffs] =
true;
675 if (selOffseeds[nL1][theOffs] !=
nullptr) {
681 tscie = selOffseeds[nL1][theOffs]->recHits().second;
682 for (; tsci != tscie; ++tsci) {
694 vector<bool> removed_row = vector<bool>(nMuColl,
false);
695 vector<bool> removed_col = vector<bool>(nOfflineSeed1,
false);
697 for (nL1 = 0; nL1 < nMuColl; ++nL1) {
699 unsigned int theL1 = 0;
700 unsigned int theOffs = 0;
702 for (i = 0; i < nMuColl; ++
i) {
705 for (j = 0; j < nOfflineSeed1; ++
j) {
708 if (tempDR > dRmtx[i][j]) {
709 tempDR = dRmtx[
i][
j];
716 auto it = muColl->begin(muColl->getFirstBX()) + theL1;
719 if (fabs(it->eta()) <
etaBins.back()) {
720 std::vector<double>::iterator lowEdge = std::upper_bound(
etaBins.begin(),
etaBins.end(), fabs(it->eta()));
724 if (!(tempDR < newDRcone))
728 removed_col[theOffs] =
true;
729 removed_row[theL1] =
true;
731 if (selOffseeds[theL1][theOffs] !=
nullptr) {
737 tscie = selOffseeds[theL1][theOffs]->recHits().second;
738 for (; tsci != tscie; ++tsci) {
750 vector<bool> removed_row = vector<bool>(nMuColl,
false);
751 vector<bool> removed_col = vector<bool>(nOfflineSeed1,
false);
753 for (nL1 = 0; nL1 < nMuColl; ++nL1) {
755 unsigned int theL1 = 0;
756 unsigned int theOffs = 0;
757 auto theit = muColl->begin(muColl->getFirstBX());
760 for (i = 0; i < nMuColl; ++
i) {
763 theit = muColl->begin(muColl->getFirstBX()) + i;
764 if (theit->hwQual() > 10) {
765 for (j = 0; j < nOfflineSeed1; ++
j) {
768 if (tempDR > dRmtx[i][j]) {
769 tempDR = dRmtx[
i][
j];
779 for (i = 0; i < nMuColl; ++
i) {
782 theit = muColl->begin(muColl->getFirstBX()) + i;
783 if ((theit->hwQual() <= 10) && (theit->hwQual() > 6)) {
784 for (j = 0; j < nOfflineSeed1; ++
j) {
787 if (tempDR > dRmtx[i][j]) {
788 tempDR = dRmtx[
i][
j];
799 for (i = 0; i < nMuColl; ++
i) {
802 theit = muColl->begin(muColl->getFirstBX()) + i;
803 if (theit->hwQual() <= 6) {
804 for (j = 0; j < nOfflineSeed1; ++
j) {
807 if (tempDR > dRmtx[i][j]) {
808 tempDR = dRmtx[
i][
j];
817 auto it = muColl->begin(muColl->getFirstBX()) + theL1;
820 if (fabs(it->eta()) <
etaBins.back()) {
821 std::vector<double>::iterator lowEdge = std::upper_bound(
etaBins.begin(),
etaBins.end(), fabs(it->eta()));
825 if (!(tempDR < newDRcone))
829 removed_col[theOffs] =
true;
830 removed_row[theL1] =
true;
832 if (selOffseeds[theL1][theOffs] !=
nullptr) {
838 tscie = selOffseeds[theL1][theOffs]->recHits().second;
839 for (; tsci != tscie; ++tsci) {
851 for (i = 0; i < nMuColl; ++
i) {
852 auto it = muColl->begin(muColl->getFirstBX()) + i;
855 unsigned int theOffs = 0;
858 if (fabs(it->eta()) <
etaBins.back()) {
859 std::vector<double>::iterator lowEdge = std::upper_bound(
etaBins.begin(),
etaBins.end(), fabs(it->eta()));
863 for (j = 0; j < nOfflineSeed1; ++
j) {
864 if (tempDR > dRmtx[i][j]) {
865 tempDR = dRmtx[
i][
j];
870 if (!(tempDR < newDRcone))
873 if (selOffseeds[i][theOffs] !=
nullptr) {
879 tscie = selOffseeds[
i][theOffs]->recHits().second;
880 for (; tsci != tscie; ++tsci) {
911 std::vector<int> &offseedMap,
914 const std::string metlabel =
"Muon|RecoMuon|L2MuonSeedGeneratorFromL1T";
919 double bestDr = 99999.;
920 unsigned int nOffseed(0);
923 for (offseed = offseeds->
begin(); offseed != endOffseed; ++offseed, ++nOffseed) {
924 if (offseedMap[nOffseed] != 0)
927 ->idToDet(offseed->startingState().detId())
929 .toGlobal(offseed->startingState().parameters().position());
931 ->idToDet(offseed->startingState().detId())
933 .toGlobal(offseed->startingState().parameters().momentum());
941 glbPos, glbMom, offseed->startingState().parameters().charge(), &*
theService->magneticField());
944 LogDebug(metlabel) <<
"Offline seed info: Det and State" << std::endl;
945 LogDebug(metlabel) << debugtmp.
dumpMuonId(offseed->startingState().detId()) << std::endl;
946 LogDebug(metlabel) <<
"pos: (r=" << offseedFTS.position().mag() <<
", phi=" << offseedFTS.position().phi()
947 <<
", eta=" << offseedFTS.position().eta() <<
")" << std::endl;
948 LogDebug(metlabel) <<
"mom: (q*pt=" << offseedFTS.charge() * offseedFTS.momentum().perp()
949 <<
", phi=" << offseedFTS.momentum().phi() <<
", eta=" << offseedFTS.momentum().eta() <<
")" 953 if (offseedTsos.isValid()) {
954 LogDebug(metlabel) <<
"Offline seed info after propagation to L1 layer:" << std::endl;
955 LogDebug(metlabel) <<
"pos: (r=" << offseedTsos.globalPosition().mag()
956 <<
", phi=" << offseedTsos.globalPosition().phi()
957 <<
", eta=" << offseedTsos.globalPosition().eta() <<
")" << std::endl;
958 LogDebug(metlabel) <<
"mom: (q*pt=" << offseedTsos.charge() * offseedTsos.globalMomentum().perp()
959 <<
", phi=" << offseedTsos.globalMomentum().phi()
960 <<
", eta=" << offseedTsos.globalMomentum().eta() <<
")" << std::endl
964 offseedTsos.globalPosition().eta(),
965 offseedTsos.globalPosition().
phi());
966 LogDebug(metlabel) <<
" -- DR = " << newDr << std::endl;
967 if (newDr < dRcone && newDr < bestDr) {
968 LogDebug(metlabel) <<
" --> OK! " << newDr << std::endl << std::endl;
969 selOffseed = &*offseed;
971 offseedMap[nOffseed] = 1;
972 if (lastOffseed > -1)
973 offseedMap[lastOffseed] = 0;
974 lastOffseed = nOffseed;
976 LogDebug(metlabel) <<
" --> Rejected. " << newDr << std::endl << std::endl;
979 LogDebug(metlabel) <<
"Invalid offline seed TSOS after propagation!" << std::endl << std::endl;
988 std::vector<std::vector<double>> &dRmtx,
991 std::vector<std::vector<const TrajectorySeed *>> &selOffseeds,
993 const std::string metlabel =
"Muon|RecoMuon|L2MuonSeedGeneratorFromL1T";
994 bool isAssociated =
false;
998 unsigned int nOffseed(0);
1000 for (offseed = offseeds->
begin(); offseed != endOffseed; ++offseed, ++nOffseed) {
1002 ->idToDet(offseed->startingState().detId())
1004 .toGlobal(offseed->startingState().parameters().position());
1006 ->idToDet(offseed->startingState().detId())
1008 .toGlobal(offseed->startingState().parameters().momentum());
1016 glbPos, glbMom, offseed->startingState().parameters().charge(), &*
theService->magneticField());
1019 LogDebug(metlabel) <<
"Offline seed info: Det and State" << std::endl;
1020 LogDebug(metlabel) << debugtmp.
dumpMuonId(offseed->startingState().detId()) << std::endl;
1021 LogDebug(metlabel) <<
"pos: (r=" << offseedFTS.position().mag() <<
", phi=" << offseedFTS.position().phi()
1022 <<
", eta=" << offseedFTS.position().eta() <<
")" << std::endl;
1023 LogDebug(metlabel) <<
"mom: (q*pt=" << offseedFTS.charge() * offseedFTS.momentum().perp()
1024 <<
", phi=" << offseedFTS.momentum().phi() <<
", eta=" << offseedFTS.momentum().eta() <<
")" 1028 if (offseedTsos.isValid()) {
1029 LogDebug(metlabel) <<
"Offline seed info after propagation to L1 layer:" << std::endl;
1030 LogDebug(metlabel) <<
"pos: (r=" << offseedTsos.globalPosition().mag()
1031 <<
", phi=" << offseedTsos.globalPosition().phi()
1032 <<
", eta=" << offseedTsos.globalPosition().eta() <<
")" << std::endl;
1033 LogDebug(metlabel) <<
"mom: (q*pt=" << offseedTsos.charge() * offseedTsos.globalMomentum().perp()
1034 <<
", phi=" << offseedTsos.globalMomentum().phi()
1035 <<
", eta=" << offseedTsos.globalMomentum().eta() <<
")" << std::endl
1039 offseedTsos.globalPosition().eta(),
1040 offseedTsos.globalPosition().
phi());
1042 LogDebug(metlabel) <<
" -- DR = " << newDr << std::endl;
1043 if (newDr < dRcone) {
1044 LogDebug(metlabel) <<
" --> OK! " << newDr << std::endl << std::endl;
1046 dRmtx[imu][nOffseed] = newDr;
1047 selOffseeds[imu][nOffseed] = &*offseed;
1049 isAssociated =
true;
1051 LogDebug(metlabel) <<
" --> Rejected. " << newDr << std::endl << std::endl;
1054 LogDebug(metlabel) <<
"Invalid offline seed TSOS after propagation!" << std::endl << std::endl;
1058 return isAssociated;
edm::EDGetTokenT< edm::View< TrajectorySeed > > offlineSeedToken_
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
TrackCharge charge() const
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
bool centralBxOnly_
use central bx only muons
std::string dumpLayer(const DetLayer *layer) const
const TrajectorySeed * associateOfflineSeedToL1(edm::Handle< edm::View< TrajectorySeed > > &, std::vector< int > &, TrajectoryStateOnSurface &, double)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
bool sortByL1Pt(L2MuonTrajectorySeed &A, L2MuonTrajectorySeed &B)
const std::string metname
const bool useOfflineSeed
Sin< T >::type sin(const T &t)
Geom::Phi< T > phi() const
constexpr uint32_t rawId() const
get the raw id
Geom::Theta< T > theta() const
l1t::MuonRef l1tParticle() const
GlobalPoint globalPosition() const
L2MuonSeedGeneratorFromL1T(const edm::ParameterSet &)
Constructor.
virtual std::vector< DetWithState > compatibleDets(const TrajectoryStateOnSurface &startingState, const Propagator &prop, const MeasurementEstimator &est) const
std::string dumpMuonId(const DetId &id) const
std::string dumpFTS(const FreeTrajectoryState &fts) const
~L2MuonSeedGeneratorFromL1T() override
Destructor.
std::string dumpTSOS(const TrajectoryStateOnSurface &tsos) const
const SurfaceType & surface() const
const_iterator begin() const
MuonServiceProxy * theService
the event setup proxy, it takes care the services update
const unsigned theL1MinQuality
recHitContainer::const_iterator const_iterator
Cos< T >::type cos(const T &t)
bool isAssociateOfflineSeedToL1(edm::Handle< edm::View< TrajectorySeed > > &, std::vector< std::vector< double > > &, TrajectoryStateOnSurface &, unsigned int, std::vector< std::vector< const TrajectorySeed * > > &, double)
virtual const BoundSurface & surface() const =0
The surface of the GeometricSearchDet.
DetId geographicalId() const
The label of this GeomDet.
bool sortByL1QandPt(L2MuonTrajectorySeed &A, L2MuonTrajectorySeed &B)
static const std::string B
ParameterDescriptionBase * add(U const &iLabel, T const &value)
const bool useUnassociatedL1
PTrajectoryStateOnDet const & startingState() const
virtual const Surface::PositionType & position() const
Returns position of the surface.
edm::EDGetTokenT< l1t::MuonBxCollection > muCollToken_
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
void add(std::string const &label, ParameterSetDescription const &psetDescription)
const double theMinPtBarrel
GlobalVector globalMomentum() const
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
MeasurementEstimator * theEstimator
void produce(edm::Event &, const edm::EventSetup &) override
std::string thePropagatorName
const double theMinPtEndcap
edm::InputTag theOfflineSeedLabel
edm::Ref< MuonBxCollection > MuonRef
std::vector< double > etaBins
std::vector< double > matchingDR