Skip to content

Commit

Permalink
Merge pull request cms-sw#17 from aperloff/L1PF_10_6_X-AddDumpCOEFiles
Browse files Browse the repository at this point in the history
[L1PF_10_6_X] Add dump and COE File Output
  • Loading branch information
gpetruc authored Jul 30, 2019
2 parents 4f54d2a + 068e1b6 commit 1f4e127
Show file tree
Hide file tree
Showing 8 changed files with 719 additions and 9 deletions.
42 changes: 42 additions & 0 deletions L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef L1Trigger_Phase2L1ParticleFlow_CoeFile_h
#define L1Trigger_Phase2L1ParticleFlow_CoeFile_h

// system include files
#include <vector>
#include <string>
#include <numeric>
#include <boost/dynamic_bitset.hpp>
#include <boost/multiprecision/cpp_int.hpp>

// user include files
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "DataFormats/Phase2L1ParticleFlow/interface/PFCandidate.h"
#include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h"
#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h"

namespace l1tpf_impl {
class COEFile {

public:
COEFile(const edm::ParameterSet&) ;
~COEFile();

void close() { fclose(file); }
template<typename T>
bool getBit(T value, unsigned bit) { return (value >> bit) & 1; }
bool is_open() { return (file != nullptr); }
void writeHeaderToFile();
void writeTracksToFile(const std::vector<Region>& regions, bool print = false);

protected:
FILE *file;
std::string coeFileName, bset_string_;
unsigned int ntracksmax, phiSlices;
static constexpr unsigned int tracksize = 96;
boost::dynamic_bitset<> bset_;
const std::vector<uint32_t> track_word_block_sizes = {14,1,12,16,12,13,4,3,7,14};
int debug_;
};
} // namespace

