From 03f81190bbe24fd57d593a84b1c5e4801fc2f383 Mon Sep 17 00:00:00 2001 From: Alexx Perloff Date: Fri, 19 Jul 2019 09:05:06 -0500 Subject: [PATCH 1/2] This commit adds back the ability to save a regionized binary (.dump) file for storing events. It also adds the new ability to store a track only text-based (.coe) file. There is a new executable which will compare the ROOT, dump, and COE files for consistency. This new executable can be run with 'scram b runtests'. This is a combination of 10 commits that are being squashed into a single commit. Not only is this cleaner, but some files were committed which are not being removed from the history. In order to preserve the more granular commit history the 10 messages below show the individual commit messages: - Add the Xilinx arbitrary precision int and float types from Vivado 2019.1. - Add back the ability to save a regionized binary (.dump) file for storing events as well as the new ability to store a track only text-based (.coe) file. - Add a new executable for testing the various output formats for PF. It will compare the ROOT, dump, and COE files. It can be run with 'scram b runtests'. - Slightly modify the configuration of the regions and add in a track standalone (TSA) region. - Rename the code that tests the output files from the L1TPFProducer. - Return the spacing back to it's original state before the most recent PR. - Remove the l1ParticleFlow_pf_tsa module from the default sequence. - Slightly modify the compare_lv_with_tolerance function signature. - Remove all references to ap_int and instead use boost and std objects/functions for converting between std ints and binary representations. Also move the COE file handling to a separate class. - Remove the ap_int, ap_fixed, and associated headers. These will be included in CMSSW some other way. --- .../Phase2L1ParticleFlow/interface/COEFile.h | 42 ++ .../interface/DiscretePFInputs.h | 8 +- .../interface/DiscretePFInputsIO.h | 11 +- .../plugins/L1TPFProducer.cc | 58 +++ .../python/l1ParticleFlow_cff.py | 39 +- L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc | 87 ++++ .../Phase2L1ParticleFlow/test/BuildFile.xml | 9 + .../test/testOutputFiles.cpp | 455 ++++++++++++++++++ 8 files changed, 700 insertions(+), 9 deletions(-) create mode 100644 L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h create mode 100644 L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc create mode 100644 L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml create mode 100644 L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h b/L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h new file mode 100644 index 0000000000000..942a345a3a7ad --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h @@ -0,0 +1,42 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_CoeFile_h +#define L1Trigger_Phase2L1ParticleFlow_CoeFile_h + +// system include files +#include +#include +#include +#include +#include + +// 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 + bool getBit(T value, unsigned bit) { return (value >> bit) & 1; } + bool is_open() { return (file != nullptr); } + void writeHeaderToFile(); + void writeTracksToFile(const std::vector& 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 track_word_block_sizes = {14,1,12,16,12,13,4,3,7,14}; + int debug_; + }; +} // namespace + +#endif \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h b/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h index 48fa2071379f2..09d0a32e26e90 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h @@ -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 diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h b/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h index 366b22a62c517..b5506b2ac8aa5 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h @@ -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 void writeManyToFile(const std::vector & 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); } @@ -99,7 +106,7 @@ namespace l1tpf_impl { void readManyFromFile(std::vector & 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); } diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFProducer.cc index 7eb9638996d65..54c6f3bf7bc86 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFProducer.cc @@ -1,6 +1,7 @@ // system include files #include #include +#include // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" @@ -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_; @@ -55,6 +60,12 @@ class L1TPFProducer : public edm::stream::EDProducer<> { std::unique_ptr l1pfalgo_; std::unique_ptr l1pualgo_; + edm::EDGetTokenT TokGenOrigin_; + + // Region dump/coe + FILE *fRegionDump; + l1tpf_impl::COEFile *fRegionCOE; + unsigned int neventscoemax, neventsproduced; // region of interest debugging float debugEta_, debugPhi_, debugR_; @@ -81,6 +92,8 @@ L1TPFProducer::L1TPFProducer(const edm::ParameterSet& iConfig): l1regions_(iConfig), l1pfalgo_(nullptr), l1pualgo_(nullptr), + fRegionDump(nullptr), + fRegionCOE(nullptr), debugEta_(iConfig.getUntrackedParameter("debugEta",0)), debugPhi_(iConfig.getUntrackedParameter("debugPhi",0)), debugR_(iConfig.getUntrackedParameter("debugR",-1)) @@ -133,6 +146,25 @@ L1TPFProducer::L1TPFProducer(const edm::ParameterSet& iConfig): for (const std::string & label : l1pualgo_->puGlobalNames()) { produces(label); } + + std::string dumpFileName = iConfig.getUntrackedParameter("dumpFileName", ""); + if (!dumpFileName.empty()) { + fRegionDump = fopen(dumpFileName.c_str(), "wb"); + TokGenOrigin_ = consumes(iConfig.getParameter("genOrigin")); + } + std::string coeFileName = iConfig.getUntrackedParameter("coeFileName", ""); + if (!coeFileName.empty()) { + fRegionCOE = new l1tpf_impl::COEFile(iConfig); + neventscoemax = iConfig.getUntrackedParameter("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 ------------ @@ -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 regions = l1regions_.regions(); + fRegionCOE->writeTracksToFile(regions,neventsproduced==0); + } + neventsproduced++; // Then do the vertexing, and save it out float z0; @@ -222,6 +269,14 @@ L1TPFProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { } l1pualgo_->doVertexing(l1regions_.regions(), vtxAlgo_, z0); iEvent.put(std::make_unique(z0), "z0"); + if (fRegionDump) { + fwrite(&z0, sizeof(float), 1, fRegionDump); + edm::Handle 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"); @@ -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(puGlobals[i]), puGlobalNames[i]); } + if (fRegionDump) { + l1tpf_impl::writeManyToFile(puGlobals, fRegionDump); + } // Then run puppi (regionally) for (auto & l1region : l1regions_.regions()) { diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ParticleFlow_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ParticleFlow_cff.py index e7299cf4e0b51..5d861a43f5087 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ParticleFlow_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ParticleFlow_cff.py @@ -131,13 +131,13 @@ 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) @@ -145,10 +145,25 @@ ), ) 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 ) @@ -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"), diff --git a/L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc b/L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc new file mode 100644 index 0000000000000..e9a6494519354 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc @@ -0,0 +1,87 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h" + +using namespace l1tpf_impl; + +COEFile::COEFile(const edm::ParameterSet& iConfig) : + file(nullptr), + coeFileName(iConfig.getUntrackedParameter("coeFileName", "")), + bset_string_(""), + ntracksmax(iConfig.getUntrackedParameter("ntracksmax")), + phiSlices(iConfig.getParameter>("regions")[0].getParameter("phiSlices")), + debug_(iConfig.getUntrackedParameter("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 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& 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(current_track.hwPt,ibit)); break; + case 1 : bset_.set(ibit+offset,current_track.hwCharge); break; + case 2 : bset_.set(ibit+offset,getBit(current_track.hwVtxPhi,ibit)); break; + case 3 : bset_.set(ibit+offset,getBit(current_track.hwVtxEta,ibit)); break; + case 4 : bset_.set(ibit+offset,getBit(current_track.hwZ0,ibit)); break; + case 5 : bset_.set(ibit+offset,0); break; + case 6 : bset_.set(ibit+offset,getBit(current_track.hwChi2,ibit)); break; + case 7 : bset_.set(ibit+offset,0); break; + case 8 : bset_.set(ibit+offset,getBit(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("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"); + } +} + diff --git a/L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml b/L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml new file mode 100644 index 0000000000000..07f2879fbe9cf --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp b/L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp new file mode 100644 index 0000000000000..7d49dcf987b24 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp @@ -0,0 +1,455 @@ +// STL includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// ROOT includes +#include "TROOT.h" +#include "TSystem.h" +#include "TFile.h" +#include "TTree.h" +#include "TLorentzVector.h" + +// CMSSW includes +#include "FWCore/FWLite/interface/FWLiteEnabler.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "DataFormats/FWLite/interface/Handle.h" +#include "DataFormats/FWLite/interface/Run.h" +#include "DataFormats/FWLite/interface/LuminosityBlock.h" +#include "DataFormats/FWLite/interface/Event.h" +#include "DataFormats/Phase2L1ParticleFlow/interface/PFTrack.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h" + +#define NTEST 64 +#define REPORT_EVERY_N 50 +#define NTRACKS_PER_SECTOR 110 +#define NBITS_PER_TRACK 96 +static unsigned int N_IN_SECTORS(0); +static std::vector SECTOR_BOUNDARIES; + +typedef l1tpf_impl::InputRegion Region; +typedef std::pair SectorTrackIndex; +typedef std::map TrackMap; + +struct Event { + uint32_t run, lumi; uint64_t event; + float z0, genZ0; + std::vector puGlobals; // [float] alphaCMed, alphaCRms, alphaFMed, alphaFRms + std::vector regions; + + Event() : run(0), lumi(0), event(0), z0(0.), regions() {} + bool readFromFile(FILE *fRegionDump) { + if (!fread(&run, sizeof(uint32_t), 1, fRegionDump)) return false; + fread(&lumi, sizeof(uint32_t), 1, fRegionDump); + fread(&event, sizeof(uint64_t), 1, fRegionDump); + l1tpf_impl::readManyFromFile(regions, fRegionDump); + fread(&z0, sizeof(float), 1, fRegionDump); + fread(&genZ0, sizeof(float), 1, fRegionDump); + l1tpf_impl::readManyFromFile(puGlobals, fRegionDump); + return true; + } +}; + +TLorentzVector* makeTLorentzVectorPtEtaPhiE(float pt, float eta, float phi, float e) { + TLorentzVector* v = new TLorentzVector(); + v->SetPtEtaPhiE(pt,eta,phi,e); + return v; +} + +/* + * Convert a bitset to a signed int64_t. + * std::bitset has built-ins for ulong and ullong. + */ +template 0 && N < 64)>> +int64_t to_int64_from_bitset(const std::bitset& b) { + int const shift = 64 - N; + return (((int64_t)b.to_ullong() << shift) >> shift); +} + +/* + * Generic implementation to search if a given value exists in a map or not. + * Adds all the keys with given value in the vector + */ +template +bool findAllInRegion(std::vector & vec, std::map mapOfElemen, T value) { + bool bResult = false; + auto it = mapOfElemen.begin(); + // Iterate through the map + while(it != mapOfElemen.end()) + { + // Check if value of this entry matches with given value + if(it->first.first == value) + { + // Yes found + bResult = true; + // Push the key in given map + vec.push_back(it->first); + } + // Go to next entry in map + it++; + } + return bResult; +} + +TrackMap get_tracks_from_root_file(fwlite::Event& ev, int entry = 0, bool print = false) { + TrackMap tracks_root, tracks_tmp; + + // go to the event under test + if (!ev.to(entry)) { + std::cerr << "ERROR::testDumpFile::get_tracks_from_root_file Unable to load the event at entry " << entry << std::endl; + assert(ev.to(entry)); + } + if (print) printf("ROOT::Run %u, lumi %u, event %llu \n", ev.getRun().id().run(), ev.getLuminosityBlock().id().luminosityBlock(), ev.eventAuxiliary().id().event()); + + edm::InputTag trackLabel ("pfTracksFromL1TracksBarrel"); + edm::Handle< std::vector> h_track; + ev.getByLabel(trackLabel, h_track); + assert( h_track.isValid() ); + + int ntrackstotal(0); + auto kTrackEnd = h_track->end(); + for (auto trackIter = h_track->begin(); trackIter != kTrackEnd; ++trackIter) { + if (trackIter->pt() <= 2.0 || trackIter->nStubs() < 4 || trackIter->normalizedChi2() >= 15.0) continue; + int sector_index = (std::lower_bound(SECTOR_BOUNDARIES.begin(), SECTOR_BOUNDARIES.end(), trackIter->phi())-SECTOR_BOUNDARIES.begin())-1; + tracks_tmp[std::make_pair(sector_index,ntrackstotal)] = makeTLorentzVectorPtEtaPhiE(trackIter->pt(),trackIter->eta(),trackIter->phi(),trackIter->pt()); + //if (print) printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", ntrackstotal, trackIter->pt(), trackIter->eta(), trackIter->phi()); + ntrackstotal++; + } + for (unsigned int is = 0; is < N_IN_SECTORS; ++is) { + std::vector tracks_in_sector; + findAllInRegion(tracks_in_sector,tracks_tmp,is); + if (print) printf("\tFound region %u [%0.2f,%0.2f] with %lu tracks\n", is, SECTOR_BOUNDARIES[is], SECTOR_BOUNDARIES[is+1], tracks_in_sector.size()); + for (unsigned int it=0; itPt(), tracks_tmp[tracks_in_sector[it]]->Eta(), tracks_tmp[tracks_in_sector[it]]->Phi()); + tracks_root[std::make_pair(is,it)] = tracks_tmp[tracks_in_sector[it]]; + } + } + if (print) { + printf("\t================================= \n"); + printf("\tTotal tracks %u \n\n", ntrackstotal); + } + + return tracks_root; +} + +std::map,TLorentzVector*> get_tracks_from_dump_file(FILE *dfile_ = nullptr, bool print = false) { + std::map,TLorentzVector*> tracks_dump; + Event event_; + + if (feof(dfile_)) { + std::cerr << "ERROR::testDumpFile::get_tracks_from_dump_file We have already reached the end of the dump file" << std::endl; + assert(!feof(dfile_)); + } + if (!event_.readFromFile(dfile_)) { + std::cerr << "ERROR::testDumpFile::get_tracks_from_dump_file Something went wrong reading from the dump file" << std::endl; + assert(event_.readFromFile(dfile_)); + } + if (event_.regions.size() != N_IN_SECTORS) { + printf("ERROR::testDumpFile::get_tracks_from_dump_file Mismatching number of input regions: %lu\n", event_.regions.size()); + assert(event_.regions.size() == N_IN_SECTORS); + } + if (print) printf("Dump::Run %u, lumi %u, event %lu, regions %lu \n", event_.run, event_.lumi, event_.event, event_.regions.size()); + + unsigned int ntrackstotal(0); + float maxabseta(0), maxz(0), minz(0); + + int pv_gen = round(event_.genZ0 * l1tpf_impl::InputTrack::Z0_SCALE); + int pv_cmssw = round(event_.z0 * l1tpf_impl::InputTrack::Z0_SCALE); + + for (unsigned int is = 0; is < N_IN_SECTORS; ++is) { + const Region & r = event_.regions[is]; + if (print) printf("\tRead region %u [%0.2f,%0.2f] with %lu tracks\n", is, r.phiCenter-r.phiHalfWidth, r.phiCenter+r.phiHalfWidth, r.track.size()); + ntrackstotal+=r.track.size(); + for (unsigned int it=0; it maxabseta) maxabseta = abs(r.track[it].hwVtxEta); + if(r.track[it].hwZ0 > maxz) maxz = r.track[it].hwZ0; + if(r.track[it].hwZ0 < minz) minz = r.track[it].hwZ0; + if (print) printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", it, r.track[it].floatVtxPt(), r.track[it].floatVtxEta(), r.track[it].floatVtxPhi()); + } + } + + if (print) { + printf("\t================================= \n"); + printf("\tTotal tracks %u \n", ntrackstotal); + printf("\tMax abs(eta) %.2f [hw units] \n", maxabseta); + printf("\tMax abs(eta) %.4f \n", maxabseta/l1tpf_impl::InputTrack::VTX_ETA_SCALE); + printf("\t[Min,max] track z0 [%.2f,%.2f] [hw units] \n", minz, maxz); + printf("\t[Min,max] track z0 [%.2f,%.2f] [cm] \n", minz/l1tpf_impl::InputTrack::Z0_SCALE, maxz/l1tpf_impl::InputTrack::Z0_SCALE); + printf("\tPV (GEN) %u \n", pv_gen); + printf("\tPV (CMSSW) %u \n\n", pv_cmssw); + } + + return tracks_dump; +} + +std::map,TLorentzVector*> get_tracks_from_coe_file(std::ifstream &cfile_, bool print = false, bool debug = false) { + std::map,TLorentzVector*> tracks_coe; + std::string bset_string_; + int ntrackstotal(0); + bool skip(false); + + // check that we haven't reached the end of the file (i.e. there a more events to be read out) + if (cfile_.eof()) { + std::cerr << "ERROR::testDumpFile::get_tracks_from_coe_file We have already reached the end of the coe file" << std::endl; + assert(!cfile_.eof()); + } + if (print) printf("COE::Run \"unknown\", lumi \"unknown\", event \"unknown\", regions %u? \n", N_IN_SECTORS); + + // read the lines one by one + for (unsigned int iline=0; iline bset_(bset_string_); + if (bset_.none()) { + skip = true; + continue; + } + else { + skip = false; + } + + std::bitset<14> hwPt; std::bitset<16> hwVtxEta; std::bitset<12> hwVtxPhi; + for (int i=14-1; i>=0; i--) {hwPt.set(i,bset_[i]);} + for (int i=12-1; i>=0; i--) {hwVtxPhi.set(i,bset_[i+15]);} + for (int i=16-1; i>=0; i--) {hwVtxEta.set(i,bset_[i+27]);} + float hwVtxPt_f = (float(hwPt.to_ulong()) / l1tpf_impl::CaloCluster::PT_SCALE); + float hwVtxEta_f = float(to_int64_from_bitset(hwVtxEta)) / l1tpf_impl::InputTrack::VTX_ETA_SCALE; + float hwVtxPhi_f = float(to_int64_from_bitset(hwVtxPhi)) / l1tpf_impl::InputTrack::VTX_PHI_SCALE; + + if (debug) { + std::cout << "bset_string_ = " << bset_string_ << std::endl; + std::cout << "\thwPt (0b) = " << std::flush; for (int i=14-1; i>=0; i--) {std::cout << bset_[i] << std::flush;} std::cout << std::endl; + std::cout << "\thwVtxPhi (0b) = " << std::flush; for (int i=12-1; i>=0; i--) {std::cout << bset_[i+15] << std::flush;} std::cout << std::endl; + std::cout << "\thwVtxEta (0b) = " << std::flush; for (int i=16-1; i>=0; i--) {std::cout << bset_[i+27] << std::flush;} std::cout << std::endl; + std::cout << "\thwPt (int) = " << hwPt.to_ulong() << std::endl; + std::cout << "\thwVtxPhi (int) = " << to_int64_from_bitset(hwVtxPhi) << std::endl; + std::cout << "\thwVtxEta (int) = " << to_int64_from_bitset(hwVtxEta) << std::endl; + std::cout << "\thwVtxPt_f (float) = " << hwVtxPt_f << std::endl; + std::cout << "\thwVtxPhi_f (float) = " << hwVtxPhi_f << std::endl; + std::cout << "\thwVtxEta_f (float) = " << hwVtxEta_f << std::endl; + } + + if (bset_.any()) { + ntrackstotal++; + tracks_coe[std::make_pair(isector,iline)] = makeTLorentzVectorPtEtaPhiE(hwVtxPt_f,hwVtxEta_f,hwVtxPhi_f,hwVtxPt_f); + //if (print) printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", it, hwPt_f, hwVtxEta_f, hwVtxPhi_f); + } + } + + // remove the trailing character + bset_string_.resize(2); + cfile_.read(&bset_string_[0],2); + if (debug && !skip) std::cout << "bset_string_ = " << bset_string_ << std::endl; + if (bset_string_!=",\n" && bset_string_!=";\n") { + std::cerr << "ERROR::testDumpFile::get_tracks_from_coe_file Something went wrong reading line " << 11+iline << " of the COE file" << std::endl + << "\tThe line should have ended with \',\' or \';\', but instead ended with \'" << bset_string_ << "\'" << std::endl; + assert(bset_string_!="," || bset_string_!=";"); + } + + } + for (unsigned int is = 0; is < N_IN_SECTORS; ++is) { + std::vector tracks_in_sector; + findAllInRegion(tracks_in_sector,tracks_coe,is); + if (print) printf("\tRead region %u [%0.2f,%0.2f] with %lu tracks\n", is, SECTOR_BOUNDARIES[is], SECTOR_BOUNDARIES[is+1], tracks_in_sector.size()); + for (unsigned int it=0; itPt(), tracks_coe[tracks_in_sector[it]]->Eta(), tracks_coe[tracks_in_sector[it]]->Phi()); + } + } + + if (print) { + printf("\t================================= \n"); + printf("\tTotal tracks %u \n\n", ntrackstotal); + } + + return tracks_coe; +} + +std::ifstream& GotoLine(std::ifstream& file, unsigned int num){ + file.seekg(std::ios::beg); + for(unsigned int i=0; i < num - 1; ++i){ + file.ignore(std::numeric_limits::max(),'\n'); + } + return file; +} + +bool compare_lv_with_tolerance(TLorentzVector a, TLorentzVector b, const std::vector& tolerance = {0,0,0,0}) { + /* + Example (Tolerance = 0.0005): + Track from ROOT file: pt=16.3452797 + InputTrack::INVPT_SCALE = 2E4 + std::numeric_limits::max() = 65535 + hwInvpt = std::min(round(1/pt * InputTrack::INVPT_SCALE), std::numeric_limits::max()) = 1224.0000 + floatVtxPt() = 1/(float(hwInvpt) / InputTrack::INVPT_SCALE) = 16.339869 + So loss of precision comes from rounding + Difference is DeltaPt=0.00541114807 + */ + if (abs(a.Pt()-b.Pt())>tolerance[0] || abs(a.Eta()-b.Eta())>tolerance[1] || abs(a.Phi()-b.Phi())>tolerance[2] || abs(a.E()-b.E())>tolerance[3]) { + std::cerr<tolerance[0]) std::cerr << "pT! " << a.Pt() << " vs " << b.Pt() << " where DeltaPt=" << abs(a.Pt()-b.Pt()) << " and epsilon=" << tolerance[0] << std::endl; + else if (abs(a.Eta()-b.Eta())>tolerance[1]) std::cerr << "eta! " << a.Eta() << " vs " << b.Eta() << " where DeltaEta=" << abs(a.Eta()-b.Eta()) << " and epsilon=" << tolerance[1] << std::endl; + else if (abs(a.Phi()-b.Phi())>tolerance[2]) std::cerr << "phi! " << a.Phi() << " vs " << b.Phi() << " where DeltaPhi=" << abs(a.Phi()-b.Phi()) << " and epsilon=" << tolerance[2] << std::endl; + else if (abs(a.E()-b.E())>tolerance[3]) std::cerr << "E! " << a.E() << " vs " << b.E() << " where DeltaE=" << abs(a.E()-b.E()) << " and epsilon=" << tolerance[3] << std::endl; + return false; + } + return true; +} + +bool compare_maps(TrackMap ref, TrackMap test) { + TLorentzVector tlv; + for (auto it=ref.begin(); it!=ref.end(); it++) { + if (test.find(it->first)==test.end()) { + std::cerr << std::endl << "\tERROR::compare_maps Can't find the test track with (sector,index)=(" << it->first.first << "," << it->first.second << ")" << std::endl; + return false; + } + tlv = *(test.find(it->first)->second); + // The pT tolerance should be 1.0/l1tpf_impl::CaloCluster::PT_SCALE, but because of the rounding this is not true and the actual resolution isn't always as good + // Instead, we will use max(1% of the pT of the reference TLorentzVector,0.25) + // We use the max statement because at low pT, the 1% definition doesn't hold anymore. This wouldn't be a problem if 1/pT were encoded rather than pT. + if (!compare_lv_with_tolerance(*(it->second),tlv,{float(std::max(it->second->Pt()*1E-2,1.0/l1tpf_impl::CaloCluster::PT_SCALE)),1.0/l1tpf_impl::InputTrack::VTX_ETA_SCALE,1.0/l1tpf_impl::InputTrack::VTX_PHI_SCALE,float(std::max(it->second->Pt()*1E-2,1.0/l1tpf_impl::CaloCluster::PT_SCALE))})) { + std::cerr << std::endl << "\tERROR::compare_maps Can't find the test track with TLorentzVector (" << it->second->Pt() << "," << it->second->Eta() << "," << it->second->Phi() << "," << it->second->E() << ")" << std::endl + << "\t\tInstead found (" << tlv.Pt() << "," << tlv.Eta() << "," << tlv.Phi() << "," << tlv.E() << ") at the position (sector,index)=(" << it->first.first << "," << it->first.second << ")" << std::endl; + return false; + } + } + return true; +} + +int main(int argc, char *argv[]) { + + // store some programatic information + std::stringstream usage; + usage << "usage: " << argv[0] << " .root .dump .coe "; + + // load framework libraries + gSystem->Load("libFWCoreFWLite"); + FWLiteEnabler::enable(); + + // argc should be 5 for correct execution + // We print argv[0] assuming it is the program name + if ( argc != 5 ) { + std::cerr << "ERROR::testDumpFile " << argc << " arguments provided" << std::endl; + for (int i=0; i Date: Fri, 26 Jul 2019 14:39:45 -0500 Subject: [PATCH 2/2] Improve the integration test code to use the l1tpf_impl::Regions rather than it's own sector format. This follows the pattern of the RegionMapper and allows the code to have multiple regions in eta as well as phi. --- L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc | 1 + .../Phase2L1ParticleFlow/test/BuildFile.xml | 2 +- .../test/testOutputFiles.cpp | 108 ++++++++++-------- 3 files changed, 65 insertions(+), 46 deletions(-) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc b/L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc index e9a6494519354..744045c3dc50c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc @@ -68,6 +68,7 @@ void COEFile::writeTracksToFile(const std::vector& regions, bool print) // 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); diff --git a/L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml b/L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml index 07f2879fbe9cf..658cac4577d94 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml +++ b/L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml @@ -1,5 +1,5 @@ - + diff --git a/L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp b/L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp index 7d49dcf987b24..e02fd9bb05b46 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp @@ -29,13 +29,13 @@ #include "DataFormats/FWLite/interface/Event.h" #include "DataFormats/Phase2L1ParticleFlow/interface/PFTrack.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h" #define NTEST 64 #define REPORT_EVERY_N 50 #define NTRACKS_PER_SECTOR 110 #define NBITS_PER_TRACK 96 -static unsigned int N_IN_SECTORS(0); -static std::vector SECTOR_BOUNDARIES; +static std::vector regions_; typedef l1tpf_impl::InputRegion Region; typedef std::pair SectorTrackIndex; @@ -102,7 +102,10 @@ bool findAllInRegion(std::vector & vec, std::map mapOfElemen, T value) } TrackMap get_tracks_from_root_file(fwlite::Event& ev, int entry = 0, bool print = false) { - TrackMap tracks_root, tracks_tmp; + TrackMap tracks_root; + + // clear the tracks currently stored in the regions + for (l1tpf_impl::Region &r : regions_) { r.track.clear(); } // go to the event under test if (!ev.to(entry)) { @@ -117,21 +120,30 @@ TrackMap get_tracks_from_root_file(fwlite::Event& ev, int entry = 0, bool print assert( h_track.isValid() ); int ntrackstotal(0); - auto kTrackEnd = h_track->end(); - for (auto trackIter = h_track->begin(); trackIter != kTrackEnd; ++trackIter) { - if (trackIter->pt() <= 2.0 || trackIter->nStubs() < 4 || trackIter->normalizedChi2() >= 15.0) continue; - int sector_index = (std::lower_bound(SECTOR_BOUNDARIES.begin(), SECTOR_BOUNDARIES.end(), trackIter->phi())-SECTOR_BOUNDARIES.begin())-1; - tracks_tmp[std::make_pair(sector_index,ntrackstotal)] = makeTLorentzVectorPtEtaPhiE(trackIter->pt(),trackIter->eta(),trackIter->phi(),trackIter->pt()); - //if (print) printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", ntrackstotal, trackIter->pt(), trackIter->eta(), trackIter->phi()); + const auto & tracks = *h_track; + for (unsigned int itk = 0, ntk = tracks.size(); itk < ntk; ++itk) { + const auto & tk = tracks[itk]; + if (tk.pt() <= 2.0 || tk.nStubs() < 4 || tk.normalizedChi2() >= 15.0) continue; + for (l1tpf_impl::Region &r : regions_) { + bool inside = r.contains(tk.eta(), tk.phi());; + if (inside) { + l1tpf_impl::PropagatedTrack prop; + prop.fillInput(tk.pt(), r.localEta(tk.eta()), r.localPhi(tk.phi()), tk.charge(), tk.vertex().Z(), tk.quality(), &tk); + prop.fillPropagated(tk.pt(), tk.trkPtError(), tk.caloPtError(), r.localEta(tk.caloEta()), r.localPhi(tk.caloPhi()), tk.quality(), tk.isMuon()); + prop.hwStubs = tk.nStubs(); + prop.hwChi2 = round(tk.chi2()*10); + r.track.push_back(prop); + } + } + //if (print) printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", ntrackstotal, tk.pt(), tk.eta(), tk.phi()); ntrackstotal++; } - for (unsigned int is = 0; is < N_IN_SECTORS; ++is) { - std::vector tracks_in_sector; - findAllInRegion(tracks_in_sector,tracks_tmp,is); - if (print) printf("\tFound region %u [%0.2f,%0.2f] with %lu tracks\n", is, SECTOR_BOUNDARIES[is], SECTOR_BOUNDARIES[is+1], tracks_in_sector.size()); - for (unsigned int it=0; itPt(), tracks_tmp[tracks_in_sector[it]]->Eta(), tracks_tmp[tracks_in_sector[it]]->Phi()); - tracks_root[std::make_pair(is,it)] = tracks_tmp[tracks_in_sector[it]]; + for (unsigned int iregion = 0; iregion < regions_.size(); ++iregion) { + std::vector tracks_in_region = regions_[iregion].track; + if (print) printf("\tFound region %u (eta=[%0.4f,%0.4f] phi=[%0.4f,%0.4f]) with %lu tracks\n", iregion, regions_[iregion].etaMin,regions_[iregion].etaMax, regions_[iregion].phiCenter-regions_[iregion].phiHalfWidth, regions_[iregion].phiCenter+regions_[iregion].phiHalfWidth, tracks_in_region.size()); + for (unsigned int it=0; itp4().pt(), tracks_in_region[it].src->p4().eta(), tracks_in_region[it].src->p4().phi()); + tracks_root[std::make_pair(iregion,it)] = makeTLorentzVectorPtEtaPhiE(tracks_in_region[it].src->pt(),tracks_in_region[it].src->eta(),tracks_in_region[it].src->phi(),tracks_in_region[it].src->pt()); } } if (print) { @@ -154,9 +166,9 @@ std::map,TLorentzVector*> get_tracks_from_dump_file(FILE *dfi std::cerr << "ERROR::testDumpFile::get_tracks_from_dump_file Something went wrong reading from the dump file" << std::endl; assert(event_.readFromFile(dfile_)); } - if (event_.regions.size() != N_IN_SECTORS) { + if (event_.regions.size() != regions_.size()) { printf("ERROR::testDumpFile::get_tracks_from_dump_file Mismatching number of input regions: %lu\n", event_.regions.size()); - assert(event_.regions.size() == N_IN_SECTORS); + assert(event_.regions.size() == regions_.size()); } if (print) printf("Dump::Run %u, lumi %u, event %lu, regions %lu \n", event_.run, event_.lumi, event_.event, event_.regions.size()); @@ -166,7 +178,7 @@ std::map,TLorentzVector*> get_tracks_from_dump_file(FILE *dfi int pv_gen = round(event_.genZ0 * l1tpf_impl::InputTrack::Z0_SCALE); int pv_cmssw = round(event_.z0 * l1tpf_impl::InputTrack::Z0_SCALE); - for (unsigned int is = 0; is < N_IN_SECTORS; ++is) { + for (unsigned int is = 0; is < regions_.size(); ++is) { const Region & r = event_.regions[is]; if (print) printf("\tRead region %u [%0.2f,%0.2f] with %lu tracks\n", is, r.phiCenter-r.phiHalfWidth, r.phiCenter+r.phiHalfWidth, r.track.size()); ntrackstotal+=r.track.size(); @@ -204,12 +216,12 @@ std::map,TLorentzVector*> get_tracks_from_coe_file(std::ifstr std::cerr << "ERROR::testDumpFile::get_tracks_from_coe_file We have already reached the end of the coe file" << std::endl; assert(!cfile_.eof()); } - if (print) printf("COE::Run \"unknown\", lumi \"unknown\", event \"unknown\", regions %u? \n", N_IN_SECTORS); + if (print) printf("COE::Run \"unknown\", lumi \"unknown\", event \"unknown\", regions %lu? \n", regions_.size()); // read the lines one by one for (unsigned int iline=0; iline bset_(bset_string_); if (bset_.none()) { @@ -259,10 +271,10 @@ std::map,TLorentzVector*> get_tracks_from_coe_file(std::ifstr } } - for (unsigned int is = 0; is < N_IN_SECTORS; ++is) { + for (unsigned int is = 0; is < regions_.size(); ++is) { std::vector tracks_in_sector; findAllInRegion(tracks_in_sector,tracks_coe,is); - if (print) printf("\tRead region %u [%0.2f,%0.2f] with %lu tracks\n", is, SECTOR_BOUNDARIES[is], SECTOR_BOUNDARIES[is+1], tracks_in_sector.size()); + if (print) printf("\tRead region %u (eta=[%0.4f,%0.4f] phi=[%0.4f,%0.4f]) with %lu tracks\n", is, regions_[is].etaMin,regions_[is].etaMax,regions_[is].phiCenter-regions_[is].phiHalfWidth,regions_[is].phiCenter+regions_[is].phiHalfWidth, tracks_in_sector.size()); for (unsigned int it=0; itPt(), tracks_coe[tracks_in_sector[it]]->Eta(), tracks_coe[tracks_in_sector[it]]->Phi()); } @@ -331,7 +343,7 @@ int main(int argc, char *argv[]) { // store some programatic information std::stringstream usage; - usage << "usage: " << argv[0] << " .root .dump .coe "; + usage << "usage: " << argv[0] << " .root .dump .coe "; // load framework libraries gSystem->Load("libFWCoreFWLite"); @@ -339,7 +351,7 @@ int main(int argc, char *argv[]) { // argc should be 5 for correct execution // We print argv[0] assuming it is the program name - if ( argc != 5 ) { + if ( argc < 9 ) { std::cerr << "ERROR::testDumpFile " << argc << " arguments provided" << std::endl; for (int i=0; i etaBoundaries; try { + etaExtra = atof(argv[4]); + phiExtra = atof(argv[5]); + nRegionsPhi = atoi(argv[6]); + std::vector etaBoundariesStrings(argv + 7, argv + argc); std::size_t pos; - N_IN_SECTORS = std::stoi(sectors, &pos); - if (pos < sectors.size()) { - std::cerr << "Trailing characters after number: " << sectors << '\n'; + for (unsigned int i=0; i