00001 #include <iomanip>
00002 #include "TrackingTools/TrackFitters/interface/TrajectoryStateCombiner.h"
00003 #include "FWCore/ServiceRegistry/interface/Service.h"
00004 #include "CommonTools/UtilAlgos/interface/TFileService.h"
00005 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00006 #include "Alignment/MuonAlignmentAlgorithms/plugins/CSCOverlapsAlignmentAlgorithm.h"
00007 #include "Alignment/MuonAlignmentAlgorithms/plugins/CSCPairResidualsConstraint.h"
00008
00009 double CSCPairResidualsConstraint::value() const {
00010 double delta = (m_sum1*m_sumxx) - (m_sumx*m_sumx);
00011 assert(delta > 0.);
00012 if (m_parent->m_mode == kModePhiy || m_parent->m_mode == kModePhiPos || m_parent->m_mode == kModeRadius) {
00013 return ((m_sumxx*m_sumy) - (m_sumx*m_sumxy))/delta;
00014 }
00015 else if (m_parent->m_mode == kModePhiz) {
00016 return ((m_sum1*m_sumxy) - (m_sumx*m_sumy))/delta;
00017 }
00018 else assert(false);
00019 }
00020
00021 double CSCPairResidualsConstraint::error() const {
00022 if (m_parent->m_errorFromRMS) {
00023 assert(m_sum1 > 0.);
00024 return sqrt((m_sumyy/m_sum1) - pow(m_sumy/m_sum1, 2))/sqrt(m_sumN);
00025 }
00026 else {
00027 double delta = (m_sum1*m_sumxx) - (m_sumx*m_sumx);
00028 assert(delta > 0.);
00029 if (m_parent->m_mode == kModePhiy || m_parent->m_mode == kModePhiPos || m_parent->m_mode == kModeRadius) {
00030 return sqrt(m_sumxx/delta);
00031 }
00032 else if (m_parent->m_mode == kModePhiz) {
00033 return sqrt(m_sum1/delta);
00034 }
00035 else assert(false);
00036 }
00037 }
00038
00039 bool CSCPairResidualsConstraint::valid() const {
00040 return (m_sumN >= m_parent->m_minTracksPerOverlap);
00041 }
00042
00043 void CSCPairResidualsConstraint::configure(CSCOverlapsAlignmentAlgorithm *parent) {
00044 m_parent = parent;
00045
00046 if (m_parent->m_makeHistograms) {
00047 edm::Service<TFileService> tFileService;
00048
00049 std::stringstream name, name2, name3, title;
00050 title << "i =" << m_id_i << " j =" << m_id_j;
00051
00052 name << "slopeResiduals_" << m_identifier;
00053 m_slopeResiduals = tFileService->make<TH1F>(name.str().c_str(), title.str().c_str(), 300, -30., 30.);
00054
00055 name2 << "offsetResiduals_" << m_identifier;
00056 m_offsetResiduals = tFileService->make<TH1F>(name2.str().c_str(), title.str().c_str(), 300, -30., 30.);
00057
00058 name3 << "radial_" << m_identifier;
00059 m_radial = tFileService->make<TH1F>(name3.str().c_str(), title.str().c_str(), 700, 0., 700.);
00060 }
00061 else {
00062 m_slopeResiduals = NULL;
00063 m_offsetResiduals = NULL;
00064 m_radial = NULL;
00065 }
00066 }
00067
00068 void CSCPairResidualsConstraint::setZplane(const CSCGeometry *cscGeometry) {
00069 m_cscGeometry = cscGeometry;
00070
00071 m_Zplane = (m_cscGeometry->idToDet(m_id_i)->surface().position().z() + m_cscGeometry->idToDet(m_id_j)->surface().position().z()) / 2.;
00072 m_averageRadius = (m_cscGeometry->idToDet(m_id_i)->surface().position().perp() + m_cscGeometry->idToDet(m_id_j)->surface().position().perp()) / 2.;
00073
00074 m_iZ = m_cscGeometry->idToDet(m_id_i)->surface().position().z();
00075 m_jZ = m_cscGeometry->idToDet(m_id_j)->surface().position().z();
00076
00077 CSCDetId i1(m_id_i.endcap(), m_id_i.station(), m_id_i.ring(), m_id_i.chamber(), 1);
00078 CSCDetId i6(m_id_i.endcap(), m_id_i.station(), m_id_i.ring(), m_id_i.chamber(), 6);
00079 CSCDetId j1(m_id_j.endcap(), m_id_j.station(), m_id_j.ring(), m_id_j.chamber(), 1);
00080 CSCDetId j6(m_id_j.endcap(), m_id_j.station(), m_id_j.ring(), m_id_j.chamber(), 6);
00081 m_iZ1 = m_cscGeometry->idToDet(m_id_i)->surface().toLocal(m_cscGeometry->idToDet(i1)->surface().position()).z();
00082 m_iZ6 = m_cscGeometry->idToDet(m_id_i)->surface().toLocal(m_cscGeometry->idToDet(i6)->surface().position()).z();
00083 m_jZ1 = m_cscGeometry->idToDet(m_id_j)->surface().toLocal(m_cscGeometry->idToDet(j1)->surface().position()).z();
00084 m_jZ6 = m_cscGeometry->idToDet(m_id_j)->surface().toLocal(m_cscGeometry->idToDet(j6)->surface().position()).z();
00085
00086 m_Zsurface = Plane::build(Plane::PositionType(0., 0., m_Zplane), Plane::RotationType());
00087 }
00088
00089 void CSCPairResidualsConstraint::setPropagator(const Propagator *propagator) {
00090 m_propagator = propagator;
00091 }
00092
00093 bool CSCPairResidualsConstraint::addTrack(const std::vector<TrajectoryMeasurement> &measurements, const reco::TransientTrack &track, const TrackTransformer *trackTransformer) {
00094 std::vector<const TransientTrackingRecHit*> hits_i;
00095 std::vector<const TransientTrackingRecHit*> hits_j;
00096
00097 for (std::vector<TrajectoryMeasurement>::const_iterator measurement = measurements.begin(); measurement != measurements.end(); ++measurement) {
00098 const TransientTrackingRecHit *hit = &*(measurement->recHit());
00099
00100 DetId id = hit->geographicalId();
00101 if (id.det() == DetId::Muon && id.subdetId() == MuonSubdetId::CSC) {
00102 CSCDetId cscid(id.rawId());
00103 CSCDetId chamberId(cscid.endcap(), cscid.station(), cscid.ring(), cscid.chamber(), 0);
00104 if (m_parent->m_combineME11 && cscid.station() == 1 && cscid.ring() == 4) chamberId = CSCDetId(cscid.endcap(), 1, 1, cscid.chamber(), 0);
00105
00106 if (chamberId == m_id_i) hits_i.push_back(hit);
00107 if (chamberId == m_id_j) hits_j.push_back(hit);
00108 }
00109 }
00110
00111 if (m_parent->m_makeHistograms) {
00112 m_parent->m_hitsPerChamber->Fill(hits_i.size());
00113 m_parent->m_hitsPerChamber->Fill(hits_j.size());
00114 }
00115
00116
00117 if (int(hits_i.size()) < m_parent->m_minHitsPerChamber || int(hits_j.size()) < m_parent->m_minHitsPerChamber) return false;
00118
00119
00120 if (m_parent->m_fiducial && !(isFiducial(hits_i, true) && isFiducial(hits_j, false))) return false;
00121
00122 double intercept_i = 0.;
00123 double interceptError2_i = 0.;
00124 double slope_i = 0.;
00125 double slopeError2_i = 0.;
00126 double intercept_j = 0.;
00127 double interceptError2_j = 0.;
00128 double slope_j = 0.;
00129 double slopeError2_j = 0.;
00130
00131
00132
00133 if (m_parent->m_slopeFromTrackRefit) {
00134 double dphidz;
00135 if (dphidzFromTrack(measurements, track, trackTransformer, dphidz)) {
00136 double sum1_i = 0.;
00137 double sumy_i = 0.;
00138 for (std::vector<const TransientTrackingRecHit*>::const_iterator hit = hits_i.begin(); hit != hits_i.end(); ++hit) {
00139 double phi, phierr2;
00140 calculatePhi(*hit, phi, phierr2, false, true);
00141 double z = (*hit)->globalPosition().z() - m_Zplane;
00142
00143 double weight = 1.;
00144 if (m_parent->m_useHitWeights) weight = 1./phierr2;
00145 sum1_i += weight;
00146 sumy_i += weight * (phi - z*dphidz);
00147 }
00148
00149 double sum1_j = 0.;
00150 double sumy_j = 0.;
00151 for (std::vector<const TransientTrackingRecHit*>::const_iterator hit = hits_j.begin(); hit != hits_j.end(); ++hit) {
00152 double phi, phierr2;
00153 calculatePhi(*hit, phi, phierr2, false, true);
00154 double z = (*hit)->globalPosition().z() - m_Zplane;
00155
00156 double weight = 1.;
00157 if (m_parent->m_useHitWeights) weight = 1./phierr2;
00158 sum1_j += weight;
00159 sumy_j += weight * (phi - z*dphidz);
00160 }
00161
00162 if (sum1_i != 0. && sum1_j != 0.) {
00163 slope_i = slope_j = dphidz;
00164
00165 intercept_i = sumy_i / sum1_i;
00166 interceptError2_i = 1. / sum1_i;
00167
00168 intercept_j = sumy_j / sum1_j;
00169 interceptError2_j = 1. / sum1_j;
00170 }
00171 else return false;
00172 }
00173 }
00174
00175 else {
00176 double sum1_i = 0.;
00177 double sumx_i = 0.;
00178 double sumy_i = 0.;
00179 double sumxx_i = 0.;
00180 double sumxy_i = 0.;
00181 for (std::vector<const TransientTrackingRecHit*>::const_iterator hit = hits_i.begin(); hit != hits_i.end(); ++hit) {
00182 double phi, phierr2;
00183 calculatePhi(*hit, phi, phierr2, false, true);
00184 double z = (*hit)->globalPosition().z() - m_Zplane;
00185
00186 double weight = 1.;
00187 if (m_parent->m_useHitWeights) weight = 1./phierr2;
00188 sum1_i += weight;
00189 sumx_i += weight * z;
00190 sumy_i += weight * phi;
00191 sumxx_i += weight * z*z;
00192 sumxy_i += weight * z*phi;
00193 }
00194
00195 double sum1_j = 0.;
00196 double sumx_j = 0.;
00197 double sumy_j = 0.;
00198 double sumxx_j = 0.;
00199 double sumxy_j = 0.;
00200 for (std::vector<const TransientTrackingRecHit*>::const_iterator hit = hits_j.begin(); hit != hits_j.end(); ++hit) {
00201 double phi, phierr2;
00202 calculatePhi(*hit, phi, phierr2, false, true);
00203 double z = (*hit)->globalPosition().z() - m_Zplane;
00204
00205 double weight = 1.;
00206 if (m_parent->m_useHitWeights) weight = 1./phierr2;
00207 sum1_j += weight;
00208 sumx_j += weight * z;
00209 sumy_j += weight * phi;
00210 sumxx_j += weight * z*z;
00211 sumxy_j += weight * z*phi;
00212 }
00213
00214 double delta_i = (sum1_i*sumxx_i) - (sumx_i*sumx_i);
00215 double delta_j = (sum1_j*sumxx_j) - (sumx_j*sumx_j);
00216 if (delta_i != 0. && delta_j != 0.) {
00217 intercept_i = ((sumxx_i*sumy_i) - (sumx_i*sumxy_i))/delta_i;
00218 interceptError2_i = sumxx_i/delta_i;
00219 slope_i = ((sum1_i*sumxy_i) - (sumx_i*sumy_i))/delta_i;
00220 slopeError2_i = sum1_i/delta_i;
00221
00222 intercept_j = ((sumxx_j*sumy_j) - (sumx_j*sumxy_j))/delta_j;
00223 interceptError2_j = sumxx_j/delta_j;
00224 slope_j = ((sum1_j*sumxy_j) - (sumx_j*sumy_j))/delta_j;
00225 slopeError2_j = sum1_j/delta_j;
00226 }
00227 else return false;
00228 }
00229
00230
00231 double sum1_ri = 0.;
00232 double sumx_ri = 0.;
00233 double sumy_ri = 0.;
00234 double sumxx_ri = 0.;
00235 double sumxy_ri = 0.;
00236 for (std::vector<const TransientTrackingRecHit*>::const_iterator hit = hits_i.begin(); hit != hits_i.end(); ++hit) {
00237 double r = (*hit)->globalPosition().perp();
00238 double z = (*hit)->globalPosition().z() - m_Zplane;
00239 sum1_ri += 1.;
00240 sumx_ri += z;
00241 sumy_ri += r;
00242 sumxx_ri += z*z;
00243 sumxy_ri += z*r;
00244 }
00245 double radial_delta_i = (sum1_ri*sumxx_ri) - (sumx_ri*sumx_ri);
00246 if (radial_delta_i == 0.) return false;
00247 double radial_slope_i = ((sum1_ri*sumxy_ri) - (sumx_ri*sumy_ri))/radial_delta_i;
00248 double radial_intercept_i = ((sumxx_ri*sumy_ri) - (sumx_ri*sumxy_ri))/radial_delta_i + radial_slope_i*(m_iZ - m_Zplane);
00249
00250 double sum1_rj = 0.;
00251 double sumx_rj = 0.;
00252 double sumy_rj = 0.;
00253 double sumxx_rj = 0.;
00254 double sumxy_rj = 0.;
00255 for (std::vector<const TransientTrackingRecHit*>::const_iterator hit = hits_j.begin(); hit != hits_j.end(); ++hit) {
00256 double r = (*hit)->globalPosition().perp();
00257 double z = (*hit)->globalPosition().z() - m_Zplane;
00258 sum1_rj += 1.;
00259 sumx_rj += z;
00260 sumy_rj += r;
00261 sumxx_rj += z*z;
00262 sumxy_rj += z*r;
00263 }
00264 double radial_delta_j = (sum1_rj*sumxx_rj) - (sumx_rj*sumx_rj);
00265 if (radial_delta_j == 0.) return false;
00266 double radial_slope_j = ((sum1_rj*sumxy_rj) - (sumx_rj*sumy_rj))/radial_delta_j;
00267 double radial_intercept_j = ((sumxx_rj*sumy_rj) - (sumx_rj*sumxy_rj))/radial_delta_j + radial_slope_j*(m_jZ - m_Zplane);
00268
00269 double radial_delta = ((sum1_ri + sum1_rj)*(sumxx_ri + sumxx_rj)) - ((sumx_ri + sumx_rj)*(sumx_ri + sumx_rj));
00270 if (radial_delta == 0.) return false;
00271 double radial_intercept = (((sumxx_ri + sumxx_rj)*(sumy_ri + sumy_rj)) - ((sumx_ri + sumx_rj)*(sumxy_ri + sumxy_rj)))/radial_delta;
00272 double radial_slope = (((sum1_ri + sum1_rj)*(sumxy_ri + sumxy_rj)) - ((sumx_ri + sumx_rj)*(sumy_ri + sumy_rj)))/radial_delta;
00273
00274 if (m_parent->m_makeHistograms) {
00275 m_parent->m_drdz->Fill(radial_slope);
00276 }
00277 if (m_parent->m_maxdrdz > 0. && fabs(radial_slope) > m_parent->m_maxdrdz) return false;
00278
00279 double quantity = 0.;
00280 double quantityError2 = 0.;
00281 if (m_parent->m_mode == kModePhiy) {
00282 quantity = (slope_i*radial_intercept_i) - (slope_j*radial_intercept_j);
00283 quantityError2 = (slopeError2_i)*pow(radial_intercept_i, 2) + (slopeError2_j)*pow(radial_intercept_j, 2);
00284 }
00285 else if (m_parent->m_mode == kModePhiPos || m_parent->m_mode == kModeRadius) {
00286 quantity = intercept_i - intercept_j;
00287 quantityError2 = interceptError2_i + interceptError2_j;
00288 }
00289 else if (m_parent->m_mode == kModePhiz) {
00290 quantity = (intercept_i - intercept_j) * radial_intercept;
00291 quantityError2 = (interceptError2_i + interceptError2_j) * pow(radial_intercept, 2);
00292 }
00293 else assert(false);
00294
00295 if (quantityError2 == 0.) return false;
00296
00297 double slopeResid = ((slope_i*radial_intercept_i) - (slope_j*radial_intercept_j)) * 1000.;
00298 double slopeResidError2 = ((slopeError2_i)*pow(radial_intercept_i, 2) + (slopeError2_j)*pow(radial_intercept_j, 2)) * 1000. * 1000.;
00299 double offsetResid = (intercept_i - intercept_j) * radial_intercept * 10.;
00300 double offsetResidError2 = (interceptError2_i + interceptError2_j) * pow(radial_intercept, 2) * 10. * 10.;
00301
00302 if (m_parent->m_truncateSlopeResid > 0. && fabs(slopeResid) > m_parent->m_truncateSlopeResid) return false;
00303 if (m_parent->m_truncateOffsetResid > 0. && fabs(offsetResid) > m_parent->m_truncateOffsetResid) return false;
00304
00305 double weight = 1.;
00306 if (m_parent->m_useTrackWeights) weight = 1./quantityError2;
00307
00308
00309 m_sumN += 1;
00310 m_sum1 += weight;
00311 m_sumx += weight * (radial_intercept - m_averageRadius);
00312 m_sumy += weight * quantity;
00313 m_sumxx += weight * pow(radial_intercept - m_averageRadius, 2);
00314 m_sumyy += weight * quantity*quantity;
00315 m_sumxy += weight * (radial_intercept - m_averageRadius)*quantity;
00316
00317 if (m_parent->m_makeHistograms) {
00318 double rphi_slope_i = slope_i * radial_intercept_i;
00319 double rphi_slope_j = slope_j * radial_intercept_j;
00320
00321 if (m_parent->m_slopeFromTrackRefit) {
00322 m_parent->m_slope->Fill(rphi_slope_i);
00323
00324 if (m_id_i.endcap() == 1 && m_id_i.station() == 4) m_parent->m_slope_MEp4->Fill(rphi_slope_i);
00325 if (m_id_i.endcap() == 1 && m_id_i.station() == 3) m_parent->m_slope_MEp3->Fill(rphi_slope_i);
00326 if (m_id_i.endcap() == 1 && m_id_i.station() == 2) m_parent->m_slope_MEp2->Fill(rphi_slope_i);
00327 if (m_id_i.endcap() == 1 && m_id_i.station() == 1) m_parent->m_slope_MEp1->Fill(rphi_slope_i);
00328 if (m_id_i.endcap() == 2 && m_id_i.station() == 1) m_parent->m_slope_MEm1->Fill(rphi_slope_i);
00329 if (m_id_i.endcap() == 2 && m_id_i.station() == 2) m_parent->m_slope_MEm2->Fill(rphi_slope_i);
00330 if (m_id_i.endcap() == 2 && m_id_i.station() == 3) m_parent->m_slope_MEm3->Fill(rphi_slope_i);
00331 if (m_id_i.endcap() == 2 && m_id_i.station() == 4) m_parent->m_slope_MEm4->Fill(rphi_slope_i);
00332 }
00333 else {
00334 m_parent->m_slope->Fill(rphi_slope_i); m_parent->m_slope->Fill(rphi_slope_j);
00335
00336 if (m_id_i.endcap() == 1 && m_id_i.station() == 4) { m_parent->m_slope_MEp4->Fill(rphi_slope_i); m_parent->m_slope_MEp4->Fill(rphi_slope_j); }
00337 if (m_id_i.endcap() == 1 && m_id_i.station() == 3) { m_parent->m_slope_MEp3->Fill(rphi_slope_i); m_parent->m_slope_MEp3->Fill(rphi_slope_j); }
00338 if (m_id_i.endcap() == 1 && m_id_i.station() == 2) { m_parent->m_slope_MEp2->Fill(rphi_slope_i); m_parent->m_slope_MEp2->Fill(rphi_slope_j); }
00339 if (m_id_i.endcap() == 1 && m_id_i.station() == 1) { m_parent->m_slope_MEp1->Fill(rphi_slope_i); m_parent->m_slope_MEp1->Fill(rphi_slope_j); }
00340 if (m_id_i.endcap() == 2 && m_id_i.station() == 1) { m_parent->m_slope_MEm1->Fill(rphi_slope_i); m_parent->m_slope_MEm1->Fill(rphi_slope_j); }
00341 if (m_id_i.endcap() == 2 && m_id_i.station() == 2) { m_parent->m_slope_MEm2->Fill(rphi_slope_i); m_parent->m_slope_MEm2->Fill(rphi_slope_j); }
00342 if (m_id_i.endcap() == 2 && m_id_i.station() == 3) { m_parent->m_slope_MEm3->Fill(rphi_slope_i); m_parent->m_slope_MEm3->Fill(rphi_slope_j); }
00343 if (m_id_i.endcap() == 2 && m_id_i.station() == 4) { m_parent->m_slope_MEm4->Fill(rphi_slope_i); m_parent->m_slope_MEm4->Fill(rphi_slope_j); }
00344 }
00345
00346 m_slopeResiduals->Fill(slopeResid);
00347 m_offsetResiduals->Fill(offsetResid);
00348 m_radial->Fill(radial_intercept);
00349
00350 m_parent->m_slopeResiduals->Fill(slopeResid);
00351 m_parent->m_slopeResiduals_weighted->Fill(slopeResid, 1./slopeResidError2);
00352 m_parent->m_slopeResiduals_normalized->Fill(slopeResid/sqrt(slopeResidError2));
00353
00354 m_parent->m_offsetResiduals->Fill(offsetResid);
00355 m_parent->m_offsetResiduals_weighted->Fill(offsetResid, 1./offsetResidError2);
00356 m_parent->m_offsetResiduals_normalized->Fill(offsetResid/sqrt(offsetResidError2));
00357
00358 double ringbin = 0;
00359 if (m_id_i.endcap() == 2 && m_id_i.station() == 4 && m_id_i.ring() == 2) ringbin = 1.5;
00360 else if (m_id_i.endcap() == 2 && m_id_i.station() == 4 && m_id_i.ring() == 1) ringbin = 2.5;
00361 else if (m_id_i.endcap() == 2 && m_id_i.station() == 3 && m_id_i.ring() == 2) ringbin = 3.5;
00362 else if (m_id_i.endcap() == 2 && m_id_i.station() == 3 && m_id_i.ring() == 1) ringbin = 4.5;
00363 else if (m_id_i.endcap() == 2 && m_id_i.station() == 2 && m_id_i.ring() == 2) ringbin = 5.5;
00364 else if (m_id_i.endcap() == 2 && m_id_i.station() == 2 && m_id_i.ring() == 1) ringbin = 6.5;
00365 else if (m_id_i.endcap() == 2 && m_id_i.station() == 1 && m_id_i.ring() == 3) ringbin = 7.5;
00366 else if (m_id_i.endcap() == 2 && m_id_i.station() == 1 && m_id_i.ring() == 2) ringbin = 8.5;
00367 else if (m_id_i.endcap() == 2 && m_id_i.station() == 1 && m_id_i.ring() == 1) ringbin = 9.5;
00368 else if (m_id_i.endcap() == 2 && m_id_i.station() == 1 && m_id_i.ring() == 4) ringbin = 10.5;
00369 else if (m_id_i.endcap() == 1 && m_id_i.station() == 1 && m_id_i.ring() == 4) ringbin = 11.5;
00370 else if (m_id_i.endcap() == 1 && m_id_i.station() == 1 && m_id_i.ring() == 1) ringbin = 12.5;
00371 else if (m_id_i.endcap() == 1 && m_id_i.station() == 1 && m_id_i.ring() == 2) ringbin = 13.5;
00372 else if (m_id_i.endcap() == 1 && m_id_i.station() == 1 && m_id_i.ring() == 3) ringbin = 14.5;
00373 else if (m_id_i.endcap() == 1 && m_id_i.station() == 2 && m_id_i.ring() == 1) ringbin = 15.5;
00374 else if (m_id_i.endcap() == 1 && m_id_i.station() == 2 && m_id_i.ring() == 2) ringbin = 16.5;
00375 else if (m_id_i.endcap() == 1 && m_id_i.station() == 3 && m_id_i.ring() == 1) ringbin = 17.5;
00376 else if (m_id_i.endcap() == 1 && m_id_i.station() == 3 && m_id_i.ring() == 2) ringbin = 18.5;
00377 else if (m_id_i.endcap() == 1 && m_id_i.station() == 4 && m_id_i.ring() == 1) ringbin = 19.5;
00378 else if (m_id_i.endcap() == 1 && m_id_i.station() == 4 && m_id_i.ring() == 2) ringbin = 20.5;
00379 m_parent->m_occupancy->Fill(m_id_i.chamber() + 0.5, ringbin);
00380 }
00381
00382 return true;
00383 }
00384
00385 bool CSCPairResidualsConstraint::dphidzFromTrack(const std::vector<TrajectoryMeasurement> &measurements, const reco::TransientTrack &track, const TrackTransformer *trackTransformer, double &dphidz) {
00386
00387 std::map<int,int> stations;
00388 int total = 0;
00389 TransientTrackingRecHit::ConstRecHitContainer cscHits;
00390 for (std::vector<TrajectoryMeasurement>::const_iterator measurement = measurements.begin(); measurement != measurements.end(); ++measurement) {
00391 DetId id = measurement->recHit()->geographicalId();
00392 if (id.det() == DetId::Muon && id.subdetId() == MuonSubdetId::CSC) {
00393 CSCDetId cscid(id.rawId());
00394 CSCDetId chamberId(cscid.endcap(), cscid.station(), cscid.ring(), cscid.chamber(), 0);
00395 if (m_parent->m_combineME11 && cscid.station() == 1 && cscid.ring() == 4) chamberId = CSCDetId(cscid.endcap(), 1, 1, cscid.chamber(), 0);
00396
00397 if (chamberId != m_id_i && chamberId != m_id_j) {
00398 int station = (cscid.endcap() == 1 ? 1 : -1) * cscid.station();
00399 if (stations.find(station) == stations.end()) {
00400 stations[station] = 0;
00401 }
00402 stations[station]++;
00403 total++;
00404
00405 cscHits.push_back(measurement->recHit());
00406 }
00407 }
00408 }
00409
00410
00411 int numStations = 0;
00412 for (std::map<int,int>::const_iterator station = stations.begin(); station != stations.end(); ++station) {
00413 if (station->second >= m_parent->m_minHitsPerChamber) {
00414 numStations++;
00415 }
00416 }
00417
00418 if (numStations >= m_parent->m_minStationsInTrackRefits) {
00419
00420 std::vector<Trajectory> trajectories = trackTransformer->transform(track, cscHits);
00421
00422 if (!trajectories.empty()) {
00423 const std::vector<TrajectoryMeasurement> &measurements2 = trajectories.begin()->measurements();
00424
00425
00426 bool found_plus = false;
00427 bool found_minus = false;
00428 TrajectoryStateOnSurface tsos_plus, tsos_minus;
00429 for (std::vector<TrajectoryMeasurement>::const_iterator measurement = measurements2.begin(); measurement != measurements2.end(); ++measurement) {
00430 double z = measurement->recHit()->globalPosition().z();
00431 if (z > m_Zplane) {
00432 if (!found_plus || fabs(z - m_Zplane) < fabs(tsos_plus.globalPosition().z() - m_Zplane)) {
00433 tsos_plus = TrajectoryStateCombiner().combine(measurement->forwardPredictedState(), measurement->backwardPredictedState());
00434 }
00435 if (tsos_plus.isValid()) found_plus = true;
00436 }
00437 else {
00438 if (!found_minus || fabs(z - m_Zplane) < fabs(tsos_minus.globalPosition().z() - m_Zplane)) {
00439 tsos_minus = TrajectoryStateCombiner().combine(measurement->forwardPredictedState(), measurement->backwardPredictedState());
00440 }
00441 if (tsos_minus.isValid()) found_minus = true;
00442 }
00443 }
00444
00445
00446 TrajectoryStateOnSurface from_plus, from_minus;
00447 if (found_plus) {
00448 from_plus = m_propagator->propagate(tsos_plus, *m_Zsurface);
00449 }
00450 if (found_minus) {
00451 from_minus = m_propagator->propagate(tsos_minus, *m_Zsurface);
00452 }
00453
00454
00455 TrajectoryStateOnSurface merged;
00456 if (found_plus && from_plus.isValid() && found_minus && from_minus.isValid()) {
00457 merged = TrajectoryStateCombiner().combine(from_plus, from_minus);
00458 }
00459 else if (found_plus && from_plus.isValid()) {
00460 merged = from_plus;
00461 }
00462 else if (found_minus && from_minus.isValid()) {
00463 merged = from_minus;
00464 }
00465 else return false;
00466
00467
00468 if (merged.isValid()) {
00469 double angle = merged.globalPosition().phi() + M_PI/2.;
00470 GlobalVector direction = merged.globalDirection();
00471 double dxdz = direction.x() / direction.z();
00472 double dydz = direction.y() / direction.z();
00473 dphidz = (dxdz*cos(angle) + dydz*sin(angle)) / merged.globalPosition().perp();
00474 return true;
00475 }
00476
00477 }
00478 }
00479 return false;
00480 }
00481
00482 void CSCPairResidualsConstraint::write(std::ofstream &output) {
00483 output << std::setprecision(14) << std::fixed;
00484 output << "CSCPairResidualsConstraint " << m_identifier << " " << i() << " " << j() << " "
00485 << m_sumN << " " << m_sum1 << " " << m_sumx << " " << m_sumy << " " << m_sumxx << " " << m_sumyy << " " << m_sumxy << " EOLN" << std::endl;
00486 }
00487
00488 void CSCPairResidualsConstraint::read(std::vector<std::ifstream*> &input, std::vector<std::string> &filenames) {
00489 m_sumN = 0;
00490 m_sum1 = 0.;
00491 m_sumx = 0.;
00492 m_sumy = 0.;
00493 m_sumxx = 0.;
00494 m_sumyy = 0.;
00495 m_sumxy = 0.;
00496
00497 std::vector<std::ifstream*>::const_iterator inputiter = input.begin();
00498 std::vector<std::string>::const_iterator filename = filenames.begin();
00499 for (; inputiter != input.end(); ++inputiter, ++filename) {
00500 int linenumber = 0;
00501 bool touched = false;
00502 while (!(*inputiter)->eof()) {
00503 linenumber++;
00504 std::string name, eoln;
00505 unsigned int identifier;
00506 int i, j;
00507 int sumN;
00508 double sum1, sumx, sumy, sumxx, sumyy, sumxy;
00509
00510 (**inputiter) >> name >> identifier >> i >> j >> sumN >> sum1 >> sumx >> sumy >> sumxx >> sumyy >> sumxy >> eoln;
00511
00512 if (!(*inputiter)->eof() && (name != "CSCPairResidualsConstraint" || eoln != "EOLN")) throw cms::Exception("CorruptTempFile") << "Temporary file " << *filename << " is incorrectly formatted on line " << linenumber << std::endl;
00513
00514 if (identifier == m_identifier) {
00515 if (i != m_i || j != m_j) throw cms::Exception("CorruptTempFile") << "Wrong (i,j) for CSCPairResidualsConstraint " << m_identifier << " (" << m_i << "," << m_j << ") in file " << *filename << " on line " << linenumber << std::endl;
00516 touched = true;
00517
00518 m_sumN += sumN;
00519 m_sum1 += sum1;
00520 m_sumx += sumx;
00521 m_sumy += sumy;
00522 m_sumxx += sumxx;
00523 m_sumyy += sumyy;
00524 m_sumxy += sumxy;
00525 }
00526 }
00527
00528 (*inputiter)->clear();
00529 (*inputiter)->seekg(0, std::ios::beg);
00530
00531 if (!touched) throw cms::Exception("CorruptTempFile") << "CSCPairResidualsConstraint " << m_identifier << " is missing from file " << *filename << std::endl;
00532 }
00533 }
00534
00535 void CSCPairResidualsConstraint::calculatePhi(const TransientTrackingRecHit *hit, double &phi, double &phierr2, bool doRphi, bool globalPhi) {
00536 LocalPoint pos = hit->localPosition();
00537 DetId id = hit->geographicalId();
00538 CSCDetId cscid = CSCDetId(id.rawId());
00539
00540 double r = 0.;
00541 if (globalPhi) {
00542 phi = hit->globalPosition().phi();
00543 r = hit->globalPosition().perp();
00544
00545
00546
00547
00548
00549
00550
00551 }
00552 else {
00553
00554 const double R_ME11 = 181.5;
00555 const double R_ME12 = 369.7;
00556 const double R_ME21 = 242.7;
00557 const double R_ME31 = 252.7;
00558 const double R_ME41 = 262.65;
00559 const double R_MEx2 = 526.5;
00560
00561 double R = 0.;
00562 if (cscid.station() == 1 && (cscid.ring() == 1 || cscid.ring() == 4)) R = R_ME11;
00563 else if (cscid.station() == 1 && cscid.ring() == 2) R = R_ME12;
00564 else if (cscid.station() == 2 && cscid.ring() == 1) R = R_ME21;
00565 else if (cscid.station() == 3 && cscid.ring() == 1) R = R_ME31;
00566 else if (cscid.station() == 4 && cscid.ring() == 1) R = R_ME41;
00567 else if (cscid.station() > 1 && cscid.ring() == 2) R = R_MEx2;
00568 else assert(false);
00569 r = (pos.y() + R);
00570
00571 phi = atan2(pos.x(), r);
00572
00573 if (cscid.endcap() == 1 && cscid.station() >= 3) phi *= -1;
00574 else if (cscid.endcap() == 2 && cscid.station() <= 2) phi *= -1;
00575 }
00576
00577 int strip = m_cscGeometry->layer(id)->geometry()->nearestStrip(pos);
00578 double angle = m_cscGeometry->layer(id)->geometry()->stripAngle(strip) - M_PI/2.;
00579 double sinAngle = sin(angle);
00580 double cosAngle = cos(angle);
00581 double xx = hit->localPositionError().xx();
00582 double xy = hit->localPositionError().xy();
00583 double yy = hit->localPositionError().yy();
00584 phierr2 = (xx*cosAngle*cosAngle + 2.*xy*sinAngle*cosAngle + yy*sinAngle*sinAngle) / (r*r);
00585
00586 if (doRphi) {
00587 phi *= r;
00588 phierr2 *= r*r;
00589 }
00590 }
00591
00592 bool CSCPairResidualsConstraint::isFiducial(std::vector<const TransientTrackingRecHit*> &hits, bool is_i) {
00593
00594 const double cut_ME11 = 0.086;
00595 const double cut_ME12 = 0.090;
00596 const double cut_MEx1 = 0.180;
00597 const double cut_MEx2 = 0.090;
00598
00599 double sum1 = 0.;
00600 double sumx = 0.;
00601 double sumy = 0.;
00602 double sumxx = 0.;
00603 double sumxy = 0.;
00604 for (std::vector<const TransientTrackingRecHit*>::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
00605 double phi, phierr2;
00606 calculatePhi(*hit, phi, phierr2);
00607 double z = (is_i ? m_cscGeometry->idToDet(m_id_i)->surface() : m_cscGeometry->idToDet(m_id_j)->surface()).toLocal((*hit)->globalPosition()).z();
00608
00609 if (m_parent->m_makeHistograms) {
00610 if (m_id_i.station() == 1 && (m_id_i.ring() == 1 || m_id_i.ring() == 4)) {
00611 m_parent->m_fiducial_ME11->Fill(fabs(phi), sqrt(phierr2));
00612 }
00613 else if (m_id_i.station() == 1 && m_id_i.ring() == 2) {
00614 m_parent->m_fiducial_ME12->Fill(fabs(phi), sqrt(phierr2));
00615 }
00616 else if (m_id_i.station() > 1 && m_id_i.ring() == 1) {
00617 m_parent->m_fiducial_MEx1->Fill(fabs(phi), sqrt(phierr2));
00618 }
00619 else if (m_id_i.station() > 1 && m_id_i.ring() == 2) {
00620 m_parent->m_fiducial_MEx2->Fill(fabs(phi), sqrt(phierr2));
00621 }
00622 }
00623
00624 double weight = 1.;
00625 if (m_parent->m_useHitWeights) weight = 1./phierr2;
00626 sum1 += weight;
00627 sumx += weight * z;
00628 sumy += weight * phi;
00629 sumxx += weight * z*z;
00630 sumxy += weight * z*phi;
00631 }
00632 double delta = (sum1*sumxx) - (sumx*sumx);
00633 if (delta == 0.) return false;
00634 double intercept = ((sumxx*sumy) - (sumx*sumxy))/delta;
00635 double slope = ((sum1*sumxy) - (sumx*sumy))/delta;
00636
00637 double phi1 = intercept + slope*(is_i ? m_iZ1 : m_jZ1);
00638 double phi6 = intercept + slope*(is_i ? m_iZ6 : m_jZ6);
00639
00640 if (m_id_i.station() == 1 && (m_id_i.ring() == 1 || m_id_i.ring() == 4)) {
00641 return (fabs(phi1) < cut_ME11 && fabs(phi6) < cut_ME11);
00642 }
00643 else if (m_id_i.station() == 1 && m_id_i.ring() == 2) {
00644 return (fabs(phi1) < cut_ME12 && fabs(phi6) < cut_ME12);
00645 }
00646 else if (m_id_i.station() > 1 && m_id_i.ring() == 1) {
00647 return (fabs(phi1) < cut_MEx1 && fabs(phi6) < cut_MEx1);
00648 }
00649 else if (m_id_i.station() > 1 && m_id_i.ring() == 2) {
00650 return (fabs(phi1) < cut_MEx2 && fabs(phi6) < cut_MEx2);
00651 }
00652 else assert(false);
00653 }