50 return (Ref_L1A->pt() > Ref_L1B->pt());
58 if (Ref_L1A->hwQual() > Ref_L1B->hwQual())
return true;
59 if (Ref_L1A->hwQual() < Ref_L1B->hwQual())
return false;
62 return (Ref_L1A->pt() > Ref_L1B->pt());
68 theL1GMTReadoutCollection(iConfig.getParameter<
InputTag>(
"GMTReadoutCollection")),
70 theL1MinPt(iConfig.getParameter<double>(
"L1MinPt")),
71 theL1MaxEta(iConfig.getParameter<double>(
"L1MaxEta")),
72 theL1MinQuality(iConfig.getParameter<unsigned
int>(
"L1MinQuality")),
73 theMinPtBarrel(iConfig.getParameter<double>(
"SetMinPtBarrelTo")),
74 theMinPtEndcap(iConfig.getParameter<double>(
"SetMinPtEndcapTo")),
75 useOfflineSeed(iConfig.getUntrackedParameter<
bool>(
"UseOfflineSeed",
false)),
76 useUnassociatedL1(iConfig.getParameter<
bool>(
"UseUnassociatedL1")),
77 matchingDR(iConfig.getParameter<
std::vector<double> >(
"MatchDR")),
78 etaBins(iConfig.getParameter<
std::vector<double> >(
"EtaMatchingBins")),
79 centralBxOnly_( iConfig.getParameter<
bool>(
"CentralBxOnly") ),
80 matchType( iConfig.getParameter<unsigned
int>(
"MatchType") ),
81 sortType( iConfig.getParameter<unsigned
int>(
"SortType") )
93 <<
"does not match number of eta bins." << endl;
100 throw cms::Exception(
"Configuration") <<
"Wrong MatchType or SortType" << endl;
113 produces<L2MuonTrajectorySeedCollection>();
127 desc.
add<
string>(
"Propagator",
"");
128 desc.
add<
double>(
"L1MinPt",-1.);
129 desc.
add<
double>(
"L1MaxEta",5.0);
130 desc.
add<
unsigned int>(
"L1MinQuality",0);
131 desc.
add<
double>(
"SetMinPtBarrelTo",3.5);
132 desc.
add<
double>(
"SetMinPtEndcapTo",1.0);
134 desc.
add<
bool>(
"UseUnassociatedL1",
true);
135 desc.
add<std::vector<double>>(
"MatchDR", {0.3});
136 desc.
add<std::vector<double>>(
"EtaMatchingBins", {0., 2.5});
137 desc.
add<
bool>(
"CentralBxOnly",
true);
138 desc.
add<
unsigned int>(
"MatchType", 0)->setComment(
"MatchType : 0 Old matching, 1 L1 Order(1to1), 2 Min dR(1to1), 3 Higher Q(1to1), 4 All matched L1");
139 desc.
add<
unsigned int>(
"SortType", 0)->setComment(
"SortType : 0 not sort, 1 Pt, 2 Q and Pt");
143 psd0.
addUntracked<std::vector<std::string>>(
"Propagators", {
144 "SteppingHelixPropagatorAny" 146 psd0.add<
bool>(
"RPCLayers",
true);
147 psd0.addUntracked<
bool>(
"UseMuonNavigation",
true);
149 descriptions.
add(
"L2MuonSeedGeneratorFromL1T",desc);
157 auto output = std::make_unique<L2MuonTrajectorySeedCollection>();
161 LogDebug(metname) <<
"Number of muons " << muColl->size() << endl;
168 vector<int> offlineSeedMap;
171 LogDebug(metname) <<
"Number of offline seeds " << offlineSeedHandle->size() << endl;
172 offlineSeedMap = vector<int>(offlineSeedHandle->size(), 0);
175 for (
int ibx = muColl->getFirstBX(); ibx <= muColl->getLastBX(); ++ibx) {
177 for (
auto it = muColl->begin(ibx); it != muColl->end(ibx); it++){
179 unsigned int quality = it->hwQual();
180 int valid_charge = it->hwChargeValid();
183 float eta = it->eta();
185 float phi = it->phi();
186 int charge = it->charge();
188 if (!valid_charge) charge = 0;
192 int link = 36 + (
int)(it -> tfMuonIndex() / 3.);
194 if ( (link >= 36 && link <= 41) || (link >= 66 && link <= 71)) barrel =
false;
198 LogDebug(metname) <<
"New L2 Muon Seed" ;
199 LogDebug(metname) <<
"Pt = " << pt <<
" GeV/c";
201 LogDebug(metname) <<
"theta = " << theta <<
" rad";
202 LogDebug(metname) <<
"phi = " << phi <<
" rad";
215 CLHEP::Hep3Vector vec(0.,1.,0.);
222 LogDebug(metname) <<
"The seed is in the barrel";
226 detLayer =
theService->detLayerGeometry()->idToLayer(theid);
232 radius = fabs(bc->radius()/
sin(theta));
239 LogDebug(metname) <<
"The seed is in the endcap";
244 detLayer =
theService->detLayerGeometry()->idToLayer(theid);
261 mat[0][0] = (0.25/
pt)*(0.25/pt);
262 if ( !barrel ) mat[0][0] = (0.4/
pt)*(0.4/pt);
265 if (!valid_charge) mat[0][0] = (1./
pt)*(1./pt);
267 mat[1][1] = 0.05*0.05;
276 LogDebug(metname) <<
"Free trajectory State from the parameters";
282 LogDebug(metname) <<
"State after the propagation on the layer";
287 if ( fabs(eta) <
etaBins.back() ){
301 if(assoOffseed!=
nullptr) {
304 tsci = assoOffseed->
recHits().first,
305 tscie = assoOffseed->
recHits().second;
306 for(; tsci!=tscie; ++tsci) {
323 std::vector< pair<const GeomDet*,TrajectoryStateOnSurface> >
328 if (detsWithStates.empty() &&
barrel ) {
340 if (!detsWithStates.empty()){
343 const GeomDet *newTSOSDet = detsWithStates.front().first;
345 LogDebug(metname) <<
"Most compatible det";
358 if(assoOffseed!=
nullptr) {
361 tsci = assoOffseed->
recHits().first,
362 tscie = assoOffseed->
recHits().second;
363 for(; tsci!=tscie; ++tsci) {
395 unsigned int nMuColl = muColl->size();
397 vector< vector<double> > dRmtx;
398 vector< vector<const TrajectorySeed *> > selOffseeds;
403 unsigned int nOfflineSeed = offlineSeedHandle->size();
404 LogDebug(metname) <<
"Number of offline seeds " << nOfflineSeed << endl;
407 dRmtx = vector< vector<double> >(nMuColl, vector<double>(nOfflineSeed, 999.0));
408 selOffseeds = vector< vector <const TrajectorySeed *> >(nMuColl, vector<const TrajectorySeed *>(nOfflineSeed,
nullptr));
415 for (
int ibx = muColl->getFirstBX(); ibx <= muColl->getLastBX(); ++ibx) {
417 for (
auto it = muColl->begin(ibx); it != muColl->end(ibx); it++){
420 unsigned int imu =
distance(muColl->begin(muColl->getFirstBX()),it);
422 unsigned int quality = it->hwQual();
423 int valid_charge = it->hwChargeValid();
426 float eta = it->eta();
428 float phi = it->phi();
429 int charge = it->charge();
431 if (!valid_charge) charge = 0;
435 int link = 36 + (
int)(it -> tfMuonIndex() / 3.);
437 if ( (link >= 36 && link <= 41) || (link >= 66 && link <= 71)) barrel =
false;
441 LogDebug(metname) <<
"New L2 Muon Seed" ;
442 LogDebug(metname) <<
"Pt = " << pt <<
" GeV/c";
444 LogDebug(metname) <<
"theta = " << theta <<
" rad";
445 LogDebug(metname) <<
"phi = " << phi <<
" rad";
458 CLHEP::Hep3Vector vec(0.,1.,0.);
465 LogDebug(metname) <<
"The seed is in the barrel";
469 detLayer =
theService->detLayerGeometry()->idToLayer(theid);
475 radius = fabs(bc->radius()/
sin(theta));
482 LogDebug(metname) <<
"The seed is in the endcap";
487 detLayer =
theService->detLayerGeometry()->idToLayer(theid);
504 mat[0][0] = (0.25/
pt)*(0.25/pt);
505 if ( !barrel ) mat[0][0] = (0.4/
pt)*(0.4/pt);
508 if (!valid_charge) mat[0][0] = (1./
pt)*(1./pt);
510 mat[1][1] = 0.05*0.05;
519 LogDebug(metname) <<
"Free trajectory State from the parameters";
525 LogDebug(metname) <<
"State after the propagation on the layer";
530 if ( fabs(eta) <
etaBins.back() ){
541 if( ( !valid_charge || charge == 0 ) ) {
561 else if( valid_charge ) {
564 std::vector< pair<const GeomDet*,TrajectoryStateOnSurface> >
569 if (detsWithStates.empty() &&
barrel ) {
581 if (!detsWithStates.empty()){
584 const GeomDet *newTSOSDet = detsWithStates.front().first;
586 LogDebug(metname) <<
"Most compatible det";
630 unsigned int nOfflineSeed1 = offlineSeedHandle->size();
635 vector<bool> removed_col = vector<bool>(nOfflineSeed1,
false);
637 for(nL1=0; nL1 < nMuColl; ++nL1) {
639 unsigned int theOffs = 0;
641 for(j=0; j<nOfflineSeed1; ++j) {
642 if(removed_col[j])
continue;
643 if( tempDR > dRmtx[nL1][j] ) {
644 tempDR = dRmtx[nL1][j];
649 auto it = muColl->begin(muColl->getFirstBX()) + nL1;
652 if ( fabs(it->eta()) <
etaBins.back() ){
657 if( !(tempDR < newDRcone) )
continue;
660 removed_col[theOffs] =
true;
662 if( selOffseeds[nL1][theOffs] !=
nullptr ) {
668 tsci = selOffseeds[nL1][theOffs]->recHits().first,
669 tscie = selOffseeds[nL1][theOffs]->recHits().second;
670 for(; tsci!=tscie; ++tsci) {
680 vector<bool> removed_row = vector<bool>(nMuColl,
false);
681 vector<bool> removed_col = vector<bool>(nOfflineSeed1,
false);
683 for(nL1=0; nL1 < nMuColl; ++nL1) {
685 unsigned int theL1 = 0;
686 unsigned int theOffs = 0;
688 for(i=0; i<nMuColl; ++
i) {
689 if(removed_row[i])
continue;
690 for(j=0; j<nOfflineSeed1; ++j) {
691 if(removed_col[j])
continue;
692 if(tempDR > dRmtx[i][j]) {
693 tempDR = dRmtx[
i][j];
700 auto it = muColl->begin(muColl->getFirstBX()) + theL1;
703 if ( fabs(it->eta()) <
etaBins.back() ){
708 if( !(tempDR < newDRcone) )
continue;
711 removed_col[theOffs] =
true;
712 removed_row[theL1] =
true;
714 if( selOffseeds[theL1][theOffs] !=
nullptr ) {
720 tsci = selOffseeds[theL1][theOffs]->recHits().first,
721 tscie = selOffseeds[theL1][theOffs]->recHits().second;
722 for(; tsci!=tscie; ++tsci) {
732 vector<bool> removed_row = vector<bool>(nMuColl,
false);
733 vector<bool> removed_col = vector<bool>(nOfflineSeed1,
false);
735 for(nL1=0; nL1 < nMuColl; ++nL1) {
737 unsigned int theL1 = 0;
738 unsigned int theOffs = 0;
739 auto theit = muColl->begin(muColl->getFirstBX());
742 for(i=0; i<nMuColl; ++
i) {
743 if(removed_row[i])
continue;
744 theit = muColl->begin(muColl->getFirstBX()) + i;
745 if (theit->hwQual() > 10) {
746 for(j=0; j<nOfflineSeed1; ++j) {
747 if(removed_col[j])
continue;
748 if(tempDR > dRmtx[i][j]) {
749 tempDR = dRmtx[
i][j];
759 for(i=0; i<nMuColl; ++
i) {
760 if(removed_row[i])
continue;
761 theit = muColl->begin(muColl->getFirstBX()) + i;
762 if ( (theit->hwQual() <= 10) && (theit->hwQual() > 6) ) {
763 for(j=0; j<nOfflineSeed1; ++j) {
764 if(removed_col[j])
continue;
765 if(tempDR > dRmtx[i][j]) {
766 tempDR = dRmtx[
i][j];
777 for(i=0; i<nMuColl; ++
i) {
778 if(removed_row[i])
continue;
779 theit = muColl->begin(muColl->getFirstBX()) + i;
780 if (theit->hwQual() <= 6) {
781 for(j=0; j<nOfflineSeed1; ++j) {
782 if(removed_col[j])
continue;
783 if(tempDR > dRmtx[i][j]) {
784 tempDR = dRmtx[
i][j];
793 auto it = muColl->begin(muColl->getFirstBX()) + theL1;
796 if ( fabs(it->eta()) <
etaBins.back() ){
801 if( !(tempDR < newDRcone) )
continue;
804 removed_col[theOffs] =
true;
805 removed_row[theL1] =
true;
807 if( selOffseeds[theL1][theOffs] !=
nullptr ) {
813 tsci = selOffseeds[theL1][theOffs]->recHits().first,
814 tscie = selOffseeds[theL1][theOffs]->recHits().second;
815 for(; tsci!=tscie; ++tsci) {
826 for(i=0; i<nMuColl; ++
i) {
828 auto it = muColl->begin(muColl->getFirstBX()) + i;
831 unsigned int theOffs = 0;
834 if ( fabs(it->eta()) <
etaBins.back() ){
839 for(j=0; j<nOfflineSeed1; ++j) {
840 if( tempDR > dRmtx[i][j] ) {
841 tempDR = dRmtx[
i][j];
846 if( !(tempDR < newDRcone) )
continue;
848 if( selOffseeds[i][theOffs] !=
nullptr ) {
854 tsci = selOffseeds[
i][theOffs]->recHits().first,
855 tscie = selOffseeds[
i][theOffs]->recHits().second;
856 for(; tsci!=tscie; ++tsci) {
886 std::vector<int> & offseedMap,
890 const std::string metlabel =
"Muon|RecoMuon|L2MuonSeedGeneratorFromL1T";
895 double bestDr = 99999.;
896 unsigned int nOffseed(0);
899 for(offseed=offseeds->
begin(); offseed!=endOffseed; ++offseed, ++nOffseed) {
900 if(offseedMap[nOffseed]!=0)
continue;
901 GlobalPoint glbPos =
theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().position());
902 GlobalVector glbMom =
theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().momentum());
906 if(preDr > 1.0)
continue;
910 LogDebug(metlabel) <<
"Offline seed info: Det and State" << std::endl;
911 LogDebug(metlabel) << debugtmp.
dumpMuonId(offseed->startingState().detId()) << std::endl;
912 LogDebug(metlabel) <<
"pos: (r=" << offseedFTS.position().mag() <<
", phi=" 913 << offseedFTS.position().phi() <<
", eta=" << offseedFTS.position().eta() <<
")" << std::endl;
914 LogDebug(metlabel) <<
"mom: (q*pt=" << offseedFTS.charge()*offseedFTS.momentum().perp() <<
", phi=" 915 << offseedFTS.momentum().phi() <<
", eta=" << offseedFTS.momentum().eta() <<
")" << std::endl << std::endl;
917 if(offseedTsos.isValid()) {
918 LogDebug(metlabel) <<
"Offline seed info after propagation to L1 layer:" << std::endl;
919 LogDebug(metlabel) <<
"pos: (r=" << offseedTsos.globalPosition().mag() <<
", phi=" 920 << offseedTsos.globalPosition().phi() <<
", eta=" << offseedTsos.globalPosition().eta() <<
")" << std::endl;
921 LogDebug(metlabel) <<
"mom: (q*pt=" << offseedTsos.charge()*offseedTsos.globalMomentum().perp() <<
", phi=" 922 << offseedTsos.globalMomentum().phi() <<
", eta=" << offseedTsos.globalMomentum().eta() <<
")" << std::endl << std::endl;
924 offseedTsos.globalPosition().eta(), offseedTsos.globalPosition().phi() );
925 LogDebug(metlabel) <<
" -- DR = " << newDr << std::endl;
926 if( newDr < dRcone && newDr<bestDr ) {
927 LogDebug(metlabel) <<
" --> OK! " << newDr << std::endl << std::endl;
928 selOffseed = &*offseed;
930 offseedMap[nOffseed] = 1;
931 if(lastOffseed>-1) offseedMap[lastOffseed] = 0;
932 lastOffseed = nOffseed;
935 LogDebug(metlabel) <<
" --> Rejected. " << newDr << std::endl << std::endl;
939 LogDebug(metlabel) <<
"Invalid offline seed TSOS after propagation!" << std::endl << std::endl;
948 std::vector< std::vector<double> > & dRmtx,
951 std::vector< std::vector<const TrajectorySeed *> > & selOffseeds,
954 const std::string metlabel =
"Muon|RecoMuon|L2MuonSeedGeneratorFromL1T";
955 bool isAssociated =
false;
959 unsigned int nOffseed(0);
961 for(offseed=offseeds->
begin(); offseed!=endOffseed; ++offseed, ++nOffseed) {
962 GlobalPoint glbPos =
theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().position());
963 GlobalVector glbMom =
theService->trackingGeometry()->idToDet(offseed->startingState().detId())->surface().toGlobal(offseed->startingState().parameters().momentum());
967 if(preDr > 1.0)
continue;
971 LogDebug(metlabel) <<
"Offline seed info: Det and State" << std::endl;
972 LogDebug(metlabel) << debugtmp.
dumpMuonId(offseed->startingState().detId()) << std::endl;
973 LogDebug(metlabel) <<
"pos: (r=" << offseedFTS.position().mag() <<
974 ", phi=" << offseedFTS.position().phi() <<
975 ", eta=" << offseedFTS.position().eta() <<
")" << std::endl;
976 LogDebug(metlabel) <<
"mom: (q*pt=" << offseedFTS.charge()*offseedFTS.momentum().perp() <<
977 ", phi=" << offseedFTS.momentum().phi() <<
978 ", eta=" << offseedFTS.momentum().eta() <<
")" << std::endl << std::endl;
980 if(offseedTsos.isValid()) {
981 LogDebug(metlabel) <<
"Offline seed info after propagation to L1 layer:" << std::endl;
982 LogDebug(metlabel) <<
"pos: (r=" << offseedTsos.globalPosition().mag() <<
983 ", phi=" << offseedTsos.globalPosition().phi() <<
984 ", eta=" << offseedTsos.globalPosition().eta() <<
")" << std::endl;
985 LogDebug(metlabel) <<
"mom: (q*pt=" << offseedTsos.charge()*offseedTsos.globalMomentum().perp() <<
986 ", phi=" << offseedTsos.globalMomentum().phi() <<
987 ", eta=" << offseedTsos.globalMomentum().eta() <<
")" << std::endl << std::endl;
989 offseedTsos.globalPosition().eta(), offseedTsos.globalPosition().phi() );
992 LogDebug(metlabel) <<
" -- DR = " << newDr << std::endl;
993 if( newDr < dRcone ) {
994 LogDebug(metlabel) <<
" --> OK! " << newDr << std::endl << std::endl;
996 dRmtx[imu][nOffseed] = newDr;
997 selOffseeds[imu][nOffseed] = &*offseed;
1002 LogDebug(metlabel) <<
" --> Rejected. " << newDr << std::endl << std::endl;
1006 LogDebug(metlabel) <<
"Invalid offline seed TSOS after propagation!" << std::endl << std::endl;
1010 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.
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
virtual std::vector< DetWithState > compatibleDets(const TrajectoryStateOnSurface &startingState, const Propagator &prop, const MeasurementEstimator &est) const
edm::Ref< MuonBxCollection > MuonRef
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_
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
std::vector< double > etaBins
std::vector< double > matchingDR