CMS 3D CMS Logo

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