00001
00002
00003 #include <RecoLocalMuon/CSCRecHitD/src/CSCMake2DRecHit.h>
00004 #include <RecoLocalMuon/CSCRecHitD/src/CSCXonStrip_MatchGatti.h>
00005 #include <RecoLocalMuon/CSCRecHitD/src/CSCStripHit.h>
00006 #include <RecoLocalMuon/CSCRecHitD/src/CSCWireHit.h>
00007 #include <RecoLocalMuon/CSCRecHitD/src/CSCRecoConditions.h>
00008
00009 #include <DataFormats/CSCRecHit/interface/CSCRecHit2D.h>
00010 #include <DataFormats/MuonDetId/interface/CSCDetId.h>
00011
00012 #include <Geometry/CSCGeometry/interface/CSCLayer.h>
00013 #include <Geometry/CSCGeometry/interface/CSCChamberSpecs.h>
00014 #include <Geometry/CSCGeometry/interface/CSCLayerGeometry.h>
00015
00016 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00017 #include <FWCore/Utilities/interface/Exception.h>
00018
00019 #include <iostream>
00020 #include <algorithm>
00021 #include <cmath>
00022 #include <string>
00023
00024
00025 CSCMake2DRecHit::CSCMake2DRecHit(const edm::ParameterSet& ps):
00026 peakTimeFinder_( new CSCFindPeakTime( ps ) ){
00027
00028 useCalib = ps.getParameter<bool>("CSCUseCalibrations");
00029 stripWireDeltaTime = ps.getParameter<int>("CSCstripWireDeltaTime");
00030 useTimingCorrections= ps.getParameter<bool>("CSCUseTimingCorrections");
00031 useGasGainCorrections = ps.getParameter<bool>("CSCUseGasGainCorrections");
00032
00033 xMatchGatti_ = new CSCXonStrip_MatchGatti( ps );
00034
00035 }
00036
00037
00038 CSCMake2DRecHit::~CSCMake2DRecHit() {
00039 delete xMatchGatti_;
00040 }
00041
00042
00043 CSCRecHit2D CSCMake2DRecHit::hitFromStripAndWire(const CSCDetId& id, const CSCLayer* layer,
00044 const CSCWireHit& wHit, const CSCStripHit& sHit)
00045 {
00046
00047 layer_ = layer;
00048 layergeom_ = layer_->geometry();
00049 specs_ = layer->chamber()->specs();
00050 id_ = id;
00051
00052 const float sqrt_12 = 3.4641;
00053
00054 float tpeak = -99.;
00055
00056 CSCRecHit2D::ADCContainer adcMap;
00057 CSCRecHit2D::ChannelContainer wgroups;
00058
00059
00060 wgroups = wHit.wgroups();
00061
00062 int wg_left = wgroups[0];;
00063 int wg_right = wgroups[wgroups.size()-1];
00064
00065 int Nwires1 = layergeom_->numberOfWiresPerGroup( wg_left );
00066 int Nwires2 = layergeom_->numberOfWiresPerGroup( wg_right );
00067
00068 float Mwire1 = layergeom_->middleWireOfGroup( wg_left );
00069 float Mwire2 = layergeom_->middleWireOfGroup( wg_right );
00070
00071 int centerWire_left = (int) (Mwire1 - Nwires1 / 2. + 0.5);
00072 int centerWire_right = (int) (Mwire2 + Nwires2 / 2.);
00073
00074 float centerWire = (centerWire_left + centerWire_right) / 2.;
00075
00076
00077
00078
00079 float sigmaWire = 0.;
00080 if(wHit.deadWG()>0 || wgroups.size()>2){
00081
00082 for(unsigned int iWG=0;iWG<wgroups.size();iWG++){
00083 sigmaWire+=layergeom_->yResolution( wgroups[iWG] );
00084 }
00085 }
00086 else if(2==wgroups.size()){
00087
00088
00089 if(layergeom_->yResolution( wgroups[0] ) > layergeom_->yResolution( wgroups[1] )){
00090 sigmaWire = layergeom_->yResolution( wgroups[0]);
00091 }
00092 else{
00093 sigmaWire = layergeom_->yResolution( wgroups[1]);
00094 }
00095 }
00096 else if(1==wgroups.size()){
00097
00098 sigmaWire = layergeom_->yResolution( wgroups[0]);
00099 }
00100
00101
00102
00103 CSCRecHit2D::ChannelContainer strips = sHit.strips();
00104 int tmax = sHit.tmax();
00105 int nStrip = strips.size();
00106 int idCenterStrip = nStrip/2;
00107 int centerStrip = strips[idCenterStrip];
00108
00109
00110 const std::vector<float>& adc = sHit.s_adc();
00111 const std::vector<float>& adcRaw = sHit.s_adcRaw();
00112
00113 std::vector<float> adc2;
00114 std::vector<float> adc2Raw;
00115
00116 LogTrace("CSCRecHit") << "CSCMake2DRecHit: dump of adc values to be added to rechit follows...";
00117
00118 for ( int iStrip = 0; iStrip < nStrip; ++iStrip) {
00119
00120 adc2.clear();
00121 adc2Raw.clear();
00122 adc2.reserve(4);
00123 adc2Raw.reserve(4);
00124 for ( int t = 0; t < 4; ++t ){
00125 adc2.push_back(adc[t+iStrip*4]);
00126 adc2Raw.push_back(adcRaw[t+iStrip*4]);
00127 }
00128
00129 adcMap.put( strips[iStrip], adc2.begin(), adc2.end() );
00130
00131
00132
00133 LogTrace("CSCRecHit") << "CSCMake2DRecHit: strip = " << strips[iStrip] <<
00134 " adcs= " << adc2Raw[0] << " " << adc2Raw[1] << " " << adc2Raw[2] << " " << adc2Raw[3];
00135
00136 }
00137
00138
00139
00140 float adcArray[4];
00141 for ( int t = 0; t < 4; ++t ) {
00142 int k = t+4*(idCenterStrip);
00143 adcArray[t] = adc[k];
00144 }
00145 tpeak = peakTimeFinder_->peakTime( tmax, adcArray, tpeak );
00146
00147 float t_zero = tpeak - 133.;
00148 LogTrace("CSCRecHit|CSCMake2DRecHit") << "CSCMake2DRecHit: " <<
00149 id << " strip=" << centerStrip << ", t_zero=" << t_zero << ", tpeak=" << tpeak;
00150
00151
00152 float positionWithinTheStrip= -99.;
00153 float sigmaWithinTheStrip = -99.;
00154 int quality = -1;
00155 LocalPoint lp0(0., 0.);
00156
00157 float stripWidth = -99.;
00158
00159 if ( centerStrip == 1 || centerStrip == specs_->nStrips() || nStrip < 2 ) {
00160 lp0 = layergeom_->stripWireIntersection( centerStrip, centerWire);
00161 positionWithinTheStrip = 0.;
00162 stripWidth = layergeom_->stripPitch(lp0);
00163 sigmaWithinTheStrip = stripWidth / sqrt_12;
00164 quality = 2;
00165 }
00166 else {
00167
00168 LocalPoint lp11 = layergeom_->stripWireIntersection( centerStrip, centerWire);
00169 stripWidth = layergeom_->stripPitch( lp11 );
00170
00171
00172 float xWithinChamber = lp11.x();
00173 quality = 0;
00174 if(layergeom_->inside(lp11 )){
00175
00176 xMatchGatti_->findXOnStrip( id, layer_, sHit, centerStrip,
00177 xWithinChamber,
00178 stripWidth, tpeak, positionWithinTheStrip,
00179 sigmaWithinTheStrip, quality);
00180 }
00181 lp0 = LocalPoint( xWithinChamber, layergeom_->yOfWire(centerWire, xWithinChamber) );
00182 }
00183
00184
00185
00186
00187 LocalError localerr = layergeom_->localError( centerStrip,
00188 sigmaWithinTheStrip, sigmaWire );
00189
00190
00191 if (useTimingCorrections){
00192 float chipCorrection = recoConditions_->chipCorrection(id,centerStrip);
00193 float phaseCorrection = (sHit.stripsl1a()[0]>> (15-0) & 0x1)*25.;
00194 float chamberCorrection = recoConditions_->chamberTimingCorrection(id);
00195
00196 GlobalPoint gp0 = layer_->toGlobal(lp0);
00197 float tofCorrection = gp0.mag()/29.9792458;
00198 float signalPropagationSpeed[11] = {0.0, -78, -76, -188, -262, -97, -99, -90, -99, -99, -113};
00199 float position = lp0.y()/sin(layergeom_->stripAngle(centerStrip));
00200 float yCorrection = position/signalPropagationSpeed[id_.iChamberType()];
00201
00202
00203
00204
00205 tpeak = tpeak + chipCorrection + phaseCorrection + chamberCorrection-tofCorrection+yCorrection;
00206
00207 }
00208
00209
00210
00211
00212 int scaledWireTime = 100*findWireBx(wHit.timeBinsOn(), tpeak,id)*25;
00213
00214
00215
00216 float gasGainCorrection = -999.;
00217 if (useGasGainCorrections) {
00218 gasGainCorrection = recoConditions_->gasGainCorrection(id,centerStrip,centerWire);
00219 }
00220
00229 float energyDeposit = -999.;
00230 if (gasGainCorrection < -998.) {
00231
00232 energyDeposit = -998.;
00233
00234 } else if (gasGainCorrection < 0.) {
00235
00236 energyDeposit = -997.;
00237
00238 } else {
00239
00240 if (adcMap.size()==12) {
00241 energyDeposit =
00242 adcMap[0] * gasGainCorrection + adcMap[1] * gasGainCorrection + adcMap[2] * gasGainCorrection +
00243 adcMap[4] * gasGainCorrection + adcMap[5] * gasGainCorrection + adcMap[6] * gasGainCorrection +
00244 adcMap[8] * gasGainCorrection + adcMap[9] * gasGainCorrection + adcMap[10]* gasGainCorrection ;
00245
00246 } else if (adcMap.size()==4) {
00247
00248 energyDeposit = -996.;
00249 }
00250
00251 }
00252
00254
00256 CSCRecHit2D::ChannelContainer L1A_and_strips = sHit.stripsTotal();
00257
00258 CSCRecHit2D::ChannelContainer BX_and_wgroups = wHit.wgroupsBXandWire();
00259
00260 CSCRecHit2D rechit( id, lp0, localerr, L1A_and_strips,
00261
00262 adcMap, BX_and_wgroups, tpeak, positionWithinTheStrip,
00263 sigmaWithinTheStrip/stripWidth, quality, sHit.deadStrip(), wHit.deadWG(), scaledWireTime,
00264 energyDeposit);
00265
00267
00268
00269 LogTrace("CSCRecHit") << "CSCMake2DRecHit: rechit created in layer " << id << "... \n" << rechit << "\n";
00270
00271 return rechit;
00272
00273 }
00274
00275
00276 bool CSCMake2DRecHit::isHitInFiducial( const CSCLayer* layer, const CSCRecHit2D& rh ) {
00277
00278 bool isInFiducial = true;
00279 const CSCLayerGeometry* layergeom_ = layer->geometry();
00280 LocalPoint rhPosition = rh.localPosition();
00281
00282
00283
00284
00285 if(!layergeom_->inside(rhPosition)){
00286 isInFiducial = false;
00287 }
00288
00289 return isInFiducial;
00290 }
00291
00292
00293 void CSCMake2DRecHit::setConditions( const CSCRecoConditions* reco ) {
00294 xMatchGatti_->setConditions( reco );
00295
00296 recoConditions_ = reco;
00297 }
00298
00299 float CSCMake2DRecHit::findWireBx(std::vector <int> timeBinsOn, float tpeak ,const CSCDetId& id) {
00300
00301
00302
00303 float anode_bx_offset = recoConditions_->anodeBXoffset(id);
00304 float wireBx=-1;
00305 float timeGuess=tpeak/25.+ anode_bx_offset;
00306 float diffMin=9999.;
00307 int bestMatch=-9;
00308 for (int j=0; j<(int)timeBinsOn.size(); j++) {
00309 double diff=timeGuess-timeBinsOn[j];
00310
00311 if (fabs(diff)<fabs(diffMin)) {
00312 diffMin=diff;
00313 bestMatch=j;
00314 wireBx=timeBinsOn[j];
00315 }
00316 }
00317 int side=diffMin/fabs(diffMin);
00318 bool unchanged=true;
00319
00320 if ((bestMatch+side)>-1 && (bestMatch+side)<(int)timeBinsOn.size()) {
00321 if (timeBinsOn[bestMatch]==(timeBinsOn[bestMatch+side]-side)) {
00322
00323 wireBx=wireBx+(float)side/2.;
00324 unchanged=false;
00325 }
00326 }
00327
00328 if ((bestMatch-side)>-1 && (bestMatch-side)<(int)timeBinsOn.size() && unchanged) {
00329 if (timeBinsOn[bestMatch]==(timeBinsOn[bestMatch-side]+side)) {
00330 wireBx=wireBx-(double)side/2.;
00331 unchanged=false;
00332 }
00333 }
00334 return wireBx - anode_bx_offset;
00335 }