00001 #include "RecoTracker/SiTrackerMRHTools/interface/SiTrackerMultiRecHitUpdator.h"
00002 #include "RecoTracker/TransientTrackingRecHit/interface/TSiTrackerMultiRecHit.h"
00003 #include "RecoTracker/SiTrackerMRHTools/interface/GenericProjectedRecHit2D.h"
00004
00005 #include "DataFormats/TrackerRecHit2D/interface/SiTrackerMultiRecHit.h"
00006 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00007 #include "TrackingTools/TransientTrackingRecHit/interface/TrackingRecHitProjector.h"
00008 #include "TrackingTools/TransientTrackingRecHit/interface/InvalidTransientRecHit.h"
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010
00011
00012 SiTrackerMultiRecHitUpdator::SiTrackerMultiRecHitUpdator(const TransientTrackingRecHitBuilder* builder,
00013 const TrackingRecHitPropagator* hitpropagator,
00014 const float Chi2Cut,
00015 const std::vector<double>& anAnnealingProgram):
00016 theBuilder(builder),
00017 theHitPropagator(hitpropagator),
00018 theChi2Cut(Chi2Cut),
00019 theAnnealingProgram(anAnnealingProgram){}
00020
00021
00022
00023
00024 TransientTrackingRecHit::RecHitPointer SiTrackerMultiRecHitUpdator::buildMultiRecHit(const std::vector<const TrackingRecHit*>& rhv,
00025 TrajectoryStateOnSurface tsos,
00026 float annealing) const{
00027 TransientTrackingRecHit::ConstRecHitContainer tcomponents;
00028 for (std::vector<const TrackingRecHit*>::const_iterator iter = rhv.begin(); iter != rhv.end(); iter++){
00029 TransientTrackingRecHit::RecHitPointer transient = theBuilder->build(*iter);
00030 if (transient->isValid()) tcomponents.push_back(transient);
00031 }
00032
00033 return update(tcomponents, tsos, annealing);
00034
00035 }
00036
00037 TransientTrackingRecHit::RecHitPointer SiTrackerMultiRecHitUpdator::update( TransientTrackingRecHit::ConstRecHitPointer original,
00038 TrajectoryStateOnSurface tsos,
00039 double annealing) const{
00040 LogTrace("SiTrackerMultiRecHitUpdator") << "Calling SiTrackerMultiRecHitUpdator::update with AnnealingFactor: " << annealing;
00041 if (original->isValid())
00042 LogTrace("SiTrackerMultiRecHitUpdator") << "Original Hit position " << original->localPosition() << " original error "
00043 << original->parametersError();
00044 else LogTrace("SiTrackerMultiRecHitUpdator") << "Invalid hit";
00045
00046 if(!tsos.isValid()) {
00047
00048 throw cms::Exception("SiTrackerMultiRecHitUpdator") << "!!! MultiRecHitUpdator::update(..): tsos NOT valid!!! ";
00049 }
00050
00051
00052 if (original->transientHits().empty()) return original->clone(tsos);
00053
00054 TransientTrackingRecHit::ConstRecHitContainer tcomponents = original->transientHits();
00055 return update(tcomponents, tsos, annealing);
00056 }
00057
00058 TransientTrackingRecHit::RecHitPointer SiTrackerMultiRecHitUpdator::update( TransientTrackingRecHit::ConstRecHitContainer& tcomponents,
00059 TrajectoryStateOnSurface tsos,
00060 double annealing) const{
00061
00062 if (tcomponents.empty()){
00063 LogTrace("SiTrackerMultiRecHitUpdator") << "Empty components vector passed to SiTrackerMultiRecHitUpdator::update, returning an InvalidTransientRecHit ";
00064 return InvalidTransientRecHit::build(0);
00065 }
00066
00067 if(!tsos.isValid()) {
00068 LogTrace("SiTrackerMultiRecHitUpdator")<<"SiTrackerMultiRecHitUpdator::update: tsos NOT valid!!!, returning an InvalidTransientRecHit";
00069 return InvalidTransientRecHit::build(0);
00070 }
00071
00072 std::vector<TransientTrackingRecHit::RecHitPointer> updatedcomponents;
00073 const GeomDet* geomdet = 0;
00074 for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator iter = tcomponents.begin(); iter != tcomponents.end(); iter++){
00075 if (iter == tcomponents.begin()) {
00076 if (&((*iter)->det()->surface())!=&(tsos.surface())){
00077 throw cms::Exception("SiTrackerMultiRecHitUpdator") << "the Trajectory state and the first rechit passed to the SiTrackerMultiRecHitUpdator lay on different surfaces!: state lays on surface " << tsos.surface().position() << " hit with detid " << (*iter)->det()->geographicalId().rawId() << " lays on surface " << (*iter)->det()->surface().position();
00078 }
00079 geomdet = (*iter)->det();
00080 LogTrace("SiTrackerMultiRecHitUpdator") << "Current reference surface located at " << geomdet->surface().position();
00081
00082 }
00083 if (&((*iter)->det()->surface())!=&(tsos.surface())){
00084 TransientTrackingRecHit::RecHitPointer cloned = theHitPropagator->project<GenericProjectedRecHit2D>(*iter, *geomdet, tsos);
00085
00086
00087 if (cloned->isValid()) updatedcomponents.push_back(cloned);
00088 } else {
00089 TransientTrackingRecHit::RecHitPointer cloned = (*iter)->clone(tsos);
00090 if (cloned->isValid()) updatedcomponents.push_back(cloned);
00091 }
00092 }
00093
00094 int ierr;
00095 std::vector<std::pair<const TrackingRecHit*, float> > mymap;
00096 std::vector<std::pair<const TrackingRecHit*, float> > normmap;
00097
00098 double a_sum=0, c_sum=0;
00099
00100 AlgebraicVector2 tsospos;
00101 tsospos[0]=tsos.localPosition().x();
00102 tsospos[1]=tsos.localPosition().y();
00103 LogTrace("SiTrackerMultiRecHitUpdator")<< "TSOS position " << tsos.localPosition();
00104 for(std::vector<TransientTrackingRecHit::RecHitPointer>::iterator ihit = updatedcomponents.begin(); ihit != updatedcomponents.end(); ihit++) {
00105 AlgebraicVector2 r(asSVector<2>((*ihit)->parameters()) - tsospos);
00106 AlgebraicSymMatrix22 V(asSMatrix<2>((*ihit)->parametersError()));
00107 V *= annealing;
00108
00109 AlgebraicSymMatrix22 W(V.Inverse(ierr));
00110 double det;
00111 bool ierr2=!(V.Det2(det));
00112
00113 if(ierr != 0|| ierr2) {
00114 LogTrace("SiTrackerMultiRecHitUpdator")<<"MultiRecHitUpdator::update: W not valid!"<<std::endl;
00115 LogTrace("SiTrackerMultiRecHitUpdator")<<"V: "<<V<<" AnnealingFactor: "<<annealing<<std::endl;
00116 }
00117 double Chi2 = ROOT::Math::Similarity(r,W);
00118 double a_i = exp(-0.5*Chi2)/(2.*M_PI*sqrt(det));
00119 mymap.push_back(std::pair<const TrackingRecHit*, float>((*ihit)->hit(), a_i));
00120 double c_i = exp(-0.5*theChi2Cut/annealing)/(2.*M_PI*sqrt(det));
00121 a_sum += a_i;
00122 c_sum += c_i;
00123 }
00124 double total_sum = a_sum + c_sum;
00125
00126 unsigned int counter = 0;
00127 TransientTrackingRecHit::ConstRecHitContainer finalcomponents;
00128 for(std::vector<TransientTrackingRecHit::RecHitPointer>::iterator ihit = updatedcomponents.begin(); ihit != updatedcomponents.end(); ihit++) {
00129
00130 double p = ((mymap[counter].second)/total_sum > 1.e-6 ? (mymap[counter].second)/total_sum : 1.e-6);
00131
00132 normmap.push_back(std::pair<const TrackingRecHit*, float>(mymap[counter].first, p));
00133
00134 (*ihit)->setWeight(p);
00135 (*ihit)->setAnnealingFactor(annealing);
00136 finalcomponents.push_back(*ihit);
00137 LogTrace("SiTrackerMultiRecHitUpdator")<< "Component hit type " << typeid(*mymap[counter].first).name()
00138 << " position " << mymap[counter].first->localPosition()
00139 << " error " << mymap[counter].first->localPositionError()
00140 << " with weight " << p;
00141 counter++;
00142 }
00143
00144 mymap = normmap;
00145
00146
00147 SiTrackerMultiRecHitUpdator::LocalParameters param=calcParameters(finalcomponents);
00148 SiTrackerMultiRecHit updated(param.first, param.second, normmap.front().first->geographicalId(), normmap);
00149 LogTrace("SiTrackerMultiRecHitUpdator") << "Updated Hit position " << updated.localPosition() << " updated error " << updated.parametersError() << std::endl;
00150
00151 return TSiTrackerMultiRecHit::build(geomdet, &updated, finalcomponents, annealing);
00152 }
00153
00154
00155 SiTrackerMultiRecHitUpdator::LocalParameters SiTrackerMultiRecHitUpdator::calcParameters(TransientTrackingRecHit::ConstRecHitContainer& map)const{
00156 AlgebraicSymMatrix22 W_sum;
00157 AlgebraicVector2 m_sum;
00158 int ierr;
00159 for(TransientTrackingRecHit::ConstRecHitContainer::const_iterator ihit = map.begin(); ihit != map.end(); ihit ++) {
00160 AlgebraicVector2 m(asSVector<2>((*ihit)->parameters()));
00161 AlgebraicSymMatrix22 V(asSMatrix<2>((*ihit)->parametersError()));
00162 AlgebraicSymMatrix22 W(V.Inverse(ierr));
00163
00164 if(ierr != 0) {
00165 edm::LogError("SiTrackerMultiRecHitUpdator")<<"MultiRecHit::checkParameters: W not valid!"<<std::endl;
00166 }
00167
00168 else {
00169 W_sum += ((*ihit)->weight()*W);
00170 m_sum += ((*ihit)->weight()*(W*m));
00171 }
00172 }
00173 AlgebraicSymMatrix22 V_sum= W_sum.Inverse(ierr);
00174 AlgebraicVector2 parameters = V_sum*m_sum;
00175 LocalError error=LocalError(V_sum(0,0), V_sum(0,1), V_sum(1,1));
00176 LocalPoint position=LocalPoint(parameters(0), parameters(1));
00177 return std::make_pair(position,error);
00178 }
00179
00180 LocalError SiTrackerMultiRecHitUpdator::calcParametersError(TransientTrackingRecHit::ConstRecHitContainer& map) const {
00181 AlgebraicSymMatrix22 W_sum;
00182 int ierr;
00183 for(TransientTrackingRecHit::ConstRecHitContainer::const_iterator ihit = map.begin(); ihit != map.end(); ihit ++) {
00184 AlgebraicSymMatrix22 V(asSMatrix<2>((*ihit)->parametersError()));
00185 AlgebraicSymMatrix22 W(V.Inverse(ierr));
00186
00187 if(ierr != 0) {
00188 edm::LogError("SiTrackerMultiRecHitUpdator")<<"MultiRecHit::checkParametersError: W not valid!"<<std::endl;
00189 }
00190
00191 else W_sum += ((*ihit)->weight()*W);
00192 }
00193 AlgebraicSymMatrix22 parametersError = W_sum.Inverse(ierr);
00194 return LocalError(parametersError(0,0), parametersError(0,1), parametersError(1,1));
00195 }
00196
00197 LocalPoint SiTrackerMultiRecHitUpdator::calcParameters(TransientTrackingRecHit::ConstRecHitContainer& map, const LocalError& er) const {
00198 AlgebraicVector2 m_sum;
00199 int ierr;
00200 for( TransientTrackingRecHit::ConstRecHitContainer::const_iterator ihit = map.begin(); ihit != map.end(); ihit ++) {
00201 AlgebraicVector2 m(asSVector<2>((*ihit)->parameters()));
00202 AlgebraicSymMatrix22 V(asSMatrix<2>((*ihit)->parametersError()));
00203 AlgebraicSymMatrix22 W(V.Inverse(ierr));
00204
00205 if(ierr != 0) {
00206 edm::LogError("SiTrackerMultiRecHitUpdator")<<"MultiRecHit::checkParameters: W not valid!"<<std::endl;
00207 }
00208
00209
00210 else m_sum += ((*ihit)->weight()*(W*m));
00211 }
00212 AlgebraicSymMatrix22 V_sum;
00213
00214 V_sum(0,0) = er.xx();
00215 V_sum(0,1) = er.xy();
00216 V_sum(1,1) = er.yy();
00217
00218 AlgebraicVector2 parameters = V_sum*m_sum;
00219 return LocalPoint(parameters(0), parameters(1));
00220 }
00221