CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CSCMake2DRecHit.cc
Go to the documentation of this file.
1 // This is CSCMake2DRecHit
2 
8 
11 
15 
18 
19 #include <iostream>
20 #include <algorithm>
21 #include <cmath>
22 #include <string>
23 
24 
26  peakTimeFinder_( new CSCFindPeakTime( ps ) ){
27 
28  useCalib = ps.getParameter<bool>("CSCUseCalibrations");
29  stripWireDeltaTime = ps.getParameter<int>("CSCstripWireDeltaTime"); //@@ Non-standard CSC*s*trip...
30  useTimingCorrections= ps.getParameter<bool>("CSCUseTimingCorrections");
31 
33 
34 }
35 
36 
38  delete xMatchGatti_;
39 }
40 
41 
43  const CSCWireHit& wHit, const CSCStripHit& sHit)
44 {
45  // Cache layer info for ease of access
46  layer_ = layer;
48  specs_ = layer->chamber()->specs();
49  id_ = id;
50 
51  const float sqrt_12 = 3.4641;
52 
53  float tpeak = -99.;
54 
57 
58  // Find wire hit position and wire properties
59  wgroups = wHit.wgroups();
60 
61  int wg_left = wgroups[0];;
62  int wg_right = wgroups[wgroups.size()-1];
63 
64  int Nwires1 = layergeom_->numberOfWiresPerGroup( wg_left );
65  int Nwires2 = layergeom_->numberOfWiresPerGroup( wg_right );
66 
67  float Mwire1 = layergeom_->middleWireOfGroup( wg_left );
68  float Mwire2 = layergeom_->middleWireOfGroup( wg_right );
69 
70  int centerWire_left = (int) (Mwire1 - Nwires1 / 2. + 0.5);
71  int centerWire_right = (int) (Mwire2 + Nwires2 / 2.);
72 
73  float centerWire = (centerWire_left + centerWire_right) / 2.;
74 
75  //---- WGs around dead HV segment regions may need special treatment...
76  //---- This is not addressed here.
77 
78  float sigmaWire = 0.;
79  if(wHit.deadWG()>0 || wgroups.size()>2){
80  //---- worst possible case; take most conservative approach
81  for(unsigned int iWG=0;iWG<wgroups.size();iWG++){
82  sigmaWire+=layergeom_->yResolution( wgroups[iWG] );
83  }
84  }
85  else if(2==wgroups.size()){
86  //---- 2 WGs - get the larger error (overestimation if a single track is passing
87  //---- between the WGs; underestimation if there are two separate signal sources)
88  if(layergeom_->yResolution( wgroups[0] ) > layergeom_->yResolution( wgroups[1] )){
89  sigmaWire = layergeom_->yResolution( wgroups[0]);
90  }
91  else{
92  sigmaWire = layergeom_->yResolution( wgroups[1]);
93  }
94  }
95  else if(1==wgroups.size()){
96  //---- simple - just 1 WG
97  sigmaWire = layergeom_->yResolution( wgroups[0]);
98  }
99 
100  // Find strips position and properties
101 
103  int tmax = sHit.tmax();
104  int nStrip = strips.size();
105  int idCenterStrip = nStrip/2;
106  int centerStrip = strips[idCenterStrip];
107 
108  // Retrieve strip pulseheights from the CSCStripHit
109  const std::vector<float>& adc = sHit.s_adc();
110  const std::vector<float>& adcRaw = sHit.s_adcRaw();
111 
112  std::vector<float> adc2;
113  std::vector<float> adc2Raw;
114 
115  LogTrace("CSCRecHit") << "CSCMake2DRecHit: dump of adc values to be added to rechit follows...";
116 
117  for ( int iStrip = 0; iStrip < nStrip; ++iStrip) {
118 
119  adc2.clear();
120  adc2Raw.clear();
121  for ( int t = 0; t < 4; ++t ){
122  adc2.push_back(adc[t+iStrip*4]);
123  adc2Raw.push_back(adcRaw[t+iStrip*4]);
124  }
125  // OLD: Rechit takes _calibrated_ adc values
126  // adcMap.put( strips[iStrip], adc2.begin(), adc2.end() );
127  // NEW: Rechit takes _raw_ adc values
128  adcMap.put( strips[iStrip], adc2Raw.begin(), adc2Raw.end() );
129 
130  LogTrace("CSCRecHit") << "CSCMake2DRecHit: strip = " << strips[iStrip] <<
131  " adcs= " << adc2Raw[0] << " " << adc2Raw[1] << " " << adc2Raw[2] << " " << adc2Raw[3];
132 
133  }
134 
135  //The tpeak finding for both edge and non-edge strips has been moved to here
136  //tpeak will be a const argument for xMatchGatti_->findXOnStrip
137  float adcArray[4];
138  for ( int t = 0; t < 4; ++t ) {
139  int k = t+4*(idCenterStrip);
140  adcArray[t] = adc[k];
141  }
142  tpeak = peakTimeFinder_->peakTime( tmax, adcArray, tpeak );
143  // Just for completeness, the start time of the pulse is 133 ns earlier, according to Stan :)
144  float t_zero = tpeak - 133.;
145  LogTrace("CSCRecHit|CSCMake2DRecHit") << "CSCMake2DRecHit: " <<
146  id << " strip=" << centerStrip << ", t_zero=" << t_zero << ", tpeak=" << tpeak;
147 
148 
149  float positionWithinTheStrip= -99.;
150  float sigmaWithinTheStrip = -99.;
151  int quality = -1;
152  LocalPoint lp0(0., 0.);
153 
154  float stripWidth = -99.;
155  // If at the edge, then used 1 strip cluster only
156  if ( centerStrip == 1 || centerStrip == specs_->nStrips() || nStrip < 2 ) {
157  lp0 = layergeom_->stripWireIntersection( centerStrip, centerWire);
158  positionWithinTheStrip = 0.;
159  stripWidth = layergeom_->stripPitch(lp0);
160  sigmaWithinTheStrip = stripWidth / sqrt_12;
161  quality = 2;
162  }
163  else {
164  // If not at the edge, used cluster of size ClusterSize:
165  LocalPoint lp11 = layergeom_->stripWireIntersection( centerStrip, centerWire);
166  stripWidth = layergeom_->stripPitch( lp11 );
167 
168  //---- Calculate local position within the strip
169  float xWithinChamber = lp11.x();
170  quality = 0;
171  if(layergeom_->inside(lp11 )){// save time; this hit is to be discarded anyway - see isHitInFiducial(...)
172 
173  xMatchGatti_->findXOnStrip( id, layer_, sHit, centerStrip,
174  xWithinChamber,
175  stripWidth, tpeak, positionWithinTheStrip,
176  sigmaWithinTheStrip, quality);
177  }
178  lp0 = LocalPoint( xWithinChamber, layergeom_->yOfWire(centerWire, xWithinChamber) );
179  }
180 
181 
182 
183  // compute the errors in local x and y
184  LocalError localerr = layergeom_->localError( centerStrip,
185  sigmaWithinTheStrip, sigmaWire );
186 
187  // Before storing the recHit, take the opportunity to change its time
189  float chipCorrection = recoConditions_->chipCorrection(id,centerStrip);
190  float phaseCorrection = (sHit.stripsl1a()[0]>> (15-0) & 0x1)*25.;
191  float chamberCorrection = recoConditions_->chamberTimingCorrection(id);
192 
193  GlobalPoint gp0 = layer_->toGlobal(lp0);
194  float tofCorrection = gp0.mag()/29.9792458;
195  //float yCorrection = lp0.y()*0.012;
196  //printf("RecHit in e:%d s:%d r:%d c:%d l:%d strip:%d \n",id.endcap(),id.station(), id.ring(),id.chamber(),id.layer(),centerStrip);
197  //printf("\t tpeak before = %5.2f \t chipCorr %5.2f phaseCorr %5.2f chamberCorr %5.2f tofCorr %5.2f \n",
198  // tpeak,chipCorrection, phaseCorrection,chamberCorrection,tofCorrection);
199  //printf("localy = %5.2f, yCorr = %5.2f \n",lp0.y(),yCorrection);
200  tpeak = tpeak + chipCorrection + phaseCorrection + chamberCorrection-tofCorrection;//-yCorrection;
201  //printf("\t tpeak after = %5.2f\n",tpeak);
202  }
203 
204  // Calculate wire time to the half bx level using time bins on
205  // Store wire time with a precision of 0.01 as an int (multiply by 100)
206  // Convert from bx to ns (multiply by 25)
207  int scaledWireTime = 100*findWireBx(wHit.timeBinsOn(), tpeak,id)*25;
208 
210 
212  CSCRecHit2D::ChannelContainer L1A_and_strips = sHit.stripsTotal();
213  CSCRecHit2D::ChannelContainer BX_and_wgroups = wHit.wgroupsBXandWire();
215  // (sigmaWithinTheStrip/stripWidth) is in strip widths just like positionWithinTheStrip is!
216  CSCRecHit2D rechit( id, lp0, localerr, L1A_and_strips,
217  //adcMap, wgroups, tpeak, positionWithinTheStrip,
218  adcMap, BX_and_wgroups, tpeak, positionWithinTheStrip,
219  sigmaWithinTheStrip/stripWidth, quality, sHit.deadStrip(), wHit.deadWG(), scaledWireTime);
220 
222  // rechit.print();
223 
224  LogTrace("CSCRecHit") << "CSCMake2DRecHit: rechit created in layer " << id << "... \n" << rechit << "\n";
225 
226  return rechit;
227 
228 }
229 
230 
231 bool CSCMake2DRecHit::isHitInFiducial( const CSCLayer* layer, const CSCRecHit2D& rh ) {
232 
233  bool isInFiducial = true;
234  const CSCLayerGeometry* layergeom_ = layer->geometry();
235  LocalPoint rhPosition = rh.localPosition();
236  // is the rechit within the chamber?
237  //(the problem occurs in ME11a/b otherwise it is OK)
238  // we could use also
239  //bool inside( const Local3DPoint&, const LocalError&, float scale=1.f ) const;
240  if(!layergeom_->inside(rhPosition)){
241  isInFiducial = false;
242  }
243 
244  return isInFiducial;
245 }
246 
247 
249  xMatchGatti_->setConditions( reco );
250  // And cache for use here
252 }
253 
254 float CSCMake2DRecHit::findWireBx(std::vector <int> timeBinsOn, float tpeak ,const CSCDetId& id) {
255  // Determine the wire Bx from the vector of time bins on for the wire digi with peak time as an intial estimate.
256  // Assumes that a single hit should create either one time bin on or two consecutive time bins on
257  // so algorithm looks for bin on nearest to peak time and checks if it has a bin on consecutive with it
258  float anode_bx_offset = recoConditions_->anodeBXoffset(id);
259  float wireBx=-1;
260  float timeGuess=tpeak/25.+ anode_bx_offset;
261  float diffMin=9999.;
262  int bestMatch=-9;
263  for (int j=0; j<(int)timeBinsOn.size(); j++) {
264  double diff=timeGuess-timeBinsOn[j];
265  // Find bin on closest to peak time
266  if (fabs(diff)<fabs(diffMin)) {
267  diffMin=diff;
268  bestMatch=j;
269  wireBx=timeBinsOn[j];
270  }
271  }
272  int side=diffMin/fabs(diffMin);
273  bool unchanged=true;
274  // First check if bin on the same side as peak time is on
275  if ((bestMatch+side)>-1 && (bestMatch+side)<(int)timeBinsOn.size()) { // Make sure one next to it within vector limits
276  if (timeBinsOn[bestMatch]==(timeBinsOn[bestMatch+side]-side)) { // See if next bin on in vector is consecutive in time
277  // Set time to the average of the two bins
278  wireBx=wireBx+(float)side/2.;
279  unchanged=false;
280  }
281  }
282  // If no match is found then check the other side
283  if ((bestMatch-side)>-1 && (bestMatch-side)<(int)timeBinsOn.size() && unchanged) { // Make sure one next to it exists
284  if (timeBinsOn[bestMatch]==(timeBinsOn[bestMatch-side]+side)) { // See if nextbin on is consecutive in time
285  wireBx=wireBx-(double)side/2.;
286  unchanged=false;
287  }
288  }
289  return wireBx - anode_bx_offset; // expect collision muons to be centered near 0 bx
290 }
int adc(sample_type sample)
get the ADC sample (12 bits)
int nStrips() const
const CSCLayer * layer_
T getParameter(std::string const &) const
ChannelContainer wgroups() const
The wire groups used for forming the cluster.
Definition: CSCWireHit.h:41
const ChannelContainer & stripsl1a() const
L1A.
Definition: CSCStripHit.h:56
std::vector< int > timeBinsOn() const
Vector of time bins ON for central wire digi, lower of center pair if even number.
Definition: CSCWireHit.h:56
const StripHitADCContainer & s_adcRaw() const
the raw ADC counts for each of the strip within cluster
Definition: CSCStripHit.h:62
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:49
const StripHitADCContainer & s_adc() const
L1A.
Definition: CSCStripHit.h:59
int numberOfWiresPerGroup(int wireGroup) const
float stripPitch() const
const CSCChamberSpecs * specs_
ChannelContainer wgroupsBXandWire() const
The BX + wire group number.
Definition: CSCWireHit.h:47
void setConditions(const CSCRecoConditions *reco)
Pass pointer to conditions data onwards.
LocalError localError(int strip, float sigmaStrip, float sigmaWire) const
short int deadStrip() const
is a neighbouring string a dead strip?
Definition: CSCStripHit.h:71
void setConditions(const CSCRecoConditions *reco)
Cache pointer to conditions data.
T mag() const
Definition: PV3DBase.h:61
CSCXonStrip_MatchGatti * xMatchGatti_
float yOfWire(float wire, float x=0.) const
const CSCChamberSpecs * specs() const
Definition: CSCChamber.h:42
float middleWireOfGroup(int wireGroup) const
float yResolution(int wireGroup=1) const
int j
Definition: DBlmapReader.cc:9
bool isHitInFiducial(const CSCLayer *layer, const CSCRecHit2D &rh)
Test if rechit is in fiducial volume.
#define LogTrace(id)
void put(ID id, CI begin, CI end)
insert an object range with specified identifier
Definition: RangeMap.h:119
int k[5][pyjets_maxn]
float chipCorrection(const CSCDetId &detId, int channel) const
static const double tmax[3]
int tmax() const
Strip hit maximum time bin.
Definition: CSCStripHit.h:47
float findWireBx(std::vector< int > timeBinsOn, float tpeak, const CSCDetId &id)
const CSCRecoConditions * recoConditions_
const ChannelContainer & stripsTotal() const
The strips used in cluster to produce strip hit (total content)
Definition: CSCStripHit.h:50
float anodeBXoffset(const CSCDetId &detId) const
const CSCLayerGeometry * layergeom_
const std::auto_ptr< CSCFindPeakTime > peakTimeFinder_
void findXOnStrip(const CSCDetId &id, const CSCLayer *layer, const CSCStripHit &stripHit, int centralStrip, float &xWithinChamber, float &stripWidth, const float &tpeak, float &xWithinStrip, float &sigma, int &quality_flag)
Returns fitted local x position and its estimated error.
CSCRecHit2D hitFromStripAndWire(const CSCDetId &id, const CSCLayer *layer, const CSCWireHit &wHit, const CSCStripHit &sHit)
Make 2D hits when have both wire and strip hit available in same layer.
const ChannelContainer & strips() const
L1A.
Definition: CSCStripHit.h:53
LocalPoint stripWireIntersection(int strip, float wire) const
Local3DPoint LocalPoint
Definition: LocalPoint.h:11
bool inside(const Local3DPoint &, const LocalError &, float scale=1.f) const
LocalPoint localPosition() const
Definition: CSCRecHit2D.h:45
CSCMake2DRecHit(const edm::ParameterSet &)
T x() const
Definition: PV3DBase.h:56
const CSCChamber * chamber() const
Definition: CSCLayer.h:52
const CSCLayerGeometry * geometry() const
Definition: CSCLayer.h:47
short int deadWG() const
a dead WG in the cluster?
Definition: CSCWireHit.h:53
float chamberTimingCorrection(const CSCDetId &detId) const
std::vector< int > ChannelContainer
Definition: CSCRecHit2D.h:22