CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
AngleConverter.cc
Go to the documentation of this file.
3 
6 
10 
14 
15 
20 
21 #include <cmath>
22 
23 AngleConverter::AngleConverter(): _geom_cache_id(0ULL) { }
31  unsigned long long geomid = geom.cacheIdentifier();
32  if( _geom_cache_id != geomid ) {
33  geom.get(_georpc);
34  geom.get(_geocsc);
35  geom.get(_geodt);
36  _geom_cache_id = geomid;
37  }
38 }
39 
42 int AngleConverter::getProcessorPhi(unsigned int iProcessor, l1t::tftype part, const L1MuDTChambPhDigi &digi) const
43 {
44 
45  double hsPhiPitch = 2*M_PI/OMTFConfiguration::instance()->nPhiBins; // width of phi Pitch, related to halfStrip at CSC station 2
46  const int dummy = OMTFConfiguration::instance()->nPhiBins;
47 
48  int processor= iProcessor+1; // FIXME: get from OMTF name when available
49  int posneg = (part==l1t::tftype::omtf_pos) ? 1 : -1; // FIXME: get from OMTF name
50 
51  int sector = digi.scNum()+1; //NOTE: there is a inconsistency in DT sector numb. Thus +1 needed to get detector numb.
52  int wheel = digi.whNum();
53  int station = digi.stNum();
54  int phiDT = digi.phi();
55 
56  if (posneg*2 != wheel) return dummy;
57  if (station > 3 ) return dummy;
58 
59  //FIXME: update the following two lines with proper method when Connections introduced
60  if (processor !=6 && !(sector >= processor*2-1 && sector <= processor*2+1) ) return dummy;
61  if (processor ==6 && !(sector >= 11 || sector==1) ) return dummy;
62 
63  // ichamber is consecutive chamber connected to processor, starting from 0 (overlaping one)
64  int ichamber = sector-1-2*(processor-1);
65  if (ichamber < 0) ichamber += 12;
66 
67  int offsetLoc = lround( ((ichamber-1)*M_PI/6+M_PI/12.)/hsPhiPitch );
68  double scale = 1./4096/hsPhiPitch;
69 
70  int phi = static_cast<int>(phiDT*scale) + offsetLoc;
71 
72  return phi;
73 }
76 int AngleConverter::getProcessorPhi(unsigned int iProcessor, l1t::tftype part, const CSCDetId & csc, const CSCCorrelatedLCTDigi &digi) const
77 {
78 
79  const double hsPhiPitch = 2*M_PI/OMTFConfiguration::instance()->nPhiBins; //
80  const int dummy = OMTFConfiguration::instance()->nPhiBins;
81 
82  int processor= iProcessor+1; // FIXME: get from OMTF name when available
83  int posneg = (part==l1t::tftype::omtf_pos) ? 1 : -1; // FIXME: get from OMTF name
84 
85 
86 
87  // filter out chambers not connected to OMTF board
88  // FIXME: temporary - use Connections or relay that filtering done before.
89  if (posneg != csc.zendcap()) return dummy;
90  if ( csc.ring() != 3 && !(csc.ring()==2 && (csc.station()==2 || csc.station()==3 || csc.station()==1)) ) return dummy;
91  if (processor !=6) {
92  if (csc.chamber() < (processor-1)*6 + 2) return dummy;
93  if (csc.chamber() > (processor-1)*6 + 8) return dummy;
94  } else {
95  if (csc.chamber() > 2 && csc.chamber() < 32) return dummy;
96  }
97 
98  //
99  // assign number 0..6, consecutive processor for a processor
100  //
101  //int ichamber = (csc.chamber()-2-6*(processor-1));
102  //if (ichamber < 0) ichamber += 36;
103 
104  //
105  // get offset for each chamber.
106  // FIXME: These parameters depends on processor and chamber only so may be precomputed and put in map
107  //
108  const CSCChamber* chamber = _geocsc->chamber(csc);
109  const CSCChamberSpecs* cspec = chamber->specs();
110  const CSCLayer* layer = chamber->layer(3);
111  int order = ( layer->centerOfStrip(2).phi() - layer->centerOfStrip(1).phi()> 0) ? 1 : -1;
112  double stripPhiPitch = cspec->stripPhiPitch();
113  double scale = fabs(stripPhiPitch/hsPhiPitch/2.); if ( fabs(scale-1.) < 0.0002) scale=1.;
114  double phi15deg = M_PI/3.*(processor-1)+M_PI/12.;
115  double phiHalfStrip0 = layer->centerOfStrip(10).phi() - order*9*stripPhiPitch - order*stripPhiPitch/4.;
116  if ( processor==6 || phiHalfStrip0<0) phiHalfStrip0 += 2*M_PI;
117  int offsetLoc = lround( (phiHalfStrip0-phi15deg)/hsPhiPitch );
118 
119  int halfStrip = digi.getStrip(); // returns halfStrip 0..159
120  //FIXME: to be checked (only important for ME1/3) keep more bits for offset, truncate at the end
121  int phi = offsetLoc + order*scale*halfStrip;
122 
123  return phi;
124 }
125 
128 int AngleConverter::getProcessorPhi(unsigned int iProcessor, l1t::tftype part, const RPCDetId & rollId, const unsigned int &digi) const
129 {
130  const double hsPhiPitch = 2*M_PI/OMTFConfiguration::instance()->nPhiBins; //
131  const int dummy = OMTFConfiguration::instance()->nPhiBins;
132 
133  int processor = iProcessor+1;
134  const RPCRoll* roll = _georpc->roll(rollId);
135  if (!roll) return dummy;
136 
137  double phi15deg = M_PI/3.*(processor-1)+M_PI/12.; // "0" is 15degree moved cyclicaly to each processor, note [0,2pi]
138  double stripPhi = (roll->toGlobal(roll->centreOfStrip((int)digi))).phi(); // note [-pi,pi]
139 
140  // adjust [0,2pi] and [-pi,pi] to get deltaPhi difference properly
141  switch (processor) {
142  case 1: break;
143  case 6: {phi15deg -= 2*M_PI; break; }
144  default : {if (stripPhi < 0) stripPhi += 2*M_PI; break; }
145  }
146 
147  // local angle in CSC halfStrip usnits
148  int halfStrip = lround ( (stripPhi-phi15deg)/hsPhiPitch );
149 
150  return halfStrip;
151 }
154 int AngleConverter::getGlobalEta(unsigned int rawid,
155  const L1MuDTChambPhDigi &aDigi,
156  const L1MuDTChambThContainer *dtThDigis){
157 
158 
159  const DTChamberId baseid(aDigi.whNum(),aDigi.stNum(),aDigi.scNum()+1);
160 
161  // do not use this pointer for anything other than creating a trig geom
162  std::unique_ptr<DTChamber> chamb(const_cast<DTChamber*>(_geodt->chamber(baseid)));
163 
164  std::unique_ptr<DTTrigGeom> trig_geom( new DTTrigGeom(chamb.get(),false) );
165  chamb.release(); // release it here so no one gets funny ideas
166  // super layer one is the theta superlayer in a DT chamber
167  // station 4 does not have a theta super layer
168  // the BTI index from the theta trigger is an OR of some BTI outputs
169  // so, we choose the BTI that's in the middle of the group
170  // as the BTI that we get theta from
171  // TODO:::::>>> need to make sure this ordering doesn't flip under wheel sign
172  const int NBTI_theta = ( (baseid.station() != 4) ?
173  trig_geom->nCell(2) : trig_geom->nCell(3) );
174  const int bti_group = findBTIgroup(aDigi,dtThDigis);
175  const unsigned bti_actual = bti_group*NBTI_theta/7 + NBTI_theta/14 + 1;
176  DTBtiId thetaBTI;
177  if ( baseid.station() != 4 && bti_group != -1) {
178  thetaBTI = DTBtiId(baseid,2,bti_actual);
179  } else {
180  // since this is phi oriented it'll give us theta in the middle
181  // of the chamber
182  thetaBTI = DTBtiId(baseid,3,1);
183  }
184  const GlobalPoint theta_gp = trig_geom->CMSPosition(thetaBTI);
185  int iEta = theta_gp.eta()/2.61*240;
186  return iEta;
187 }
190 int AngleConverter::getGlobalEta(unsigned int rawid, const CSCCorrelatedLCTDigi &aDigi){
191 
195 
196 
197  // alot of this is transcription and consolidation of the CSC
198  // global phi calculation code
199  // this works directly with the geometry
200  // rather than using the old phi luts
201  const CSCDetId id(rawid);
202  // we should change this to weak_ptrs at some point
203  // requires introducing std::shared_ptrs to geometry
204  std::unique_ptr<const CSCChamber> chamb(_geocsc->chamber(id));
205  std::unique_ptr<const CSCLayerGeometry> layer_geom(
206  chamb->layer(CSCConstants::KEY_ALCT_LAYER)->geometry()
207  );
208  std::unique_ptr<const CSCLayer> layer(
209  chamb->layer(CSCConstants::KEY_ALCT_LAYER)
210  );
211 
212  const uint16_t halfstrip = aDigi.getStrip();
213  const uint16_t pattern = aDigi.getPattern();
214  const uint16_t keyWG = aDigi.getKeyWG();
215  //const unsigned maxStrips = layer_geom->numberOfStrips();
216 
217  // so we can extend this later
218  // assume TMB2007 half-strips only as baseline
219  double offset = 0.0;
220  switch(1) {
221  case 1:
222  offset = CSCPatternLUT::get2007Position(pattern);
223  }
224  const unsigned halfstrip_offs = unsigned(0.5 + halfstrip + offset);
225  const unsigned strip = halfstrip_offs/2 + 1; // geom starts from 1
226 
227  // the rough location of the hit at the ALCT key layer
228  // we will refine this using the half strip information
229  const LocalPoint coarse_lp =
230  layer_geom->stripWireGroupIntersection(strip,keyWG);
231  const GlobalPoint coarse_gp = layer->surface().toGlobal(coarse_lp);
232 
233  // the strip width/4.0 gives the offset of the half-strip
234  // center with respect to the strip center
235  const double hs_offset = layer_geom->stripPhiPitch()/4.0;
236 
237  // determine handedness of the chamber
238  const bool ccw = isCSCCounterClockwise(layer);
239  // we need to subtract the offset of even half strips and add the odd ones
240  const double phi_offset = ( ( halfstrip_offs%2 ? 1 : -1)*
241  ( ccw ? -hs_offset : hs_offset ) );
242 
243  // the global eta calculation uses the middle of the strip
244  // so no need to increment it
245  const GlobalPoint final_gp( GlobalPoint::Polar( coarse_gp.theta(),
246  (coarse_gp.phi().value() +
247  phi_offset),
248  coarse_gp.mag() ) );
249  // release ownership of the pointers
250  chamb.release();
251  layer_geom.release();
252  layer.release();
253 
254  int iEta = final_gp.eta()/2.61*240;
255  return iEta;
256 }
259 int AngleConverter::getGlobalEta(unsigned int rawid, const unsigned int &strip){
260 
261  const RPCDetId id(rawid);
262  std::unique_ptr<const RPCRoll> roll(_georpc->roll(id));
263  const LocalPoint lp = roll->centreOfStrip((int)strip);
264  const GlobalPoint gp = roll->toGlobal(lp);
265  roll.release();
266 
267  float iEta = gp.eta()/2.61*240;
268 
269  return iEta;
270 
271 }
274 bool AngleConverter::
275 isCSCCounterClockwise(const std::unique_ptr<const CSCLayer>& layer) const {
276  const int nStrips = layer->geometry()->numberOfStrips();
277  const double phi1 = layer->centerOfStrip(1).phi();
278  const double phiN = layer->centerOfStrip(nStrips).phi();
279  return ( (std::abs(phi1 - phiN) < M_PI && phi1 >= phiN) ||
280  (std::abs(phi1 - phiN) >= M_PI && phi1 < phiN) );
281 }
285  const L1MuDTChambThContainer *dtThDigis){
286 
287  int bti_group = -1;
288 
289  const L1MuDTChambThDigi *theta_segm = dtThDigis->chThetaSegm(aDigi.whNum(),
290  aDigi.stNum(),
291  aDigi.scNum(),
292  aDigi.bxNum());
293  if(!theta_segm) return bti_group;
294 
295  for(unsigned int i = 0; i < 7; ++i ){
296  if(theta_segm->position(i) && bti_group<0) bti_group = i;
300  else if(theta_segm->position(i) && bti_group>-1) return -1;
301  }
302 
303  return bti_group;
304 }
int chamber() const
Definition: CSCDetId.h:68
int getStrip() const
return the key halfstrip from 0,159
unsigned long long cacheIdentifier() const
int i
Definition: DBlmapReader.cc:9
LocalPoint centreOfStrip(int strip) const
Definition: RPCRoll.cc:52
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:52
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
int getGlobalEta(unsigned int rawid, const L1MuDTChambPhDigi &aDigi, const L1MuDTChambThContainer *dtThDigis)
Convert local eta coordinate to global digital microGMT scale.
unsigned long long _geom_cache_id
int position(const int i) const
Geom::Theta< T > theta() const
Definition: PV3DBase.h:75
int getProcessorPhi(unsigned int iProcessor, l1t::tftype part, const L1MuDTChambPhDigi &digi) const
float stripPhiPitch() const
T mag() const
Definition: PV3DBase.h:67
const CSCChamberSpecs * specs() const
Definition: CSCChamber.h:42
void get(HolderT &iHolder) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const CSCLayer * layer(CSCDetId id) const
Return the layer corresponding to the given id.
Definition: CSCChamber.cc:39
unsigned int nPhiBins
const int findBTIgroup(const L1MuDTChambPhDigi &aDigi, const L1MuDTChambThContainer *dtThDigis)
Find BTI group.
bool isCSCCounterClockwise(const std::unique_ptr< const CSCLayer > &layer) const
Check orientation of strips in given CSC chamber.
#define M_PI
T value() const
Explicit access to value in case implicit conversion not OK.
Definition: Phi.h:38
int ring() const
Definition: CSCDetId.h:75
short int zendcap() const
Definition: CSCDetId.h:100
GlobalPoint centerOfStrip(int strip) const
Definition: CSCLayer.cc:4
static double get2007Position(int pattern)
part
Definition: HCALResponse.h:20
const T & get() const
Definition: EventSetup.h:56
L1MuDTChambThDigi const * chThetaSegm(int wheel, int stat, int sect, int bx) const
T eta() const
Definition: PV3DBase.h:76
int getPattern() const
return pattern
edm::ESHandle< CSCGeometry > _geocsc
int station() const
Definition: CSCDetId.h:86
edm::ESHandle< RPCGeometry > _georpc
static const OMTFConfiguration * instance()
int getKeyWG() const
return the key wire group
void checkAndUpdateGeometry(const edm::EventSetup &)
Update the Geometry with current Event Setup.
edm::ESHandle< DTGeometry > _geodt