#endif
8 changes: 4 additions & 4 deletions L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ namespace l1tpf_impl {
const l1t::PFTrack *src;

#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE
static constexpr float INVPT_SCALE = 2E4; // 1%/pt @ 100 GeV is 2 bits
static constexpr float VTX_PHI_SCALE = 1/2.5E-6; // 5 micro rad is 2 bits
static constexpr float VTX_ETA_SCALE = 1/1E-5; // no idea, but assume it's somewhat worse than phi
static constexpr float Z0_SCALE = 20; // 1mm is 2 bits
static constexpr float INVPT_SCALE = 2E4; // 1%/pt @ 100 GeV is 2 bits
static constexpr float VTX_PHI_SCALE = 1/1.6E-3; // 5 micro rad is 2 bits
static constexpr float VTX_ETA_SCALE = 1/1E-4; // no idea, but assume it's somewhat worse than phi
static constexpr float Z0_SCALE = 20; // 1mm is 2 bits
static constexpr int32_t VTX_ETA_1p3 = 1.3 * InputTrack::VTX_ETA_SCALE;

// filling from floating point
Expand Down
11 changes: 9 additions & 2 deletions L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,16 @@ namespace l1tpf_impl {
m.src = nullptr;
}

void writeToFile(const float & pug, FILE * file) {
fwrite(&pug, sizeof(float), 1, file);
}
void readFromFile(float & pug, FILE *file) {
fread(&pug, sizeof(float), 1, file);
}

template<typename T>
void writeManyToFile(const std::vector<T> & objs, FILE *file) {
uint32_t number = objs.size();
uint32_t number = objs.size();
fwrite(&number, 4, 1, file);
for (uint32_t i = 0; i < number; ++i) writeToFile(objs[i], file);
}
Expand All @@ -99,7 +106,7 @@ namespace l1tpf_impl {
void readManyFromFile(std::vector<T> & objs, FILE *file) {
uint32_t number;
fread(&number, 4, 1, file);
objs.resize(number);
objs.resize(number);
for (uint32_t i = 0; i < number; ++i) readFromFile(objs[i], file);
}

Expand Down
58 changes: 58 additions & 0 deletions L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFProducer.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// system include files
#include <memory>
#include <algorithm>
#include <fstream>

// user include files
#include "FWCore/Framework/interface/Frameworkfwd.h"
Expand All @@ -22,13 +23,17 @@
#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo2HGC.h"
#include "L1Trigger/Phase2L1ParticleFlow/interface/PuppiAlgo.h"
#include "L1Trigger/Phase2L1ParticleFlow/interface/LinearizedPuppiAlgo.h"
#include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h"
#include "L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h"

#include "DataFormats/L1TrackTrigger/interface/L1TkMuonParticle.h"
#include "DataFormats/L1TrackTrigger/interface/L1TkMuonParticleFwd.h"

//--------------------------------------------------------------------------------------------------
class L1TPFProducer : public edm::stream::EDProducer<> {
public:
explicit L1TPFProducer(const edm::ParameterSet&);
~L1TPFProducer();

private:
int debug_;
Expand All @@ -55,6 +60,12 @@ class L1TPFProducer : public edm::stream::EDProducer<> {
std::unique_ptr<l1tpf_impl::PFAlgoBase> l1pfalgo_;
std::unique_ptr<l1tpf_impl::PUAlgoBase> l1pualgo_;

edm::EDGetTokenT<math::XYZPointF> TokGenOrigin_;

// Region dump/coe
FILE *fRegionDump;
l1tpf_impl::COEFile *fRegionCOE;
unsigned int neventscoemax, neventsproduced;

// region of interest debugging
float debugEta_, debugPhi_, debugR_;
Expand All @@ -81,6 +92,8 @@ L1TPFProducer::L1TPFProducer(const edm::ParameterSet& iConfig):
l1regions_(iConfig),
l1pfalgo_(nullptr),
l1pualgo_(nullptr),
fRegionDump(nullptr),
fRegionCOE(nullptr),
debugEta_(iConfig.getUntrackedParameter<double>("debugEta",0)),
debugPhi_(iConfig.getUntrackedParameter<double>("debugPhi",0)),
debugR_(iConfig.getUntrackedParameter<double>("debugR",-1))
Expand Down Expand Up @@ -133,6 +146,25 @@ L1TPFProducer::L1TPFProducer(const edm::ParameterSet& iConfig):
for (const std::string & label : l1pualgo_->puGlobalNames()) {
produces<float>(label);
}

std::string dumpFileName = iConfig.getUntrackedParameter<std::string>("dumpFileName", "");
if (!dumpFileName.empty()) {
fRegionDump = fopen(dumpFileName.c_str(), "wb");
TokGenOrigin_ = consumes<math::XYZPointF>(iConfig.getParameter<edm::InputTag>("genOrigin"));
}
std::string coeFileName = iConfig.getUntrackedParameter<std::string>("coeFileName", "");
if (!coeFileName.empty()) {
fRegionCOE = new l1tpf_impl::COEFile(iConfig);
neventscoemax = iConfig.getUntrackedParameter<unsigned int>("neventscoemax");
neventsproduced = 0;
}
}

L1TPFProducer::~L1TPFProducer() {
// do anything here that needs to be done at desctruction time
// (e.g. close files, deallocate resources etc.)
if (fRegionDump) fclose(fRegionDump);
if (fRegionCOE) fRegionCOE->close();
}

// ------------ method called to produce the data ------------
Expand Down Expand Up @@ -206,6 +238,21 @@ L1TPFProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
iEvent.put(l1regions_.fetchCalo(/*ptmin=*/0.1, /*em=*/true), "EmCalo");
iEvent.put(l1regions_.fetchCalo(/*ptmin=*/0.1, /*em=*/false), "Calo");
iEvent.put(l1regions_.fetchTracks(/*ptmin=*/0.0, /*fromPV=*/false), "TK");
if (fRegionDump) {
uint32_t run = iEvent.id().run(), lumi = iEvent.id().luminosityBlock(); uint64_t event = iEvent.id().event();
fwrite(&run, sizeof(uint32_t), 1, fRegionDump);
fwrite(&lumi, sizeof(uint32_t), 1, fRegionDump);
fwrite(&event, sizeof(uint64_t), 1, fRegionDump);
l1tpf_impl::writeManyToFile(l1regions_.regions(), fRegionDump);
}

// Then save the regions to the COE file
// Do it here because there is some sorting going on in a later function
if (fRegionCOE && fRegionCOE->is_open() && neventsproduced<neventscoemax) {
std::vector<l1tpf_impl::Region> regions = l1regions_.regions();
fRegionCOE->writeTracksToFile(regions,neventsproduced==0);
}
neventsproduced++;

// Then do the vertexing, and save it out
float z0;
Expand All @@ -222,6 +269,14 @@ L1TPFProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
}
l1pualgo_->doVertexing(l1regions_.regions(), vtxAlgo_, z0);
iEvent.put(std::make_unique<float>(z0), "z0");
if (fRegionDump) {
fwrite(&z0, sizeof(float), 1, fRegionDump);
edm::Handle<math::XYZPointF> hGenOrigin;
iEvent.getByToken(TokGenOrigin_,hGenOrigin);
const math::XYZPointF & genOrigin = *hGenOrigin;
float genZ = genOrigin.Z();
fwrite(&genZ, sizeof(float), 1, fRegionDump);
}

// Then also save the tracks with a vertex cut
iEvent.put(l1regions_.fetchTracks(/*ptmin=*/0.0, /*fromPV=*/true), "TKVtx");
Expand All @@ -242,6 +297,9 @@ L1TPFProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
for (unsigned int i = 0, n = puGlobalNames.size(); i < n; ++i) {
iEvent.put(std::make_unique<float>(puGlobals[i]), puGlobalNames[i]);
}
if (fRegionDump) {
l1tpf_impl::writeManyToFile(puGlobals, fRegionDump);
}

// Then run puppi (regionally)
for (auto & l1region : l1regions_.regions()) {
Expand Down
39 changes: 36 additions & 3 deletions L1Trigger/Phase2L1ParticleFlow/python/l1ParticleFlow_cff.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,24 +131,39 @@
trackRegionMode = cms.string("atCalo"),
regions = cms.VPSet(
cms.PSet(
etaBoundaries = cms.vdouble(-3,-1.5),
etaBoundaries = cms.vdouble(-2.5,-1.5),
phiSlices = cms.uint32(1),
etaExtra = cms.double(0.3),
phiExtra = cms.double(0.0)
),
cms.PSet(
etaBoundaries = cms.vdouble(1.5,3.0),
etaBoundaries = cms.vdouble(1.5,2.5),
phiSlices = cms.uint32(1),
etaExtra = cms.double(0.3),
phiExtra = cms.double(0.0)
),
),
)
l1pfProducerHGCal.linking.trackCaloDR = 0.1 # more precise cluster positions
l1pfProducerHGCalNoTK = l1pfProducerHGCal.clone(regions = cms.VPSet(
cms.PSet(
etaBoundaries = cms.vdouble(-3,-2.5),
phiSlices = cms.uint32(1),
etaExtra = cms.double(0.3),
phiExtra = cms.double(0.0)
),
cms.PSet(
etaBoundaries = cms.vdouble(2.5,3),
phiSlices = cms.uint32(1),
etaExtra = cms.double(0.3),
phiExtra = cms.double(0.0)
),
))

l1ParticleFlow_pf_hgcal = cms.Sequence(
pfTracksFromL1TracksHGCal +
l1pfProducerHGCal
l1pfProducerHGCal +
l1pfProducerHGCalNoTK
)


Expand Down Expand Up @@ -204,11 +219,29 @@
)


# PF in the TSA Region
l1pfProducerTSA = l1pfProducerBarrel.clone(
trackRegionMode = cms.string("atVertex"),
regions = cms.VPSet(
cms.PSet(
etaBoundaries = cms.vdouble(-3,3),
phiSlices = cms.uint32(18),
etaExtra = cms.double(0.0),
phiExtra = cms.double(0.0)
),
),
)
l1ParticleFlow_pf_tsa = cms.Sequence(
pfTracksFromL1TracksBarrel +
l1pfProducerTSA
)

# Merging all outputs
l1pfCandidates = cms.EDProducer("L1TPFCandMultiMerger",
pfProducers = cms.VInputTag(
cms.InputTag("l1pfProducerBarrel"),
cms.InputTag("l1pfProducerHGCal"),
cms.InputTag("l1pfProducerHGCalNoTK"),
cms.InputTag("l1pfProducerHF")
),
labelsToMerge = cms.vstring("Calo", "TK", "TKVtx", "PF", "Puppi"),
Expand Down
88 changes: 88 additions & 0 deletions L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h"

using namespace l1tpf_impl;

COEFile::COEFile(const edm::ParameterSet& iConfig) :
file(nullptr),
coeFileName(iConfig.getUntrackedParameter<std::string>("coeFileName", "")),
bset_string_(""),
ntracksmax(iConfig.getUntrackedParameter<unsigned int>("ntracksmax")),
phiSlices(iConfig.getParameter<std::vector<edm::ParameterSet>>("regions")[0].getParameter<uint32_t>("phiSlices")),
debug_(iConfig.getUntrackedParameter<int>("debug",0))
{
file = fopen(coeFileName.c_str(), "w");
writeHeaderToFile();
bset_.resize(tracksize);
}

void COEFile::writeHeaderToFile() {
char depth_width[256];
sprintf(depth_width, "; of depth=%i, and width=%i. In this case, values are specified\n",ntracksmax,tracksize*phiSlices);
std::vector<std::string> vheader = {"; Sample memory initialization file for Dual Port Block Memory,\n",
"; v3.0 or later.\n",
"; Board: VCU118\n",
"; tmux: 1\n",
";\n",
"; This .COE file specifies the contents for a block memory\n",
std::string(depth_width),
"; in binary format.\n",
"memory_initialization_radix=2;\n",
"memory_initialization_vector=\n"};
for (uint32_t i=0; i<vheader.size(); ++i) fprintf(file, vheader[i].c_str());
}

void COEFile::writeTracksToFile(const std::vector<Region>& regions, bool print) {
PropagatedTrack current_track;
bool has_track = false;
for (unsigned int irow = 0; irow < ntracksmax; irow++) {
for (unsigned int icol = 0; icol < regions.size(); icol++) {
if (regions[icol].track.size()<=irow) has_track = false;
else has_track = true;

if (has_track) {
// select the track that will be converted to a bit string
current_track = regions[icol].track[irow];

// convert the values in a PropogatedTrack to a 96-bit track word
for (unsigned int iblock=0; iblock<track_word_block_sizes.size(); iblock++) {
for (unsigned int ibit=0; ibit<track_word_block_sizes[iblock]; ibit++) {
int offset = std::accumulate(track_word_block_sizes.begin(), track_word_block_sizes.begin()+iblock, 0);
switch(iblock) {
case 0 : bset_.set(ibit+offset,getBit<uint16_t>(current_track.hwPt,ibit)); break;
case 1 : bset_.set(ibit+offset,current_track.hwCharge); break;
case 2 : bset_.set(ibit+offset,getBit<uint16_t>(current_track.hwVtxPhi,ibit)); break;
case 3 : bset_.set(ibit+offset,getBit<uint16_t>(current_track.hwVtxEta,ibit)); break;
case 4 : bset_.set(ibit+offset,getBit<uint16_t>(current_track.hwZ0,ibit)); break;
case 5 : bset_.set(ibit+offset,0); break;
case 6 : bset_.set(ibit+offset,getBit<uint16_t>(current_track.hwChi2,ibit)); break;
case 7 : bset_.set(ibit+offset,0); break;
case 8 : bset_.set(ibit+offset,getBit<uint16_t>(current_track.hwStubs,ibit)); break;
case 9 : bset_.set(ibit+offset,0); break;
}
}
}

// print the track word to the COE file
boost::to_string(bset_,bset_string_);
fprintf(file, "%s", bset_string_.c_str());

// print some debugging information
if (debug_ && print && irow==0 && icol==0) {
printf("region: eta=[%f,%f] phi=%f+/-%f\n",regions[icol].etaMin,regions[icol].etaMax,regions[icol].phiCenter,regions[icol].phiHalfWidth);
printf("l1t::PFTrack (pT,eta,phi) [float] = (%f,%f,%f)\n",current_track.src->p4().Pt(),current_track.src->p4().Eta(),current_track.src->p4().Phi());
printf("l1t::PFTrack (pT,eta,phi) [int] = (%i,%i,%i)\n",current_track.src->hwPt(),current_track.src->hwEta(),current_track.src->hwPhi());
printf("l1tpf_impl::PropagatedTrack (1/pT,eta,phi) [int,10] = (%i,%i,%i)\n",current_track.hwPt,current_track.hwVtxEta,current_track.hwVtxPhi);
printf("l1tpf_impl::PropagatedTrack (1/pT,eta,phi) [int,2] = (%s,%s,%s)\n",std::bitset<16>(current_track.hwPt).to_string().c_str(),std::bitset<32>(current_track.hwVtxEta).to_string().c_str(),std::bitset<32>(current_track.hwVtxPhi).to_string().c_str());
printf("bitset = %s\n",bset_string_.c_str());
}
}
else {
bset_.reset();
boost::to_string(bset_,bset_string_);
fprintf(file, "%s", bset_string_.c_str());
}
}
fprintf(file, (irow==ntracksmax-1) ? ";\n" : ",\n");
}
}

9 changes: 9 additions & 0 deletions L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<bin name = "testOutputFiles" file="testOutputFiles.cpp">
<flags TEST_RUNNER_CMD="cd $(CMSSW_BASE)/src/L1Trigger/Phase2L1ParticleFlow/test; testOutputFiles Phase2L1ParticleFlowOutput.root trackerRegion_alltracks_sectors_2x9_TTbar_PU200.dump trackerRegion_alltracks_sectors_2x9_TTbar_PU200.coe 0 0 9 -3 0 3"/>
<use name="root"/>
<use name="FWCore/FWLite"/>
<use name="FWCore/Utilities"/>
<use name="DataFormats/FWLite"/>
<use name="DataFormats/Phase2L1ParticleFlow"/>
<use name="L1Trigger/Phase2L1ParticleFlow"/>
</bin>
Loading

0 comments on commit 1f4e127

Please sign in to comment.