CMS 3D CMS Logo

KFin.cc
Go to the documentation of this file.
2 
3 #include <vector>
4 #include <numeric>
5 #include <algorithm>
6 
7 using namespace std;
8 using namespace edm;
9 using namespace tt;
10 using namespace trackerTFP;
11 
12 namespace trklet {
13 
14  KFin::KFin(const ParameterSet& iConfig,
15  const Setup* setup,
16  const DataFormats* dataFormats,
17  const LayerEncoding* layerEncoding,
18  const ChannelAssignment* channelAssignment,
19  int region)
20  : enableTruncation_(iConfig.getParameter<bool>("EnableTruncation")),
21  setup_(setup),
22  dataFormats_(dataFormats),
23  layerEncoding_(layerEncoding),
24  channelAssignment_(channelAssignment),
25  region_(region),
26  input_(channelAssignment_->numNodesDR()) {}
27 
28  // read in and organize input tracks and stubs
29  void KFin::consume(const StreamsTrack& streamsTrack, const StreamsStub& streamsStub) {
30  const int offsetTrack = region_ * channelAssignment_->numNodesDR();
31  auto nonNullTrack = [](int sum, const FrameTrack& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); };
32  auto nonNullStub = [](int sum, const FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); };
33  // count tracks and stubs and reserve corresponding vectors
34  int sizeTracks(0);
35  int sizeStubs(0);
36  for (int channel = 0; channel < channelAssignment_->numNodesDR(); channel++) {
37  const int streamTrackId = offsetTrack + channel;
38  const int offsetStub = streamTrackId * setup_->numLayers();
39  const StreamTrack& streamTrack = streamsTrack[streamTrackId];
40  input_[channel].reserve(streamTrack.size());
41  sizeTracks += accumulate(streamTrack.begin(), streamTrack.end(), 0, nonNullTrack);
42  for (int layer = 0; layer < setup_->numLayers(); layer++) {
43  const StreamStub& streamStub = streamsStub[offsetStub + layer];
44  sizeStubs += accumulate(streamStub.begin(), streamStub.end(), 0, nonNullStub);
45  }
46  }
47  tracks_.reserve(sizeTracks);
48  stubs_.reserve(sizeStubs);
49  // transform input data into handy structs
50  for (int channel = 0; channel < channelAssignment_->numNodesDR(); channel++) {
51  vector<Track*>& input = input_[channel];
52  const int streamTrackId = offsetTrack + channel;
53  const int offsetStub = streamTrackId * setup_->numLayers();
54  const StreamTrack& streamTrack = streamsTrack[streamTrackId];
55  for (int frame = 0; frame < (int)streamTrack.size(); frame++) {
56  const FrameTrack& frameTrack = streamTrack[frame];
57  if (frameTrack.first.isNull()) {
58  input.push_back(nullptr);
59  continue;
60  }
61  vector<Stub*> stubs;
62  stubs.reserve(setup_->numLayers());
63  for (int layer = 0; layer < setup_->numLayers(); layer++) {
64  const FrameStub& frameStub = streamsStub[offsetStub + layer][frame];
65  if (frameStub.first.isNull())
66  continue;
67  TTBV ttBV = frameStub.second;
68  const TTBV zBV(ttBV, dataFormats_->format(Variable::z, Process::kfin).width(), 0, true);
69  ttBV >>= dataFormats_->format(Variable::z, Process::kfin).width();
70  const TTBV phiBV(ttBV, dataFormats_->format(Variable::phi, Process::kfin).width(), 0, true);
71  ttBV >>= dataFormats_->format(Variable::phi, Process::kfin).width();
72  const TTBV rBV(ttBV, dataFormats_->format(Variable::r, Process::kfin).width(), 0, true);
73  ttBV >>= dataFormats_->format(Variable::r, Process::kfin).width();
74  const TTBV layerIdBV(ttBV, channelAssignment_->widthLayerId(), 0);
75  ttBV >>= channelAssignment_->widthPSTilt();
76  const TTBV tiltBV(ttBV, channelAssignment_->widthPSTilt(), 0);
77  const double r = rBV.val(dataFormats_->base(Variable::r, Process::kfin));
78  const double phi = phiBV.val(dataFormats_->base(Variable::phi, Process::kfin));
79  const double z = zBV.val(dataFormats_->base(Variable::z, Process::kfin));
80  stubs_.emplace_back(frameStub.first, r, phi, z, layerIdBV.val(), tiltBV.val(), layer);
81  stubs.push_back(&stubs_.back());
82  }
83  TTBV ttBV = frameTrack.second;
84  const TTBV cotBV(ttBV, dataFormats_->format(Variable::cot, Process::kfin).width(), 0, true);
85  ttBV >>= dataFormats_->format(Variable::cot, Process::kfin).width();
86  const TTBV zTBV(ttBV, dataFormats_->format(Variable::zT, Process::kfin).width(), 0, true);
87  ttBV >>= dataFormats_->format(Variable::zT, Process::kfin).width();
88  const TTBV phiTBV(ttBV, dataFormats_->format(Variable::phiT, Process::kfin).width(), 0, true);
89  ttBV >>= dataFormats_->format(Variable::phiT, Process::kfin).width();
90  const TTBV inv2RBV(ttBV, dataFormats_->format(Variable::inv2R, Process::kfin).width(), 0, true);
91  ttBV >>= dataFormats_->format(Variable::inv2R, Process::kfin).width();
92  const TTBV sectorEtaBV(ttBV, dataFormats_->format(Variable::sectorEta, Process::kfin).width(), 0);
93  ttBV >>= dataFormats_->format(Variable::sectorEta, Process::kfin).width();
94  const TTBV sectorPhiBV(ttBV, dataFormats_->format(Variable::sectorPhi, Process::kfin).width(), 0);
95  const double cot = cotBV.val(dataFormats_->base(Variable::cot, Process::kfin));
96  const double zT = zTBV.val(dataFormats_->base(Variable::zT, Process::kfin));
97  const double inv2R = inv2RBV.val(dataFormats_->base(Variable::inv2R, Process::kfin));
98  const int sectorEta = sectorEtaBV.val();
99  const int zTu = dataFormats_->format(Variable::zT, Process::kfin).toUnsigned(zT);
100  const int cotu = dataFormats_->format(Variable::cot, Process::kfin).toUnsigned(cot);
101  const TTBV maybe = layerEncoding_->maybePattern(sectorEta, zTu, cotu);
102  const FrameTrack frameT(frameTrack.first,
103  Frame("1" + maybe.str() + sectorPhiBV.str() + sectorEtaBV.str() + phiTBV.str() +
104  inv2RBV.str() + zTBV.str() + cotBV.str()));
105  tracks_.emplace_back(frameT, stubs, cot, zT, inv2R, sectorEtaBV.val());
106  input.push_back(&tracks_.back());
107  }
108  // remove all gaps between end and last track
109  for (auto it = input.end(); it != input.begin();)
110  it = (*--it) ? input.begin() : input.erase(it);
111  }
112  }
113 
114  // fill output products
115  void KFin::produce(StreamsStub& accpetedStubs,
116  StreamsTrack& acceptedTracks,
117  StreamsStub& lostStubs,
119  // calculate stub uncertainties
120  static constexpr int usedMSBpitchOverRaddr = 1;
121  static const double baseRlut =
122  dataFormats_->base(Variable::r, Process::kfin) *
123  pow(2, dataFormats_->width(Variable::r, Process::zht) - setup_->widthAddrBRAM18() + usedMSBpitchOverRaddr);
124  static const double baseRinvR = dataFormats_->base(Variable::r, Process::kfin) *
125  pow(2, dataFormats_->width(Variable::r, Process::zht) - setup_->widthAddrBRAM18());
126  static const double basePhi =
127  dataFormats_->base(Variable::inv2R, Process::kfin) * dataFormats_->base(Variable::r, Process::kfin);
128  static const double baseInvR =
129  pow(2.,
130  ceil(log2(dataFormats_->base(Variable::r, Process::kfin) / setup_->tbInnerRadius())) -
131  setup_->widthDSPbu()) /
132  dataFormats_->base(Variable::r, Process::kfin);
133  static const double maxCot = sinh(setup_->maxEta()) + setup_->beamWindowZ() / setup_->chosenRofZ();
134  static constexpr int usedMSBCotLutaddr = 3;
135  static const double baseCotLut = pow(2., ceil(log2(maxCot)) - setup_->widthAddrBRAM18() + usedMSBCotLutaddr);
136  static const double baseCot = dataFormats_->base(Variable::cot, Process::kfin);
137  static const double baseZ = dataFormats_->base(Variable::z, Process::kfin);
138  static const double baseR = dataFormats_->base(Variable::r, Process::kfin);
139  for (const Track& track : tracks_) {
140  const int sectorEta = track.sectorEta_;
141  const double inv2R = abs(track.inv2R_);
142  for (Stub* stub : track.stubs_) {
143  const bool barrel = setup_->barrel(stub->ttStubRef_);
144  const bool ps = barrel ? setup_->psModule(stub->ttStubRef_) : stub->psTilt_;
145  const bool tilt = barrel ? (ps && !stub->psTilt_) : false;
146  const double length = ps ? setup_->lengthPS() : setup_->length2S();
147  const double pitch = ps ? setup_->pitchPS() : setup_->pitch2S();
148  const double pitchOverR = digi(pitch / (digi(stub->r_, baseRlut) + dataFormats_->chosenRofPhi()), basePhi);
149  const double r = digi(stub->r_, baseRinvR) + dataFormats_->chosenRofPhi();
150  const double sumdz = track.zT_ + stub->z_;
151  const double dZ = digi(sumdz - digi(setup_->chosenRofZ(), baseR) * track.cot_, baseCot * baseR);
152  const double sumcot = track.cot_ + digi(setup_->sectorCot(sectorEta), baseCot);
153  const double cot = digi(abs(dZ * digi(1. / r, baseInvR) + sumcot), baseCotLut);
154  double lengthZ = length;
155  double lengthR = 0.;
156  if (!barrel) {
157  lengthZ = length * cot;
158  lengthR = length;
159  } else if (tilt) {
160  lengthZ = length * abs(setup_->tiltApproxSlope() * cot + setup_->tiltApproxIntercept());
161  lengthR = setup_->tiltUncertaintyR();
162  }
163  const double scat = digi(setup_->scattering(), baseR);
164  stub->dZ_ = lengthZ + baseZ;
165  stub->dPhi_ = (scat + digi(lengthR, baseR)) * inv2R + pitchOverR;
166  stub->dPhi_ = digi(stub->dPhi_, basePhi) + basePhi;
167  }
168  }
169  // store helper
170  auto frameTrack = [](Track* track) { return track->frame_; };
171  auto frameStub = [this](Track* track, int layer) {
172  auto equal = [layer](Stub* stub) { return stub->channel_ == layer; };
173  const auto it = find_if(track->stubs_.begin(), track->stubs_.end(), equal);
174  if (it == track->stubs_.end())
175  return FrameStub();
176  Stub* stub = *it;
177  const TTBV r(dataFormats_->format(Variable::r, Process::kfin).ttBV(stub->r_));
178  const TTBV phi(dataFormats_->format(Variable::phi, Process::kfin).ttBV(stub->phi_));
179  const TTBV z(dataFormats_->format(Variable::z, Process::kfin).ttBV(stub->z_));
180  const TTBV dPhi(dataFormats_->format(Variable::dPhi, Process::kfin).ttBV(stub->dPhi_));
181  const TTBV dZ(dataFormats_->format(Variable::dZ, Process::kfin).ttBV(stub->dZ_));
182  return FrameStub(stub->ttStubRef_, Frame("1" + r.str() + phi.str() + z.str() + dPhi.str() + dZ.str()));
183  };
184  // merge number of nodes DR to number of Nodes KF and store result
185  static const int nMux = channelAssignment_->numNodesDR() / setup_->kfNumWorker();
186  const int offsetTrack = region_ * setup_->kfNumWorker();
187  for (int nodeKF = 0; nodeKF < setup_->kfNumWorker(); nodeKF++) {
188  const int offset = nodeKF * nMux;
189  deque<Track*> accepted;
190  deque<Track*> lost;
191  vector<deque<Track*>> stacks(nMux);
192  vector<deque<Track*>> inputs(nMux);
193  for (int channel = 0; channel < nMux; channel++) {
194  const vector<Track*>& input = input_[offset + channel];
195  inputs[channel] = deque<Track*>(input.begin(), input.end());
196  }
197  // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick
198  while (!all_of(inputs.begin(), inputs.end(), [](const deque<Track*>& tracks) { return tracks.empty(); }) or
199  !all_of(stacks.begin(), stacks.end(), [](const deque<Track*>& tracks) { return tracks.empty(); })) {
200  // fill input fifos
201  for (int channel = 0; channel < nMux; channel++) {
202  deque<Track*>& stack = stacks[channel];
203  Track* track = pop_front(inputs[channel]);
204  if (track)
205  stack.push_back(track);
206  }
207  // merge input fifos to one stream, prioritizing higher input channel over lower channel
208  bool nothingToRoute(true);
209  for (int channel = nMux - 1; channel >= 0; channel--) {
210  Track* track = pop_front(stacks[channel]);
211  if (track) {
212  nothingToRoute = false;
213  accepted.push_back(track);
214  break;
215  }
216  }
217  if (nothingToRoute)
218  accepted.push_back(nullptr);
219  }
220  // truncate if desired
221  if (enableTruncation_ && (int)accepted.size() > setup_->numFrames()) {
222  const auto limit = next(accepted.begin(), setup_->numFrames());
223  copy_if(limit, accepted.end(), back_inserter(lost), [](const Track* track) { return track; });
224  accepted.erase(limit, accepted.end());
225  }
226  // remove all gaps between end and last track
227  for (auto it = accepted.end(); it != accepted.begin();)
228  it = (*--it) ? accepted.begin() : accepted.erase(it);
229  // fill products StreamsStub& accpetedStubs, StreamsTrack& acceptedTracks, StreamsStub& lostStubs, StreamsTrack& lostTracks
230  const int channelTrack = offsetTrack + nodeKF;
231  const int offsetStub = channelTrack * setup_->numLayers();
232  // fill lost tracks and stubs without gaps
233  lostTracks[channelTrack].reserve(lost.size());
234  for (int layer = 0; layer < setup_->numLayers(); layer++)
235  lostStubs[offsetStub + layer].reserve(lost.size());
236  for (Track* track : lost) {
237  lostTracks[channelTrack].emplace_back(frameTrack(track));
238  for (int layer = 0; layer < setup_->numLayers(); layer++)
239  lostStubs[offsetStub + layer].emplace_back(frameStub(track, layer));
240  }
241  // fill accepted tracks and stubs with gaps
242  acceptedTracks[channelTrack].reserve(accepted.size());
243  for (int layer = 0; layer < setup_->numLayers(); layer++)
244  accpetedStubs[offsetStub + layer].reserve(accepted.size());
245  for (Track* track : accepted) {
246  if (!track) { // fill gap
247  acceptedTracks[channelTrack].emplace_back(FrameTrack());
248  for (int layer = 0; layer < setup_->numLayers(); layer++)
249  accpetedStubs[offsetStub + layer].emplace_back(FrameStub());
250  continue;
251  }
252  acceptedTracks[channelTrack].emplace_back(frameTrack(track));
253  for (int layer = 0; layer < setup_->numLayers(); layer++)
254  accpetedStubs[offsetStub + layer].emplace_back(frameStub(track, layer));
255  }
256  }
257  }
258 
259  // remove and return first element of deque, returns nullptr if empty
260  template <class T>
261  T* KFin::pop_front(deque<T*>& ts) const {
262  T* t = nullptr;
263  if (!ts.empty()) {
264  t = ts.front();
265  ts.pop_front();
266  }
267  return t;
268  }
269 
270 } // namespace trklet
bool enableTruncation_
Definition: KFin.h:74
constexpr int32_t ceil(float num)
double base(Variable v, Process p) const
Definition: DataFormats.h:492
std::bitset< TTBV::S_ > Frame
Definition: TTTypes.h:58
double dPhi_
Definition: KFin.h:49
std::vector< StreamTrack > StreamsTrack
Definition: TTTypes.h:67
bool psTilt_
Definition: KFin.h:46
double z_
Definition: KFin.h:44
double length2S() const
Definition: Setup.h:173
double phi_
Definition: KFin.h:43
double chosenRofZ() const
Definition: Setup.h:417
Bit vector used by Track Trigger emulators. Mainly used to convert integers into arbitrary (within ma...
Definition: TTBV.h:20
std::pair< TTStubRef, Frame > FrameStub
Definition: TTTypes.h:60
TTBV ttBV(int i) const
Definition: DataFormats.h:78
std::vector< Stub > stubs_
Definition: KFin.h:88
Class to process and provide run-time constants used by Track Trigger emulators.
Definition: Setup.h:44
std::vector< StreamStub > StreamsStub
Definition: TTTypes.h:66
std::vector< FrameStub > StreamStub
Definition: TTTypes.h:63
int numFrames() const
Definition: Setup.h:153
int widthDSPbu() const
Definition: Setup.h:141
void consume(const tt::StreamsTrack &streamsTrack, const tt::StreamsStub &streamsStub)
Definition: KFin.cc:29
double digi(double val, double base) const
Definition: KFin.h:37
const ChannelAssignment * channelAssignment_
Definition: KFin.h:82
double lengthPS() const
Definition: Setup.h:175
Class to assign tracklet tracks and stubs to output channel based on their Pt or seed type as well as...
float float float z
TTBV maybePattern(int binEta, int binZT, int binCot) const
std::vector< FrameTrack > StreamTrack
Definition: TTTypes.h:64
bool equal(const T &first, const T &second)
Definition: Equal.h:32
static std::string const input
Definition: EdmProvDump.cc:50
int width(Variable v, Process p) const
Definition: DataFormats.h:490
double chosenRofPhi() const
Definition: DataFormats.h:508
double pitch2S() const
Definition: Setup.h:169
std::pair< TTTrackRef, Frame > FrameTrack
Definition: TTTypes.h:62
double pitchPS() const
Definition: Setup.h:171
Definition: TTTypes.h:54
double beamWindowZ() const
Definition: Setup.h:180
double tiltUncertaintyR() const
Definition: Setup.h:253
std::string str() const
Definition: TTBV.h:253
T * pop_front(std::deque< T *> &ts) const
Definition: KFin.cc:261
TTStubRef ttStubRef_
Definition: KFin.h:41
int kfNumWorker() const
Definition: Setup.h:491
double r_
Definition: KFin.h:42
double maxEta() const
Definition: Setup.h:211
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
const int region_
Definition: KFin.h:84
stack
Definition: svgfig.py:559
std::vector< Track > tracks_
Definition: KFin.h:86
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< std::vector< Track * > > input_
Definition: KFin.h:90
double dZ_
Definition: KFin.h:51
double tiltApproxSlope() const
Definition: Setup.h:249
int numLayers() const
Definition: Setup.h:215
int widthAddrBRAM18() const
Definition: Setup.h:151
bool psModule(int dtcId) const
Definition: Setup.cc:322
double tbInnerRadius() const
Definition: Setup.h:304
double scattering() const
Definition: Setup.h:255
int toUnsigned(int i) const
Definition: DataFormats.h:102
HLT enums.
Class to encode layer ids for Kalman Filter Layers consitent with rough r-z track parameters are coun...
Definition: LayerEncoding.h:19
double tiltApproxIntercept() const
Definition: Setup.h:251
Class to calculate and provide dataformats used by Track Trigger emulator.
Definition: DataFormats.h:216
double sectorCot(int eta) const
Definition: Setup.h:432
const trackerTFP::DataFormats * dataFormats_
Definition: KFin.h:78
const tt::Setup * setup_
Definition: KFin.h:76
long double T
void produce(tt::StreamsStub &accpetedStubs, tt::StreamsTrack &acceptedTracks, tt::StreamsStub &lostStubs, tt::StreamsTrack &lostTracks)
Definition: KFin.cc:115
bool barrel(const TTStubRef &ttStubRef) const
Definition: Setup.cc:528
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
const trackerTFP::LayerEncoding * layerEncoding_
Definition: KFin.h:80
const DataFormat & format(Variable v, Process p) const
Definition: DataFormats.h:506