Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EMTF new LCT coordinate conversion LUTs #24766

Merged
merged 1 commit into from
Oct 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion L1Trigger/L1TMuonEndCap/interface/SectorProcessorLUT.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class SectorProcessorLUT {
explicit SectorProcessorLUT();
~SectorProcessorLUT();

void read(int pc_lut_version);
void read(bool pc_lut_data, int pc_lut_version);

uint32_t get_ph_init(int fw_endcap, int fw_sector, int pc_lut_id) const;

Expand Down
9 changes: 5 additions & 4 deletions L1Trigger/L1TMuonEndCap/python/simEmtfDigis_cfi.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
# * 'simCscTriggerPrimitiveDigis','MPCSORTED' : simulated trigger primitives (LCTs) from re-emulating CSC digis
# * 'csctfDigis' : real trigger primitives as received by CSCTF (legacy trigger), available only in 2016 data
# * 'emtfStage2Digis' : real trigger primitives as received by EMTF, unpacked in EventFilter/L1TRawToDigi/
CSCInput = cms.InputTag('simCscTriggerPrimitiveDigis','MPCSORTED'),
RPCInput = cms.InputTag('simMuonRPCDigis'),
CSCInput = cms.InputTag('simCscTriggerPrimitiveDigis','MPCSORTED'),
RPCInput = cms.InputTag('simMuonRPCDigis'),
CPPFInput = cms.InputTag('simCPPFDigis'), ## Cannot use in MC workflow, does not exist yet. CPPFEnable set to False - AWB 01.06.18
GEMInput = cms.InputTag('simMuonGEMPadDigis'),
GEMInput = cms.InputTag('simMuonGEMPadDigis'),

# Run with CSC, RPC, GEM
CSCEnable = cms.bool(True), # Use CSC LCTs from the MPCs in track-building
Expand All @@ -47,7 +47,7 @@

# Sector processor primitive-conversion parameters
spPCParams16 = cms.PSet(
PrimConvLUT = cms.int32(1), # v0 and v1 LUTs used at different times, "-1" for local CPPF files (only works if FWConfig = False)
PrimConvLUT = cms.int32(2), # v0, v1, and v2 LUTs used at different times, "-1" for local CPPF files (only works if FWConfig = False)
ZoneBoundaries = cms.vint32(0,41,49,87,127), # Vertical boundaries of track-building zones, in integer theta (5 for 4 zones)
# ZoneBoundaries = cms.vint32(0,36,54,96,127), # New proposed zone boundaries
ZoneOverlap = cms.int32(2), # Overlap between zones
Expand Down Expand Up @@ -125,6 +125,7 @@
GEMInput = cms.InputTag('muonGEMPadDigis'),

CPPFEnable = cms.bool(True), # Use CPPF-emulated clustered RPC hits from CPPF as the RPC hits

)

simEmtfDigis = simEmtfDigisMC.clone()
Expand Down
9 changes: 7 additions & 2 deletions L1Trigger/L1TMuonEndCap/src/ConditionHelper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,12 @@ unsigned int ConditionHelper::get_pc_lut_version() const {

// Hack until we figure out why the database is returning "0" for 2017 data - AWB 04.08.17
// std::cout << " - Getting hacked PC LUT version from ConditionHelper: version = " << (params_->firmwareVersion_ >= 50000) << std::endl;
if (params_->firmwareVersion_ < 50000) // for 2016
if (params_->firmwareVersion_ < 50000) { // For 2016
return 0;
return 1;
} else if (params_->firmwareVersion_ < 1537467271) { // From the beginning of 2017
return 1; // Corresponding to FW timestamps before Sept. 20, 2018
} else {
return 2; // Starting September 26, 2018 with run 323556 (data only, not in MC)
}

}
17 changes: 12 additions & 5 deletions L1Trigger/L1TMuonEndCap/src/SectorProcessorLUT.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,25 @@ SectorProcessorLUT::~SectorProcessorLUT() {

}

void SectorProcessorLUT::read(int pc_lut_version) {
void SectorProcessorLUT::read(bool pc_lut_data, int pc_lut_version) {
if (version_ == pc_lut_version) return;

edm::LogInfo("L1T") << "EMTF using pc_lut_ver: " << pc_lut_version;
edm::LogInfo("L1T") << "EMTF using pc_lut_ver: " << pc_lut_version
<< ", configured for " << (pc_lut_data ? "data" : "MC");

std::string coord_lut_dir = "";
if (pc_lut_version == 0)
coord_lut_dir = "ph_lut_v1"; // All year 2016
coord_lut_dir = "ph_lut_v1"; // All year 2016
else if (pc_lut_version == 1)
coord_lut_dir = "ph_lut_v2"; // Beginning of 2017
coord_lut_dir = "ph_lut_v2"; // Beginning of 2017, improved alignment from ideal CMS geometry (MC)
else if (pc_lut_version == 2 && pc_lut_data)
coord_lut_dir = "ph_lut_v3_data"; // Update in September 2017 from ReReco alignment, data only
else if (pc_lut_version == 2)
coord_lut_dir = "ph_lut_v2"; // MC still uses ideal CMS aligment
else if (pc_lut_version == -1 && pc_lut_data)
coord_lut_dir = "ph_lut_v3_data"; // September 2017 data LCT alignment, but use local CPPF LUTs for RPC
else if (pc_lut_version == -1)
coord_lut_dir = "ph_lut_v2"; // Beginning of 2017, use local CPPF LUTs
coord_lut_dir = "ph_lut_v2"; // MC using ideal CMS LCT alignment, but use local CPPF LUTs for RPC
else
throw cms::Exception("SectorProcessorLUT")
<< "Trying to use EMTF pc_lut_version = " << pc_lut_version << ", does not exist!";
Expand Down
2 changes: 1 addition & 1 deletion L1Trigger/L1TMuonEndCap/src/TrackFinder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ void TrackFinder::process(
// Run each sector processor

// Reload primitive conversion LUTs if necessary
sector_processor_lut_.read(fwConfig_ ? condition_helper_.get_pc_lut_version() : primConvLUT_);
sector_processor_lut_.read(iEvent.isRealData(), fwConfig_ ? condition_helper_.get_pc_lut_version() : primConvLUT_);

// Reload pT LUT if necessary
pt_assign_engine_->load(condition_helper_.get_pt_lut_version(), &(condition_helper_.getForest()));
Expand Down
112 changes: 73 additions & 39 deletions L1Trigger/L1TMuonEndCap/test/tools/MakeCoordLUT.cc
Original file line number Diff line number Diff line change
Expand Up @@ -220,42 +220,41 @@ void MakeCoordLUT::generateLUTs_init() {
return;
}

// values for ph and th init values hardcoded in verilog zones.v
// these are with offset relative to actual init values to allow for chamber displacement
// [station_5][chamber_16]
// ME1 chambers 13,14,15,16 are neighbor sector chambers 3,6,9,12
// ME2 chambers 10,11 are neighbor sector chambers 3,9
// NOTE: since Sep 2016, th_init_hard and ph_cover_hard are not being used anymore
static const int ph_init_hard[5][16] = {
{39, 57, 76, 39, 58, 76, 41, 60, 79, 39, 57, 76, 21, 21, 23, 21},
{95, 114, 132, 95, 114, 133, 98, 116, 135, 95, 114, 132, 0, 0, 0, 0},
{38, 76, 113, 39, 58, 76, 95, 114, 132, 1, 21, 0, 0, 0, 0, 0},
{38, 76, 113, 39, 58, 76, 95, 114, 132, 1, 21, 0, 0, 0, 0, 0},
{38, 76, 113, 38, 57, 76, 95, 113, 132, 1, 20, 0, 0, 0, 0, 0}
};

static const int th_init_hard[5][16] = {
{1,1,1,42,42,42,94,94,94,1,1, 1,1,42,94, 1},
{1,1,1,42,42,42,94,94,94,1,1, 1,0, 0, 0, 0},
{1,1,1,48,48,48,48,48,48,1,48,0,0, 0, 0, 0},
{1,1,1,40,40,40,40,40,40,1,40,0,0, 0, 0, 0},
{2,2,2,34,34,34,34,34,34,2,34,0,0, 0, 0, 0}
};

// hardcoded chamber ph coverage in verilog prim_conv.v
static const int ph_cover_hard[5][16] = {
{40,40,40,40,40,40,30,30,30,40,40,40,40,40,30,40},
{40,40,40,40,40,40,30,30,30,40,40,40, 0, 0, 0, 0},
{80,80,80,40,40,40,40,40,40,80,40, 0, 0, 0, 0, 0},
{80,80,80,40,40,40,40,40,40,80,40, 0, 0, 0, 0, 0},
{80,80,80,40,40,40,40,40,40,80,40, 0, 0, 0, 0, 0}
};

void MakeCoordLUT::generateLUTs_run() {
constexpr double theta_scale = (UPPER_THETA - LOWER_THETA)/128; // = 0.28515625 (7 bits encode 128 values)
constexpr double nominal_pitch = 10./75.; // = 0.133333 (ME2/2 strip pitch. 10-degree chamber, 80 strips - 5 overlap strips)

// values for ph and th init values hardcoded in verilog zones.v
// these are with offset relative to actual init values to allow for chamber displacement
// [station_5][chamber_16]
// ME1 chambers 13,14,15,16 are neighbor sector chambers 3,6,9,12
// ME2 chambers 10,11 are neighbor sector chambers 3,9
// NOTE: since Sep 2016, th_init_hard and ph_cover_hard are not being used anymore
const int ph_init_hard[5][16] = {
{39, 57, 76, 39, 58, 76, 41, 60, 79, 39, 57, 76, 21, 21, 23, 21},
{95, 114, 132, 95, 114, 133, 98, 116, 135, 95, 114, 132, 0, 0, 0, 0},
{38, 76, 113, 39, 58, 76, 95, 114, 132, 1, 21, 0, 0, 0, 0, 0},
{38, 76, 113, 39, 58, 76, 95, 114, 132, 1, 21, 0, 0, 0, 0, 0},
{38, 76, 113, 38, 57, 76, 95, 113, 132, 1, 20, 0, 0, 0, 0, 0}
};

const int th_init_hard[5][16] = {
{1,1,1,42,42,42,94,94,94,1,1, 1,1,42,94, 1},
{1,1,1,42,42,42,94,94,94,1,1, 1,0, 0, 0, 0},
{1,1,1,48,48,48,48,48,48,1,48,0,0, 0, 0, 0},
{1,1,1,40,40,40,40,40,40,1,40,0,0, 0, 0, 0},
{2,2,2,34,34,34,34,34,34,2,34,0,0, 0, 0, 0}
};

// hardcoded chamber ph coverage in verilog prim_conv.v
const int ph_cover_hard[5][16] = {
{40,40,40,40,40,40,30,30,30,40,40,40,40,40,30,40},
{40,40,40,40,40,40,30,30,30,40,40,40, 0, 0, 0, 0},
{80,80,80,40,40,40,40,40,40,80,40, 0, 0, 0, 0, 0},
{80,80,80,40,40,40,40,40,40,80,40, 0, 0, 0, 0, 0},
{80,80,80,40,40,40,40,40,40,80,40, 0, 0, 0, 0, 0}
};


for (int endcap = MIN_ENDCAP; endcap <= MAX_ENDCAP; ++endcap) {
for (int sector = MIN_TRIGSECTOR; sector <= MAX_TRIGSECTOR; ++sector) {
for (int station = 1; station <= 4; ++station) {
Expand Down Expand Up @@ -541,6 +540,15 @@ void MakeCoordLUT::validateLUTs() {
int es = 0;
int st = 0;
int ch = 0;
//
int endcap = 0;
int station = 0;
int sector = 0;
int subsector = 0;
int ring = 0;
int chamber = 0;
int CSC_ID = 0;
//
int strip = 0; // it is half-strip, despite the name
int wire = 0; // it is wiregroup, despite the name
int fph_int = 0;
Expand All @@ -555,6 +563,15 @@ void MakeCoordLUT::validateLUTs() {
ttree->Branch("es" , &es );
ttree->Branch("st" , &st );
ttree->Branch("ch" , &ch );
//
ttree->Branch("endcap" , &endcap );
ttree->Branch("station" , &station );
ttree->Branch("sector" , &sector );
ttree->Branch("subsector", &subsector );
ttree->Branch("ring" , &ring );
ttree->Branch("chamber" , &chamber );
ttree->Branch("CSC_ID" , &CSC_ID );
//
ttree->Branch("strip" , &strip );
ttree->Branch("wire" , &wire );
ttree->Branch("fph_int", &fph_int);
Expand Down Expand Up @@ -588,11 +605,11 @@ void MakeCoordLUT::validateLUTs() {
assert(es < 12 && st < 5 && ch < 16);

// Retrieve endcap, sector, subsector, station, chamber
int endcap = (es/6) + 1;
int sector = (es%6) + 1;
int subsector = (st <= 1) ? st + 1 : 0;
int station = (st <= 1) ? 1 : st;
int chamber = ch + 1;
endcap = (es/6) + 1;
sector = (es%6) + 1;
subsector = (st <= 1) ? st + 1 : 0;
station = (st <= 1) ? 1 : st;
chamber = ch + 1;

bool is_me11a = false;
bool is_neighbor = false;
Expand Down Expand Up @@ -638,12 +655,14 @@ void MakeCoordLUT::validateLUTs() {
}
}

CSC_ID = rcscid;

// Set maxWire, maxStrip
const CSCDetId cscDetId = getCSCDetId(endcap, rsector, rsubsector, station, rcscid, is_me11a);
const CSCChamber* chamb = theCSCGeometry_->chamber(cscDetId);
const CSCLayerGeometry* layerGeom = chamb->layer(CSCConstants::KEY_CLCT_LAYER)->geometry();

const int ring = cscDetId.ring();
ring = cscDetId.ring();
const int maxWire = layerGeom->numberOfWireGroups();
const int maxStrip = layerGeom->numberOfStrips();

Expand Down Expand Up @@ -712,6 +731,9 @@ void MakeCoordLUT::validateLUTs() {
int fph = ph_init_full[es][st][ch];
fph = fph + ph_tmp_sign * ph_tmp;

// ph_init_hard is used to calculate zone_hit in the firmware
assert(((fph + (1<<4)) >> 5) >= ph_init_hard[st][ch]);

// ___________________________________________________________________
// theta conversion

Expand Down Expand Up @@ -1023,7 +1045,19 @@ double MakeCoordLUT::getSectorPhi(int endcap, int sector, int subsector, int sta
#ifndef REPRODUCE_OLD_LUTS
// but sector boundary does depend on endcap. apply additional correction to make integer phi 0
// lines up at -22 deg (Jia Fu, 2016-11-12)
sectorStartPhi = (endcap == 2) ? sectorStartPhi + 36./60 : sectorStartPhi + 28./60;
//sectorStartPhi = (endcap == 2) ? sectorStartPhi + 36./60 : sectorStartPhi + 28./60;

// Manually lines up at -22 deg (Jia Fu, 2018-09-19)
double oldSectorStartPhi = sectorStartPhi;
sectorStartPhi = -22. + 15. + (60. * (sector-1));
if (isNeighbor) {
// This chamber comes from the neighbor sector into the native sector
// Use the native sector sectorStartPhi (+60 deg)
sectorStartPhi += 60.;
}
if (sectorStartPhi > 180.)
sectorStartPhi -= 360.;
assert(std::abs(oldSectorStartPhi-sectorStartPhi) < 2.); // sanity check
#endif

double res = deltaPhiInDegrees(globalPhi, sectorStartPhi);
Expand Down
43 changes: 43 additions & 0 deletions L1Trigger/L1TMuonEndCap/test/tools/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

#############################
### EMTF emulator tools ###
#############################

-------------------------------------------------
-- Primitive Conversion Look-Up Table generation
-------------------------------------------------

'PC LUTs' are responsible for converting the CSC LCT strip and wire info into phi and theta coordinates
New PC LUTs can be generated for data (using real CMS geometry) or MC as follows
The latest Global Tag can be found at: https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideFrontierConditions

cd CMSSW_X_Y_Z/src
cmsenv
cd L1Trigger/L1TMuonEndCap/test/tools/
mkdir -p pc_luts/firmware_data ## To store the 924 actual LUTs needed by the firmware
mkdir pc_luts/firmware_MC ## These files are then simplified into 6 text files used by the emulator
cmsRun make_coordlut_data.py ## To create 924 LUTs from real CMSSW geometry, specified by process.GlobalTag
cmsRun make_coordlut_MC.py ## Instead uses ideal CMS geometry / alignment from MC
python write_ph_lut_v2.py ## Modify 'path' in file to specify data or MC

The 6 text files for the emulator will appear in pc_luts/emulator_data or pc_luts/emulator_MC
These can be copied over to the L1Trigger/L1TMuon/data/emtf_luts directory as follows:

cd CMSSW_X_Y_Z/src
git cms-addpkg L1Trigger/L1TMuon
git clone https://github.com/cms-l1t-offline/L1Trigger-L1TMuon.git L1Trigger/L1TMuon/data
mkdir L1Trigger/L1TMuon/data/emtf_luts/ph_lut_new
cp L1Trigger/L1TMuonEndCap/test/tools/pc_luts/emulator_data/* L1Trigger/L1TMuon/data/emtf_luts/ph_lut_new/

The new path can then be added to L1Trigger/L1TMuonEndCap/src/SectorProcessorLUT.cc in the lines containing "ph_lut"

To validate that the coordinate transformation worked properly, you can do the following:

cd L1Trigger/L1TMuonEndCap/test/tools/
root -l pc_luts/firmware_data/validate.root
## EMTF emulator vs. CMS simulation phi or theta coordinate
tree->Draw("fph_emu - fph_sim : fph_sim >> dPh_vs_phi(360,-180,180,80,-0.5,0.5)","","colz")
tree->Draw("fth_emu - fth_sim : fph_sim >> dTh_vs_phi(360,-180,180,80,-1.0,1.0)","","colz")
## Look at a specific region, e.g. ME+1/1a
tree->Draw("fph_emu - fph_sim : fph_sim >> dPh_vs_phi(360,-180,180,80,-0.5,0.5)","(endcap == 1 && station == 1 && ring == 4)","colz")

Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
from __future__ import print_function
import FWCore.ParameterSet.Config as cms

process = cms.Process("Whatever")

#process.load('Configuration.Geometry.GeometryExtended2016Reco_cff')
process.load("Configuration.StandardSequences.GeometryDB_cff") # load from DB
process.load('Configuration.StandardSequences.MagneticField_cff')
process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")

from Configuration.AlCa.GlobalTag import GlobalTag
process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:run2_mc', '')
print("Using GlobalTag: %s" % process.GlobalTag.globaltag.value())
print "Using GlobalTag: %s" % process.GlobalTag.globaltag.value()

# Fake alignment is/should be ideal geometry
# ==========================================
Expand All @@ -26,7 +24,7 @@
verbosity = cms.untracked.int32(1),

# Output diectory
outdir = cms.string("./"),
outdir = cms.string("./pc_luts/firmware_MC/"),

# Produce "validate.root" to validate the LUTs
please_validate = cms.bool(True),
Expand Down
35 changes: 35 additions & 0 deletions L1Trigger/L1TMuonEndCap/test/tools/make_coordlut_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import FWCore.ParameterSet.Config as cms

from Configuration.StandardSequences.Eras import eras

process = cms.Process("Whatever",eras.Run2_2018)

process.load('Configuration.StandardSequences.GeometryRecoDB_cff') # load from DB
process.load('Configuration.StandardSequences.MagneticField_AutoFromDBCurrent_cff')
process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff")

from Configuration.AlCa.GlobalTag import GlobalTag
process.GlobalTag = GlobalTag(process.GlobalTag, '102X_dataRun2_Sep2018Rereco_v1')
print "Using GlobalTag: %s" % process.GlobalTag.globaltag.value()

process.source = cms.Source("EmptyIOVSource",
timetype = cms.string('runnumber'),
firstValue = cms.uint64(321988),
lastValue = cms.uint64(321988),
interval = cms.uint64(1)
)

process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(1))

process.analyzer1 = cms.EDAnalyzer("MakeCoordLUT",
# Verbosity level
verbosity = cms.untracked.int32(1),

# Output diectory
outdir = cms.string("./pc_luts/firmware_data/"),

# Produce "validate.root" to validate the LUTs
please_validate = cms.bool(True),
)

process.path1 = cms.Path(process.analyzer1)
Loading