CMS 3D CMS Logo

TrapezoidalGrouping.cc
Go to the documentation of this file.
1 #include <memory>
2 
4 
6 
7 using namespace edm;
8 using namespace std;
9 using namespace cmsdt;
10 using namespace dtamgrouping;
11 // ============================================================================
12 // Constructors and destructor
13 // ============================================================================
15  : MotherGrouping(pset, iC), debug_(pset.getUntrackedParameter<bool>("debug")), currentBaseChannel_(-1) {
16  // Obtention of parameters
17  if (debug_)
18  LogDebug("TrapezoidalGrouping") << "TrapezoidalGrouping: constructor";
19 
20  // Initialisation of channelIn array
21  chInDummy_.push_back(DTPrimitive());
22  for (int lay = 0; lay < NUM_LAYERS; lay++) {
23  for (int ch = 0; ch < NUM_CH_PER_LAYER; ch++) {
24  channelIn_[lay][ch] = {chInDummy_};
25  channelIn_[lay][ch].clear();
26  }
27  }
28 }
29 
31  if (debug_)
32  LogDebug("TrapezoidalGrouping") << "TrapezoidalGrouping: destructor";
33 }
34 
35 // ============================================================================
36 // Main methods (initialise, run, finish)
37 // ============================================================================
39  if (debug_)
40  LogDebug("TrapezoidalGrouping") << "TrapezoidalGrouping::initialiase";
41 }
42 
44  const EventSetup &iEventSetup,
45  const DTDigiCollection &digis,
46  MuonPathPtrs &mpaths) {
47  // This function returns the analyzable mpath collection back to the the main function
48  // so it can be fitted. This is in fact doing the so-called grouping.
49  for (int supLayer = 0; supLayer < NUM_SUPERLAYERS; supLayer++) { // for each SL:
50  if (debug_)
51  LogDebug("TrapezoidalGrouping") << "TrapezoidalGrouping::run Reading SL" << supLayer;
52  setInChannels(&digis, supLayer);
53 
54  for (auto &hit : all_hits) {
55  int layer_to_pivot = hit.layerId();
56  int channel_to_pivot = hit.channelId();
57  DTPrimitives hits_in_trapezoid;
58  std::vector<DTPrimitives> hit_mpaths;
59  std::vector<int> hit_tasks;
60  for (size_t itask = 0; itask < task_list.size(); itask++) {
61  // when pivoting over an internal layer, there are two cases
62  // where the second layer is duplicated
63  // 12 (0, 5) <-> 14 (0, 7)
64  // 15 (1, 6) <-> 17 (1, 8)
65  // we leave it hard-coded here, could be moved somewhere else
66  if (layer_to_pivot == 1 || layer_to_pivot == 2) {
67  if (itask == 14 || itask == 17)
68  continue;
69  }
70 
71  auto task = task_list[itask];
72 
73  std::vector<DTPrimitives> task_mpaths;
74  std::stack<std::pair<DTPrimitives, int>> mpath_cells_per_task;
75  mpath_cells_per_task.push(std::make_pair(DTPrimitives({hit}), 0));
76 
77  while (!mpath_cells_per_task.empty()) {
78  auto mpath_cells = std::move(mpath_cells_per_task.top());
79  std::vector<DTPrimitives> tmp_mpaths = {mpath_cells.first};
80  auto task_index = mpath_cells.second;
81  auto cell = task[task_index];
82  auto vertical_shift = trapezoid_vertical_mapping[layer_to_pivot][cell];
83  auto horizontal_shift = trapezoid_horizontal_mapping[layer_to_pivot][cell];
84  if (channel_to_pivot + horizontal_shift >= 0 && channel_to_pivot + horizontal_shift < NUM_CH_PER_LAYER) {
85  tmp_mpaths = group_hits(hit,
86  tmp_mpaths,
87  channelIn_[layer_to_pivot + vertical_shift][channel_to_pivot + horizontal_shift],
88  hits_in_trapezoid);
89  }
90  mpath_cells_per_task.pop();
91  for (const auto &tmp_mpath : tmp_mpaths) {
92  mpath_cells_per_task.push(std::make_pair(tmp_mpath, task_index + 1));
93  }
94  while (!mpath_cells_per_task.empty()) {
95  if (mpath_cells_per_task.top().second == (int)task.size()) {
96  task_mpaths.push_back(mpath_cells_per_task.top().first);
97  mpath_cells_per_task.pop();
98  } else
99  break;
100  }
101  }
102  for (auto &task_mpath : task_mpaths) {
103  hit_mpaths.push_back(task_mpath);
104  hit_tasks.push_back(itask);
105  }
106  }
107  if (hits_in_trapezoid.size() <= PATHFINDER_INPUT_HITS_LIMIT) {
108  for (size_t ipath = 0; ipath < hit_mpaths.size(); ipath++) {
109  auto ptrPrimitive = hit_mpaths[ipath];
110  auto itask = hit_tasks[ipath];
111 
112  // In any case, if we have less than 3 hits, we don't output the mpath
113  if (ptrPrimitive.size() < 3)
114  continue;
115 
116  // check if the task has a missing layer associated
117  // if it does, we add a dummy hit in the missing layer
118  // if it does not, we check that we actually have 4 present hits;
119  // if not, we skip the mpath.
120  if (MISSING_LAYER_LAYOUTS_PER_TASK[layer_to_pivot][itask] != -1) {
121  auto dtpAux = DTPrimitive();
122  dtpAux.setTDCTimeStamp(-1);
123  dtpAux.setChannelId(-1);
124  dtpAux.setLayerId(MISSING_LAYER_LAYOUTS_PER_TASK[layer_to_pivot][itask]); // L=0,1,2,3
125  dtpAux.setSuperLayerId(hit.superLayerId());
126  dtpAux.setCameraId(-1);
127  ptrPrimitive.push_back(dtpAux);
128  } else { // we have no missing hits, it must be a 4-hit TP.
129  if (ptrPrimitive.size() < 4)
130  continue;
131  }
132 
133  // sort the hits by layer, so they are included ordered in the MuonPath object
134  std::stable_sort(ptrPrimitive.begin(), ptrPrimitive.end(), hitLayerSort);
135 
136  auto ptrMuonPath = std::make_shared<MuonPath>(ptrPrimitive);
137  ptrMuonPath->setCellHorizontalLayout(CELL_HORIZONTAL_LAYOUTS_PER_TASK[layer_to_pivot][itask]);
138  ptrMuonPath->setMissingLayer(MISSING_LAYER_LAYOUTS_PER_TASK[layer_to_pivot][itask]);
139  mpaths.push_back(std::move(ptrMuonPath));
140  }
141  }
142  }
143  }
144  if (debug_)
145  LogDebug("TrapezoidalGrouping") << "[TrapezoidalGrouping::run] end";
146 }
147 
148 void TrapezoidalGrouping::finish() { return; };
149 
150 // ============================================================================
151 // Other methods
152 // ============================================================================
153 
155  // before setting channels we need to clear
156  for (int lay = 0; lay < NUM_LAYERS; lay++) {
157  for (int ch = 0; ch < NUM_CH_PER_LAYER; ch++) {
158  channelIn_[lay][ch].clear();
159  }
160  }
161  all_hits.clear();
162 
163  // now fill with those primitives that make sense:
164  for (const auto &dtLayerId_It : *digis) {
165  const DTLayerId dtLId = dtLayerId_It.first;
166 
167  if (dtLId.superlayer() != sl + 1)
168  continue; //skip digis not in SL...
169 
170  for (DTDigiCollection::const_iterator digiIt = (dtLayerId_It.second).first; digiIt != (dtLayerId_It.second).second;
171  ++digiIt) {
172  int layer = dtLId.layer() - 1;
173  int wire = (*digiIt).wire() - 1;
174  int digiTIME = (*digiIt).time();
175  int digiTIMEPhase2 = digiTIME;
176 
177  if (debug_)
178  LogDebug("TrapezoidalGrouping") << "[TrapezoidalGrouping::setInChannels] SL" << sl << " L" << layer << " : "
179  << wire << " " << digiTIMEPhase2;
180  auto dtpAux = DTPrimitive();
181  dtpAux.setTDCTimeStamp(digiTIMEPhase2);
182  dtpAux.setChannelId(wire);
183  dtpAux.setLayerId(layer); // L=0,1,2,3
184  dtpAux.setSuperLayerId(sl); // SL=0,1,2
185  dtpAux.setCameraId(dtLId.rawId());
186  channelIn_[layer][wire].push_back(dtpAux);
187  all_hits.push_back(dtpAux);
188  }
189  }
190 
191  // sort everything by the time of the hits, so it has the same behaviour as the fw
192  for (int lay = 0; lay < NUM_LAYERS; lay++) {
193  for (int ch = 0; ch < NUM_CH_PER_LAYER; ch++) {
194  std::stable_sort(channelIn_[lay][ch].begin(), channelIn_[lay][ch].end(), hitTimeSort);
195  }
196  }
197  std::stable_sort(all_hits.begin(), all_hits.end(), hitTimeSort);
198 }
199 
200 std::vector<DTPrimitives> TrapezoidalGrouping::group_hits(DTPrimitive pivot_hit,
201  std::vector<DTPrimitives> input_paths,
202  DTPrimitives hits_per_cell,
203  DTPrimitives &hits_in_trapezoid) {
204  std::vector<DTPrimitives> output_paths;
205  for (auto &hit : hits_per_cell) {
206  int hit_bx = hit.tdcTimeStamp() / LHC_CLK_FREQ;
207  int pivot_hit_bx = pivot_hit.tdcTimeStamp() / LHC_CLK_FREQ;
208  if (hitTimeSort(pivot_hit, hit) || (pivot_hit_bx / BX_PER_FRAME) - (hit_bx / BX_PER_FRAME) > MAX_FRAME_DIF)
209  continue;
210  // limit the number of hits in the trapezoid to PATHFINDER_INPUT_HITS_LIMIT
211  if (std::find(hits_in_trapezoid.begin(), hits_in_trapezoid.end(), hit) == hits_in_trapezoid.end())
212  hits_in_trapezoid.push_back(hit);
213 
214  if (hits_in_trapezoid.size() > PATHFINDER_INPUT_HITS_LIMIT) {
215  std::vector<DTPrimitives> empty_paths;
216  return empty_paths;
217  }
218 
219  for (auto &input_path : input_paths) {
220  auto tmp_path = input_path;
221  tmp_path.push_back(hit);
222  output_paths.push_back(tmp_path);
223  }
224  }
225  if (output_paths.empty())
226  return input_paths;
227  else
228  return output_paths;
229 }
std::vector< std::vector< short > > task_list
bool hitLayerSort(const DTPrimitive &hit1, const DTPrimitive &hit2)
void setInChannels(const DTDigiCollection *digi, int sl)
int MISSING_LAYER_LAYOUTS_PER_TASK[4][24]
short trapezoid_horizontal_mapping[4][9]
std::vector< MuonPathPtr > MuonPathPtrs
Definition: MuonPath.h:132
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
bool hitTimeSort(const DTPrimitive &hit1, const DTPrimitive &hit2)
U second(std::pair< T, U > const &p)
int iEvent
Definition: GenABIO.cc:224
constexpr int NUM_SUPERLAYERS
Definition: constants.h:362
constexpr int PATHFINDER_INPUT_HITS_LIMIT
Definition: constants.h:230
TrapezoidalGrouping(const edm::ParameterSet &pset, edm::ConsumesCollector &iC)
constexpr int MAX_FRAME_DIF
Definition: constants.h:229
short trapezoid_vertical_mapping[4][9]
void run(edm::Event &iEvent, const edm::EventSetup &iEventSetup, const DTDigiCollection &digis, MuonPathPtrs &outMpath) override
const int tdcTimeStamp() const
Definition: DTprimitive.h:30
void initialise(const edm::EventSetup &iEventSetup) override
int superlayer() const
Return the superlayer number (deprecated method name)
constexpr int NUM_CH_PER_LAYER
Definition: constants.h:357
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
std::vector< DigiType >::const_iterator const_iterator
constexpr int LHC_CLK_FREQ
Definition: constants.h:222
int layer() const
Return the layer number.
Definition: DTLayerId.h:45
std::vector< DTPrimitives > group_hits(DTPrimitive pivot_hit, std::vector< DTPrimitives > input_paths, DTPrimitives hits_per_cell, DTPrimitives &hits_in_trapezoid)
constexpr int BX_PER_FRAME
Definition: constants.h:228
HLT enums.
std::vector< DTPrimitive > DTPrimitives
Definition: DTprimitive.h:58
DTPrimitives channelIn_[cmsdt::NUM_LAYERS][cmsdt::NUM_CH_PER_LAYER]
int CELL_HORIZONTAL_LAYOUTS_PER_TASK[4][24][4]
def move(src, dest)
Definition: eostools.py:511
#define LogDebug(id)