CMS 3D CMS Logo

Phase2EndcapLayer.cc
Go to the documentation of this file.
1 #include "Phase2EndcapLayer.h"
2 
4 
6 
9 
10 #include<array>
11 #include "DetGroupMerger.h"
12 
13 
14 //#include "CommonDet/DetLayout/src/DetLessR.h"
15 
16 
17 using namespace std;
18 
20 
21 //hopefully is never called!
22 const std::vector<const GeometricSearchDet*>& Phase2EndcapLayer::components() const{
23  if (not theComponents) {
24  auto temp = std::make_unique<std::vector<const GeometricSearchDet*>>();
25  temp->reserve(15); // This number is just an upper bound
26  for ( auto c: theComps) temp->push_back(c);
27  std::vector<const GeometricSearchDet*>* expected = nullptr;
28  if(theComponents.compare_exchange_strong(expected,temp.get())) {
29  //this thread set the value
30  temp.release();
31  }
32  }
33  return *theComponents;
34  }
35 
36 
37 void
39  const BoundDisk& ringDisk = static_cast<const BoundDisk&>(theComps[i]->surface());
40  float ringMinZ = std::abs( ringDisk.position().z()) - ringDisk.bounds().thickness()/2.;
41  float ringMaxZ = std::abs( ringDisk.position().z()) + ringDisk.bounds().thickness()/2.;
42  RingPar tempPar;
43  tempPar.thetaRingMin = ringDisk.innerRadius()/ ringMaxZ;
44  tempPar.thetaRingMax = ringDisk.outerRadius()/ ringMinZ;
45  tempPar.theRingR=( ringDisk.innerRadius() +
46  ringDisk.outerRadius())/2.;
47  ringPars.push_back(tempPar);
48 }
49 
50 
51 Phase2EndcapLayer::Phase2EndcapLayer(vector<const Phase2EndcapRing*>& rings, const bool isOT):
53  isOuterTracker(isOT),
54  theComponents{nullptr}
55 {
56  //They should be already R-ordered. TO BE CHECKED!!
57  //sort( theRings.begin(), theRings.end(), DetLessR());
58 
59  theRingSize = rings.size();
60  LogDebug("TkDetLayers") << "Number of rings in Phase2 OT EC layer is " << theRingSize << std::endl;
61  setSurface( computeDisk( rings ) );
62 
63  for(unsigned int i=0; i!=rings.size(); ++i) {
64  theComps.push_back(rings[i]);
65  fillRingPars(i);
66  theBasicComps.insert(theBasicComps.end(),
67  (*rings[i]).basicComponents().begin(),
68  (*rings[i]).basicComponents().end());
69  }
70 
71 
72  LogDebug("TkDetLayers") << "==== DEBUG Phase2EndcapLayer =====" ;
73  LogDebug("TkDetLayers") << "r,zed pos , thickness, innerR, outerR: "
74  << this->position().perp() << " , "
75  << this->position().z() << " , "
76  << this->specificSurface().bounds().thickness() << " , "
77  << this->specificSurface().innerRadius() << " , "
78  << this->specificSurface().outerRadius() ;
79 }
80 
81 
82 BoundDisk*
83 Phase2EndcapLayer::computeDisk( const vector<const Phase2EndcapRing*>& rings) const
84 {
85  float theRmin = rings.front()->specificSurface().innerRadius();
86  float theRmax = rings.front()->specificSurface().outerRadius();
87  float theZmin = rings.front()->position().z() -
88  rings.front()->surface().bounds().thickness()/2;
89  float theZmax = rings.front()->position().z() +
90  rings.front()->surface().bounds().thickness()/2;
91 
92  for (vector<const Phase2EndcapRing*>::const_iterator i = rings.begin(); i != rings.end(); i++) {
93  float rmin = (**i).specificSurface().innerRadius();
94  float rmax = (**i).specificSurface().outerRadius();
95  float zmin = (**i).position().z() - (**i).surface().bounds().thickness()/2.;
96  float zmax = (**i).position().z() + (**i).surface().bounds().thickness()/2.;
97  theRmin = min( theRmin, rmin);
98  theRmax = max( theRmax, rmax);
99  theZmin = min( theZmin, zmin);
100  theZmax = max( theZmax, zmax);
101  }
102 
103  float zPos = (theZmax+theZmin)/2.;
104  PositionType pos(0.,0.,zPos);
106 
107  return new BoundDisk( pos, rot, new SimpleDiskBounds(theRmin, theRmax,
108  theZmin-zPos, theZmax-zPos));
109 
110 }
111 
112 
114  for (auto c : theComps) delete c;
115 
116  delete theComponents.load();
117 }
118 
119 
120 
121 void
123  const Propagator& prop,
124  const MeasurementEstimator& est,
125  std::vector<DetGroup> & result) const
126 {
127  std::array<int,3> const & ringIndices = ringIndicesByCrossingProximity(startingState,prop);
128  if ( ringIndices[0]==-1 || ringIndices[1] ==-1 || ringIndices[2] == -1 ) {
129  edm::LogError("TkDetLayers") << "TkRingedForwardLayer::groupedCompatibleDets : error in CrossingProximity";
130  return;
131  }
132 
133  //order is: rings in front = 0; rings in back = 1
134  //rings should be already ordered in r
135  //if the layer has 1 ring, it does not matter
136  //FIXME: to be optimized once the geometry is stable
137  std::vector<int> ringOrder(theRingSize);
138  std::fill(ringOrder.begin(), ringOrder.end(), 1);
139  if (theRingSize > 1){
140  if(fabs(theComps[0]->position().z()) < fabs(theComps[1]->position().z())){
141  for (int i=0; i<theRingSize; i++) {
142  if(i % 2 == 0) ringOrder[i] = 0;
143  }
144  } else if(fabs(theComps[0]->position().z()) > fabs(theComps[1]->position().z())){
145  std::fill(ringOrder.begin(), ringOrder.end(), 0);
146  for (int i=0; i<theRingSize; i++) {
147  if(i % 2 == 0) ringOrder[i] = 1;
148  }
149  } else {
150  throw DetLayerException("Rings in Endcap Layer have same z position, no idea how to order them!");
151  }
152  }
153 
154  auto index = [&ringIndices,& ringOrder](int i) { return ringOrder[ringIndices[i]];};
155 
156  std::vector<DetGroup> closestResult;
157  theComps[ringIndices[0]]->groupedCompatibleDetsV( startingState, prop, est, closestResult);
158  // if the closest is empty, use the next one and exit: inherited from TID !
159  if ( closestResult.empty() ){
160  theComps[ringIndices[1]]->groupedCompatibleDetsV( startingState, prop, est, result);
161  return;
162  }
163 
164  DetGroupElement closestGel( closestResult.front().front());
165  float rWindow = computeWindowSize( closestGel.det(), closestGel.trajectoryState(), est);
166 
167  // check if next ring and next next ring are found and if there is overlap
168 
169  bool ring1ok = ringIndices[1] != -1 && overlapInR(closestGel.trajectoryState(),ringIndices[1],rWindow);
170  bool ring2ok = ringIndices[2] != -1 && overlapInR(closestGel.trajectoryState(),ringIndices[2],rWindow);
171 
172  // look for the two rings in the same plane (are they only two?)
173 
174  // determine if we are propagating from in to out (0) or from out to in (1)
175 
176  int direction = 0;
177  if(startingState.globalPosition().z()*startingState.globalMomentum().z()>0) {
178  if(prop.propagationDirection() == alongMomentum) direction=0;
179  else direction=1;
180  }
181  else{
182  if(prop.propagationDirection() == alongMomentum) direction=1;
183  else direction=0;
184  }
185 
186  if((index(0) == index(1)) && (index(0) == index(2))) {
187  edm::LogInfo("AllRingsInOnePlane") << " All rings: "
188  << ringIndices[0] << " "
189  << ringIndices[1] << " "
190  << ringIndices[2] << " in one plane. Only the first two will be considered";
191  ring2ok=false;
192  }
193 
194  if(index(0) == index(1)) {
195  if(ring1ok) {
196  std::vector<DetGroup> ring1res;
197  theComps[ringIndices[1]]->groupedCompatibleDetsV( startingState, prop, est, ring1res);
198  DetGroupMerger::addSameLevel(std::move(ring1res),closestResult);
199  }
200  if(ring2ok) {
201  std::vector<DetGroup> ring2res;
202  theComps[ringIndices[2]]->groupedCompatibleDetsV( startingState, prop, est, ring2res);
203  DetGroupMerger::orderAndMergeTwoLevels(std::move(closestResult),std::move(ring2res),result,index(0),direction);
204  return;
205  }
206  else {
207  result.swap(closestResult);
208  return;
209  }
210  }
211  else if(index(0) == index(2)) {
212  if(ring2ok) {
213  std::vector<DetGroup> ring2res;
214  theComps[ringIndices[2]]->groupedCompatibleDetsV( startingState, prop, est, ring2res);
215  DetGroupMerger::addSameLevel(std::move(ring2res),closestResult);
216  }
217  if(ring1ok) {
218  std::vector<DetGroup> ring1res;
219  theComps[ringIndices[1]]->groupedCompatibleDetsV( startingState, prop, est, ring1res);
220  DetGroupMerger::orderAndMergeTwoLevels(std::move(closestResult),std::move(ring1res),result,index(0),direction);
221  return;
222  }
223  else {
224  result.swap(closestResult);
225  return;
226  }
227  }
228  else {
229  std::vector<DetGroup> ring12res;
230  if(ring1ok) {
231  std::vector<DetGroup> ring1res;
232  theComps[ringIndices[1]]->groupedCompatibleDetsV( startingState, prop, est, ring1res);
233  ring12res.swap(ring1res);
234  }
235  if(ring2ok) {
236  std::vector<DetGroup> ring2res;
237  theComps[ringIndices[2]]->groupedCompatibleDetsV( startingState, prop, est, ring2res);
238  DetGroupMerger::addSameLevel(std::move(ring2res),ring12res);
239  }
240  if(!ring12res.empty()) {
241  DetGroupMerger::orderAndMergeTwoLevels(std::move(closestResult),std::move(ring12res),result,index(0),direction);
242  return;
243  }
244  else {
245  result.swap(closestResult);
246  return;
247  }
248  }
249 }
250 
251 
252 std::array<int,3>
254  const Propagator& prop ) const
255 {
256  typedef HelixForwardPlaneCrossing Crossing;
258 
259  HelixPlaneCrossing::PositionType startPos( startingState.globalPosition());
260  HelixPlaneCrossing::DirectionType startDir( startingState.globalMomentum());
262  float rho( startingState.transverseCurvature());
263 
264  // calculate the crossings with the ring surfaces
265  // rings are assumed to be sorted in R !
266 
267  Crossing myXing( startPos, startDir, rho, propDir );
268 
269  std::vector<GlobalPoint> ringCrossings;
270  ringCrossings.reserve(theRingSize);
271  // vector<GlobalVector> ringXDirections;
272 
273  for (int i = 0; i < theRingSize ; i++ ) {
274  const BoundDisk & theRing = static_cast<const BoundDisk &>(theComps[i]->surface());
275  pair<bool,double> pathlen = myXing.pathLength( theRing);
276  if ( pathlen.first ) {
277  ringCrossings.push_back(GlobalPoint( myXing.position(pathlen.second )));
278  // ringXDirections.push_back( GlobalVector( myXing.direction(pathlen.second )));
279  } else {
280  // TO FIX.... perhaps there is something smarter to do
281  //throw DetLayerException("trajectory doesn't cross TID rings");
282  ringCrossings.push_back(GlobalPoint( 0.,0.,0.));
283  // ringXDirections.push_back( GlobalVector( 0.,0.,0.));
284  }
285  }
286 
287  //find three closest rings to the crossing
288 
289  std::array<int,3> closests = findThreeClosest(ringCrossings);
290 
291  return closests;
292 }
293 
294 
295 
296 
297 float
299  const TrajectoryStateOnSurface& tsos,
300  const MeasurementEstimator& est) const
301 {
302  const Plane& startPlane = det->surface();
304  est.maximalLocalDisplacement( tsos, startPlane);
305  return maxDistance.y();
306 }
307 
308 std::array<int,3>
309 Phase2EndcapLayer::findThreeClosest(std::vector<GlobalPoint> ringCrossing ) const
310 {
311  std::array<int,3> theBins={{-1,-1,-1}};
312  theBins[0] = 0;
313  float initialR = ringPars[0].theRingR;
314  float rDiff0 = std::abs( ringCrossing[0].perp() - initialR);
315  float rDiff1 = -1.;
316  float rDiff2 = -1.;
317  for (int i = 1; i < theRingSize ; i++){
318  float ringR = ringPars[i].theRingR;
319  float testDiff = std::abs( ringCrossing[i].perp() - ringR);
320  if ( testDiff<rDiff0 ) {
321  rDiff2 = rDiff1;
322  rDiff1 = rDiff0;
323  rDiff0 = testDiff;
324  theBins[2] = theBins[1];
325  theBins[1] = theBins[0];
326  theBins[0] = i;
327  }
328  else
329  if ( rDiff1 < 0 || testDiff<rDiff1 ) {
330  rDiff2 = rDiff1;
331  rDiff1 = testDiff;
332  theBins[2] = theBins[1];
333  theBins[1] = i;
334  }
335  else
336  if ( rDiff2 < 0 || testDiff<rDiff2 ) {
337  rDiff2 = testDiff;
338  theBins[2] = i;
339  }
340  }
341 
342  return theBins;
343 }
344 
345 bool
347 {
348  // assume "fixed theta window", i.e. margin in local y = r is changing linearly with z
349  float tsRadius = tsos.globalPosition().perp();
350  float thetamin = ( max(0.,tsRadius-ymax))/(std::abs(tsos.globalPosition().z())+10.f); // add 10 cm contingency
351  float thetamax = ( tsRadius + ymax)/(std::abs(tsos.globalPosition().z())-10.f);
352 
353  // do the theta regions overlap ?
354 
355  return !( thetamin > ringPars[index].thetaRingMax || ringPars[index].thetaRingMin > thetamax);
356 }
357 
358 
#define LogDebug(id)
TkRotation< Scalar > RotationType
Definition: Definitions.h:29
Common base class.
std::vector< const Phase2EndcapRing * > theComps
void fillRingPars(int i) __attribute__((cold))
T y() const
Definition: PV2DBase.h:46
T perp() const
Definition: PV3DBase.h:72
std::array< int, 3 > findThreeClosest(std::vector< GlobalPoint >) const __attribute__((hot))
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
float computeWindowSize(const GeomDet *det, const TrajectoryStateOnSurface &tsos, const MeasurementEstimator &est) const __attribute__((hot))
bool overlapInR(const TrajectoryStateOnSurface &tsos, int i, double ymax) const __attribute__((hot))
std::atomic< std::vector< const GeometricSearchDet * > * > theComponents
GlobalPoint globalPosition() const
Vector2DBase< float, LocalTag > Local2DVector
~Phase2EndcapLayer() override __attribute__((cold))
PropagationDirection
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:42
Definition: Plane.h:17
Point3DBase< Scalar, GlobalTag > PositionType
Definition: Definitions.h:30
static void addSameLevel(std::vector< DetGroup > &&gvec, std::vector< DetGroup > &result)
virtual PropagationDirection propagationDirection() const final
Definition: Propagator.h:151
BoundDisk * computeDisk(const std::vector< const Phase2EndcapRing * > &rings) const __attribute__((cold))
const std::vector< const GeometricSearchDet * > & components() const override __attribute__((cold))
T z() const
Definition: PV3DBase.h:64
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
Phase2EndcapLayer(std::vector< const Phase2EndcapRing * > &rings, const bool isOT) __attribute__((cold))
T min(T a, T b)
Definition: MathUtil.h:58
GeometricSearchDet::DetWithState DetWithState
std::vector< GeomDet const * > theBasicComps
const std::vector< const GeomDet * > & basicComponents() const override
Disk BoundDisk
Definition: BoundDisk.h:62
void groupedCompatibleDetsV(const TrajectoryStateOnSurface &tsos, const Propagator &prop, const MeasurementEstimator &est, std::vector< DetGroup > &result) const override __attribute__((hot))
std::array< int, 3 > ringIndicesByCrossingProximity(const TrajectoryStateOnSurface &startingState, const Propagator &prop) const
std::vector< RingPar > ringPars
T perp() const
Magnitude of transverse component.
GlobalVector globalMomentum() const
virtual Local2DVector maximalLocalDisplacement(const TrajectoryStateOnSurface &ts, const Plane &plane) const =0
static int position[264][3]
Definition: ReadPGInfo.cc:509
std::pair< const GeomDet *, TrajectoryStateOnSurface > DetWithState
static void orderAndMergeTwoLevels(std::vector< DetGroup > &&one, std::vector< DetGroup > &&two, std::vector< DetGroup > &result, int firstIndex, int firstCrossed)
def move(src, dest)
Definition: eostools.py:510