CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TIDLayer.cc
Go to the documentation of this file.
1 #include "TIDLayer.h"
2 
4 
6 
9 
10 #include "DetGroupMerger.h"
11 
12 //#include "CommonDet/DetLayout/src/DetLessR.h"
13 
14 
15 using namespace std;
16 
18 
19 
20 class TIDringLess : public binary_function< int, int, bool> {
21  // z-position ordering of TID rings indices
22 public:
23  bool operator()( const pair<vector<DetGroup> const *,int> & a,const pair<vector<DetGroup>const *,int> & b) const {
24  if(a.second==2) {return true;}
25  else if(a.second==0) {
26  if(b.second==2) return false;
27  if(b.second==1) return true;
28  }
29  return false;
30  };
31 };
32 
33 
34 TIDLayer::TIDLayer(vector<const TIDRing*>& rings):
35  theComps(rings.begin(),rings.end())
36 {
37  //They should be already R-ordered. TO BE CHECKED!!
38  //sort( theRings.begin(), theRings.end(), DetLessR());
39  setSurface( computeDisk( rings ) );
40 
41  if ( theComps.size() != 3) throw DetLayerException("Number of rings in TID layer is not equal to 3 !!");
42 
43  for(vector<const GeometricSearchDet*>::const_iterator it=theComps.begin();
44  it!=theComps.end();it++){
45  theBasicComps.insert(theBasicComps.end(),
46  (**it).basicComponents().begin(),
47  (**it).basicComponents().end());
48  }
49 
50 
51  LogDebug("TkDetLayers") << "==== DEBUG TIDLayer =====" ;
52  LogDebug("TkDetLayers") << "r,zed pos , thickness, innerR, outerR: "
53  << this->position().perp() << " , "
54  << this->position().z() << " , "
55  << this->specificSurface().bounds().thickness() << " , "
56  << this->specificSurface().innerRadius() << " , "
57  << this->specificSurface().outerRadius() ;
58 }
59 
60 
61 BoundDisk*
62 TIDLayer::computeDisk( const vector<const TIDRing*>& rings) const
63 {
64  float theRmin = rings.front()->specificSurface().innerRadius();
65  float theRmax = rings.front()->specificSurface().outerRadius();
66  float theZmin = rings.front()->position().z() -
67  rings.front()->surface().bounds().thickness()/2;
68  float theZmax = rings.front()->position().z() +
69  rings.front()->surface().bounds().thickness()/2;
70 
71  for (vector<const TIDRing*>::const_iterator i = rings.begin(); i != rings.end(); i++) {
72  float rmin = (**i).specificSurface().innerRadius();
73  float rmax = (**i).specificSurface().outerRadius();
74  float zmin = (**i).position().z() - (**i).surface().bounds().thickness()/2.;
75  float zmax = (**i).position().z() + (**i).surface().bounds().thickness()/2.;
76  theRmin = min( theRmin, rmin);
77  theRmax = max( theRmax, rmax);
78  theZmin = min( theZmin, zmin);
79  theZmax = max( theZmax, zmax);
80  }
81 
82  float zPos = (theZmax+theZmin)/2.;
83  PositionType pos(0.,0.,zPos);
85 
86  return new BoundDisk( pos, rot,SimpleDiskBounds(theRmin, theRmax,
87  theZmin-zPos, theZmax-zPos));
88 
89 }
90 
91 
92 TIDLayer::~TIDLayer(){
93  vector<const GeometricSearchDet*>::const_iterator i;
94  for (i=theComps.begin(); i!=theComps.end(); i++) {
95  delete *i;
96  }
97 
98 }
99 
100 
101 
102 void
103 TIDLayer::groupedCompatibleDetsV( const TrajectoryStateOnSurface& startingState,
104  const Propagator& prop,
105  const MeasurementEstimator& est,
106  std::vector<DetGroup> & result) const
107 {
108  vector<int> ringIndices = ringIndicesByCrossingProximity(startingState,prop);
109  if ( ringIndices.size()!=3 ) {
110  edm::LogError("TkDetLayers") << "TkRingedForwardLayer::groupedCompatibleDets : ringIndices.size() = "
111  << ringIndices.size() << " and not =3!!" ;
112  return;
113  }
114 
115  vector<DetGroup> closestResult;
116  vector<DetGroup> nextResult;
117  vector<DetGroup> nextNextResult;
118  vector<vector<DetGroup> > groupsAtRingLevel;
119 
120  theComps[ringIndices[0]]->groupedCompatibleDetsV( startingState, prop, est, closestResult);
121  if ( closestResult.empty() ){
122  theComps[ringIndices[1]]->groupedCompatibleDetsV( startingState, prop, est, result);
123  return;
124  }
125 
126  groupsAtRingLevel.push_back(closestResult);
127 
128  DetGroupElement closestGel( closestResult.front().front());
129  float rWindow = computeWindowSize( closestGel.det(), closestGel.trajectoryState(), est);
130  if(!overlapInR(closestGel.trajectoryState(),ringIndices[1],rWindow)) {
131  result.swap(closestResult);
132  return;
133  };
134 
135  nextResult.clear();
136  theComps[ringIndices[1]]->groupedCompatibleDetsV( startingState, prop, est, nextResult);
137  if(nextResult.empty()) {
138  result.swap(closestResult);
139  return;
140  }
141  groupsAtRingLevel.push_back(nextResult);
142 
143  if(!overlapInR(closestGel.trajectoryState(),ringIndices[2],rWindow) ) {
144  //then merge 2 levels & return
145  orderAndMergeLevels(closestGel.trajectoryState(),prop,groupsAtRingLevel,ringIndices,result);
146  return;
147  }
148 
149  theComps[ringIndices[2]]->groupedCompatibleDetsV( startingState, prop, est, nextNextResult);
150  if(nextNextResult.empty()) {
151  // then merge 2 levels and return
152  orderAndMergeLevels(closestGel.trajectoryState(),prop,groupsAtRingLevel,ringIndices,result);
153  return;
154  }
155 
156  groupsAtRingLevel.push_back(nextNextResult);
157  // merge 3 level and return merged
158  orderAndMergeLevels(closestGel.trajectoryState(),prop,groupsAtRingLevel,ringIndices, result);
159 }
160 
161 
162 vector<int>
163 TIDLayer::ringIndicesByCrossingProximity(const TrajectoryStateOnSurface& startingState,
164  const Propagator& prop ) const
165 {
166  typedef HelixForwardPlaneCrossing Crossing;
168 
169  HelixPlaneCrossing::PositionType startPos( startingState.globalPosition());
170  HelixPlaneCrossing::DirectionType startDir( startingState.globalMomentum());
172  float rho( startingState.transverseCurvature());
173 
174  // calculate the crossings with the ring surfaces
175  // rings are assumed to be sorted in R !
176 
177  Crossing myXing( startPos, startDir, rho, propDir );
178 
179  GlobalPoint ringCrossings[3];
180  // vector<GlobalVector> ringXDirections;
181 
182  for (int i = 0; i < 3 ; i++ ) {
183  const BoundDisk & theRing = static_cast<const BoundDisk &>(theComps[i]->surface());
184  pair<bool,double> pathlen = myXing.pathLength( theRing);
185  if ( pathlen.first ) {
186  ringCrossings[i] = GlobalPoint( myXing.position(pathlen.second ));
187  // ringXDirections.push_back( GlobalVector( myXing.direction(pathlen.second )));
188  } else {
189  // TO FIX.... perhaps there is something smarter to do
190  //throw DetLayerException("trajectory doesn't cross TID rings");
191  ringCrossings[i] = GlobalPoint( 0.,0.,0.);
192  // ringXDirections.push_back( GlobalVector( 0.,0.,0.));
193  }
194  }
195 
196  int closestIndex = findClosest(ringCrossings);
197  int nextIndex = findNextIndex(ringCrossings,closestIndex);
198  if ( closestIndex<0 || nextIndex<0 ) return vector<int>();
199  int nextNextIndex = -1;
200  for(int i=0; i<3 ; i++){
201  if(i!= closestIndex && i!=nextIndex) {
202  nextNextIndex = i;
203  break;
204  }
205  }
206 
207  vector<int> indices;
208  indices.push_back(closestIndex);
209  indices.push_back(nextIndex);
210  indices.push_back(nextNextIndex);
211  return indices;
212 }
213 
214 
215 
216 
217 float
219  const TrajectoryStateOnSurface& tsos,
220  const MeasurementEstimator& est) const
221 {
222  const BoundPlane& startPlane = det->surface();
224  est.maximalLocalDisplacement( tsos, startPlane);
225  return maxDistance.y();
226 }
227 
228 namespace {
229  void mergeOutward(vector< pair<vector<DetGroup> const *,int> > const & groupPlusIndex,
230  std::vector<DetGroup> & result ) {
231  typedef DetGroupMerger Merger;
232  Merger::orderAndMergeTwoLevels(*groupPlusIndex[0].first,
233  *groupPlusIndex[1].first,result,1,1);
234  int size = groupPlusIndex.size();
235  if(size==3) {
236  std::vector<DetGroup> tmp;
237  tmp.swap(result);
238  Merger::orderAndMergeTwoLevels(tmp,*groupPlusIndex[2].first,result,1,1);
239  }
240 
241  }
242 
243  void mergeInward(vector< pair<vector<DetGroup> const *,int> > const & groupPlusIndex,
244  std::vector<DetGroup> & result ) {
245  typedef DetGroupMerger Merger;
246  int size = groupPlusIndex.size();
247 
248  if(size==2){
249  Merger::orderAndMergeTwoLevels(*groupPlusIndex[1].first,
250  *groupPlusIndex[0].first,result,1,1);
251  }else if(size==3){
252  std::vector<DetGroup> tmp;
253  Merger::orderAndMergeTwoLevels(*groupPlusIndex[2].first,
254  *groupPlusIndex[1].first,tmp,1,1);
255  Merger::orderAndMergeTwoLevels(tmp,*groupPlusIndex[0].first,result,1,1);
256  }
257  }
258 }
259 
260 void
261 TIDLayer::orderAndMergeLevels(const TrajectoryStateOnSurface& tsos,
262  const Propagator& prop,
263  const vector<vector<DetGroup> > & groups,
264  const vector<int> & indices,
265  std::vector<DetGroup> & result )
266 {
267  vector< pair<vector<DetGroup> const *,int> > groupPlusIndex;
268 
269  for(unsigned int i=0;i<groups.size();i++){
270  groupPlusIndex.push_back(pair<vector<DetGroup> const *,int>(&groups[i],indices[i]) );
271  }
272  //order is ring3,ring1,ring2
273  std::sort(groupPlusIndex.begin(),groupPlusIndex.end(),TIDringLess());
274 
275 
276  float zpos = tsos.globalPosition().z();
277  if(tsos.globalMomentum().z()*zpos>0){ // momentum points outwards
278  if(prop.propagationDirection() == alongMomentum)
279  mergeOutward(groupPlusIndex,result);
280  else
281  mergeInward(groupPlusIndex,result);
282  }
283  else{ // momentum points inwards
285  mergeOutward(groupPlusIndex,result);
286  else
287  mergeInward(groupPlusIndex,result);
288  }
289 
290 }
291 
292 int
293 TIDLayer::findClosest(const GlobalPoint ringCrossing[3] ) const
294 {
295  int theBin = 0;
296  const BoundDisk & theFrontRing = static_cast<const BoundDisk &>(theComps[0]->surface());
297  float initialR = 0.5*( theFrontRing.innerRadius() +
298  theFrontRing.outerRadius());
299  float rDiff = fabs( ringCrossing[0].perp() - initialR);
300  for (int i = 1; i < 3 ; i++){
301  const BoundDisk & theRing = static_cast<const BoundDisk &>(theComps[i]->surface());
302  float ringR = 0.5*( theRing.innerRadius() +
303  theRing.outerRadius());
304  float testDiff = fabs( ringCrossing[i].perp() - ringR);
305  if ( testDiff<rDiff ) {
306  rDiff = testDiff;
307  theBin = i;
308  }
309  }
310  return theBin;
311 }
312 
313 int
314 TIDLayer::findNextIndex(const GlobalPoint ringCrossing[3], int closest ) const
315 {
316 
317  int firstIndexToCheck = (closest != 0)? 0 : 1;
318  const BoundDisk & theFrontRing = static_cast<const BoundDisk &>(theComps[firstIndexToCheck]->surface());
319  float initialR = ( theFrontRing.innerRadius() +
320  theFrontRing.outerRadius())/2.;
321 
322  float rDiff = fabs( ringCrossing[0].perp() - initialR);
323  int theBin = firstIndexToCheck;
324  for (int i = firstIndexToCheck+1; i < 3 ; i++){
325  if ( i != closest) {
326  const BoundDisk & theRing = static_cast<const BoundDisk &>(theComps[i]->surface());
327  float ringR = ( theRing.innerRadius() +
328  theRing.outerRadius())/2.;
329  float testDiff = fabs( ringCrossing[i].perp() - ringR);
330  if ( testDiff<rDiff ) {
331  rDiff = testDiff;
332  theBin = i;
333  }
334  }
335  }
336  return theBin;
337 }
338 
339 
340 
341 bool
342 TIDLayer::overlapInR( const TrajectoryStateOnSurface& tsos, int index, double ymax ) const
343 {
344  // assume "fixed theta window", i.e. margin in local y = r is changing linearly with z
345  float tsRadius = tsos.globalPosition().perp();
346  float thetamin = ( max(0.,tsRadius-ymax))/(fabs(tsos.globalPosition().z())+10.); // add 10 cm contingency
347  float thetamax = ( tsRadius + ymax)/(fabs(tsos.globalPosition().z())-10.);
348 
349  const BoundDisk& ringDisk = static_cast<const BoundDisk&>(theComps[index]->surface());
350  float ringMinZ = fabs( ringDisk.position().z()) - ringDisk.bounds().thickness()/2.;
351  float ringMaxZ = fabs( ringDisk.position().z()) + ringDisk.bounds().thickness()/2.;
352  float thetaRingMin = ringDisk.innerRadius()/ ringMaxZ;
353  float thetaRingMax = ringDisk.outerRadius()/ ringMinZ;
354 
355  // do the theta regions overlap ?
356 
357  return !( thetamin > thetaRingMax || thetaRingMin > thetamax);
358 }
359 
360 
#define LogDebug(id)
TkRotation< Scalar > RotationType
Definition: Definitions.h:29
Common base class.
int i
Definition: DBlmapReader.cc:9
T y() const
Definition: PV2DBase.h:45
T perp() const
Definition: PV3DBase.h:71
virtual PropagationDirection propagationDirection() const
Definition: Propagator.h:143
double zPos
Definition: DDAxes.h:10
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
GlobalPoint globalPosition() const
#define min(a, b)
Definition: mlp_lapack.h:161
Vector2DBase< float, LocalTag > Local2DVector
PropagationDirection
virtual Local2DVector maximalLocalDisplacement(const TrajectoryStateOnSurface &ts, const BoundPlane &plane) const
static int position[TOTALCHAMBERS][3]
Definition: ReadPGInfo.cc:509
float computeWindowSize(const GeomDet *det, const TrajectoryStateOnSurface &tsos, const MeasurementEstimator &est)
Definition: TkDetUtil.cc:31
Point3DBase< Scalar, GlobalTag > PositionType
Definition: Definitions.h:30
virtual float thickness() const =0
const T & max(const T &a, const T &b)
T z() const
Definition: PV3DBase.h:63
tuple result
Definition: query.py:137
#define end
Definition: vmac.h:38
Definition: Merger.h:30
std::pair< const GeomDet *, TrajectoryStateOnSurface > DetWithState
bool first
Definition: L1TdeRCT.cc:94
bool operator()(const pair< vector< DetGroup > const *, int > &a, const pair< vector< DetGroup >const *, int > &b) const
Definition: TIDLayer.cc:23
const Bounds & bounds() const
Definition: BoundSurface.h:89
double b
Definition: hdecay.h:120
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
T perp() const
Magnitude of transverse component.
#define begin
Definition: vmac.h:31
GlobalVector globalMomentum() const
const BoundPlane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:35
double a
Definition: hdecay.h:121
float outerRadius() const
The outer radius of the disk.
Definition: BoundDisk.h:75
std::pair< const GeomDet *, TrajectoryStateOnSurface > DetWithState
float innerRadius() const
The inner radius of the disk.
Definition: BoundDisk.h:72
const PositionType & position() const
tuple size
Write out results.