CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_2_9_HLT1_bphpatch4/src/RecoVertex/AdaptiveVertexFit/src/AdaptiveVertexFitter.cc

Go to the documentation of this file.
00001 #include "RecoVertex/AdaptiveVertexFit/interface/AdaptiveVertexFitter.h"
00002 #include "DataFormats/GeometryCommonDetAlgo/interface/GlobalError.h"
00003 #include "RecoVertex/VertexTools/interface/AnnealingSchedule.h"
00004 #include "RecoVertex/VertexTools/interface/GeometricAnnealing.h"
00005 #include "RecoVertex/VertexTools/interface/VertexTrackFactory.h"
00006 #include "RecoVertex/VertexPrimitives/interface/VertexException.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 
00009 #include <algorithm>
00010 
00011 using namespace edm;
00012 
00013 // #define STORE_WEIGHTS
00014 #ifdef STORE_WEIGHTS
00015 #include <dataharvester/Writer.h>
00016 #endif
00017 
00018 using namespace std;
00019 
00020 namespace {
00021   struct CompareTwoTracks {
00022     int operator() ( const reco::TransientTrack & a, const reco::TransientTrack & b ) {
00023             return ( a.impactPointState().globalMomentum().perp() >
00024                      b.impactPointState().globalMomentum().perp() ) ;
00025     };
00026   };
00027   // typedef ReferenceCountingPointer<VertexTrack<5> > RefCountedVertexTrack;
00028   typedef AdaptiveVertexFitter::RefCountedVertexTrack RefCountedVertexTrack;
00029 
00030   GlobalError fitError()
00031   {
00032     static GlobalError err;
00033     static bool once=true;
00034     if (once)
00035     {
00036       // that's how we model the lin pt error for the initial seed!
00037       static const float initialError = 10000;
00038       AlgebraicSymMatrix33 ret;
00039       ret(0,0)=initialError;
00040       ret(1,1)=initialError;
00041       ret(2,2)=initialError;
00042       err=GlobalError ( ret );
00043       once=false;
00044     }
00045     return err;
00046   }
00047 
00048   GlobalError linPointError()
00049   {
00050     static GlobalError err;
00051     static bool once=true;
00052     if (once)
00053     {
00054       // that's how we model the error of the linearization point.
00055       // for track weighting!
00056       AlgebraicSymMatrix33 ret;
00057       ret(0,0)=.3; ret(1,1)=.3; ret(2,2)=3.;
00058       // ret(0,0)=1e-7; ret(1,1)=1e-7; ret(2,2)=1e-7;
00059       err=GlobalError ( ret );
00060       once=false;
00061     }
00062     return err;
00063   }
00064 
00065   struct DistanceToRefPoint {
00066     DistanceToRefPoint ( const GlobalPoint & ref ) : theRef ( ref ) {}
00067 
00068     bool operator() ( const RefCountedVertexTrack & v1, const RefCountedVertexTrack & v2 )
00069     {
00070       return ( distance ( v1 ) < distance ( v2 ) );
00071     }
00072 
00073     float distance ( const RefCountedVertexTrack & v1 )
00074     {
00075       return ( v1->linearizedTrack()->track().initialFreeState().position() - theRef ).mag2();
00076     }
00077 
00078     private:
00079       GlobalPoint theRef;
00080   };
00081 
00082   #ifdef STORE_WEIGHTS
00083   map < RefCountedLinearizedTrackState, int > ids;
00084   int iter=0;
00085 
00086   int getId ( const RefCountedLinearizedTrackState & r )
00087   {
00088     static int ctr=1;
00089     if ( ids.count(r) == 0 )
00090     {
00091       ids[r]=ctr++;
00092     }
00093     return ids[r];
00094   }
00095   #endif
00096 }
00097 
00098 AdaptiveVertexFitter::AdaptiveVertexFitter(
00099       const AnnealingSchedule & ann,
00100       const LinearizationPointFinder & linP,
00101       const VertexUpdator<5> & updator,
00102       const VertexTrackCompatibilityEstimator<5> & crit,
00103       const VertexSmoother<5> & smoother,
00104       const AbstractLTSFactory<5> & ltsf ) :
00105     theNr(0),
00106     theLinP(linP.clone()), theUpdator( updator.clone()),
00107     theSmoother ( smoother.clone() ), theAssProbComputer( ann.clone() ),
00108     theComp ( crit.clone() ), theLinTrkFactory ( ltsf.clone() ),
00109     gsfIntermediarySmoothing_(false)
00110 {
00111   setParameters();
00112 }
00113 
00114 void AdaptiveVertexFitter::setWeightThreshold ( float w )
00115 {
00116   theWeightThreshold=w;
00117 }
00118 
00119 AdaptiveVertexFitter::AdaptiveVertexFitter
00120                         (const AdaptiveVertexFitter & o ) :
00121     theMaxShift ( o.theMaxShift ), theMaxLPShift ( o.theMaxLPShift ),
00122     theMaxStep ( o.theMaxStep ), theWeightThreshold ( o.theWeightThreshold ),
00123     theNr ( o.theNr ),
00124     theLinP ( o.theLinP->clone() ), theUpdator ( o.theUpdator->clone() ),
00125     theSmoother ( o.theSmoother->clone() ),
00126     theAssProbComputer ( o.theAssProbComputer->clone() ),
00127     theComp ( o.theComp->clone() ),
00128     theLinTrkFactory ( o.theLinTrkFactory->clone() ),
00129     gsfIntermediarySmoothing_(o.gsfIntermediarySmoothing_)
00130 {}
00131 
00132 AdaptiveVertexFitter::~AdaptiveVertexFitter()
00133 {
00134   delete theLinP;
00135   delete theUpdator;
00136   delete theSmoother;
00137   delete theAssProbComputer;
00138   delete theComp;
00139   delete theLinTrkFactory;
00140 }
00141 
00142 void AdaptiveVertexFitter::setParameters( double maxshift, double maxlpshift, 
00143                                           unsigned maxstep, double weightthreshold )
00144 {
00145   theMaxShift = maxshift;
00146   theMaxLPShift = maxlpshift;
00147   theMaxStep = maxstep;
00148   theWeightThreshold=weightthreshold;
00149 }
00150 
00151 
00152 void AdaptiveVertexFitter::setParameters ( const edm::ParameterSet & s )
00153 {
00154     setParameters ( s.getParameter<double>("maxshift"),
00155                     s.getParameter<double>("maxlpshift"),
00156                     s.getParameter<int>("maxstep"),
00157                     s.getParameter<double>("weightthreshold") );
00158 }
00159 
00160 CachingVertex<5>
00161 AdaptiveVertexFitter::vertex(const vector<reco::TransientTrack> & unstracks) const
00162 {
00163   if ( unstracks.size() < 2 )
00164   {
00165     LogError("RecoVertex|AdaptiveVertexFitter")
00166       << "Supplied fewer than two tracks. Vertex is invalid.";
00167     return CachingVertex<5>(); // return invalid vertex
00168   };
00169   vector < reco::TransientTrack > tracks = unstracks;
00170   sort ( tracks.begin(), tracks.end(), CompareTwoTracks() );
00171   // Linearization Point
00172   GlobalPoint linP = theLinP->getLinearizationPoint(tracks);
00173   // Initial vertex seed, with a very large error matrix
00174   VertexState lseed (linP, linPointError() );
00175   vector<RefCountedVertexTrack> vtContainer = linearizeTracks(tracks, lseed);
00176 
00177   VertexState seed (linP, fitError() );
00178   return fit(vtContainer, seed, false);
00179 }
00180 
00181 CachingVertex<5>
00182 AdaptiveVertexFitter::vertex(const vector<RefCountedVertexTrack> & tracks) const
00183 {
00184   if ( tracks.size() < 2 )
00185   {
00186     LogError("RecoVertex|AdaptiveVertexFitter")
00187       << "Supplied fewer than two tracks. Vertex is invalid.";
00188     return CachingVertex<5>(); // return invalid vertex
00189   };
00190   // Initial vertex seed, with a very small weight matrix
00191   GlobalPoint linP = tracks[0]->linearizedTrack()->linearizationPoint();
00192   VertexState seed (linP, fitError() );
00193   return fit(tracks, seed, false);
00194 }
00195 
00196 CachingVertex<5>
00197 AdaptiveVertexFitter::vertex(const vector<RefCountedVertexTrack> & tracks, const reco::BeamSpot & spot ) const
00198 {
00199   if ( tracks.size() < 1 )
00200   {
00201     LogError("RecoVertex|AdaptiveVertexFitter")
00202       << "Supplied no tracks. Vertex is invalid.";
00203     return CachingVertex<5>(); // return invalid vertex
00204   };
00205   VertexState beamSpotState(spot);
00206   return fit(tracks, beamSpotState, true );
00207 }
00208 
00209 
00210 
00214 CachingVertex<5>
00215 AdaptiveVertexFitter::vertex(const vector<reco::TransientTrack> & tracks,
00216                   const GlobalPoint& linPoint) const
00217 {
00218   if ( tracks.size() < 2 )
00219   {
00220     LogError("RecoVertex|AdaptiveVertexFitter")
00221       << "Supplied fewer than two tracks. Vertex is invalid.";
00222     return CachingVertex<5>(); // return invalid vertex
00223   };
00224   // Initial vertex seed, with a very large error matrix
00225   VertexState seed (linPoint, linPointError() );
00226   vector<RefCountedVertexTrack> vtContainer = linearizeTracks(tracks, seed);
00227   VertexState fitseed (linPoint, fitError() );
00228   return fit(vtContainer, fitseed, false);
00229 }
00230 
00231 
00236 CachingVertex<5> 
00237 AdaptiveVertexFitter::vertex(const vector<reco::TransientTrack> & unstracks,
00238                                const reco::BeamSpot& beamSpot) const
00239 {
00240   if ( unstracks.size() < 1 )
00241   {
00242     LogError("RecoVertex|AdaptiveVertexFitter")
00243       << "Supplied no tracks. Vertex is invalid.";
00244     return CachingVertex<5>(); // return invalid vertex
00245   };
00246 
00247   VertexState beamSpotState(beamSpot);
00248   vector<RefCountedVertexTrack> vtContainer;
00249 
00250   vector < reco::TransientTrack > tracks = unstracks;
00251   sort ( tracks.begin(), tracks.end(), CompareTwoTracks() );
00252 
00253   if (tracks.size() > 1) {
00254     // Linearization Point search if there are more than 1 track
00255     GlobalPoint linP = theLinP->getLinearizationPoint(tracks);
00256     VertexState lpState(linP, linPointError() );
00257     vtContainer = linearizeTracks(tracks, lpState);
00258   } else {
00259     // otherwise take the beamspot position.
00260     vtContainer = linearizeTracks(tracks, beamSpotState);
00261   }
00262 
00263   return fit(vtContainer, beamSpotState, true);
00264 }
00265 
00266 
00272 CachingVertex<5> AdaptiveVertexFitter::vertex(const vector<reco::TransientTrack> & tracks,
00273                   const GlobalPoint& priorPos,
00274                   const GlobalError& priorError) const
00275 
00276 {
00277   if ( tracks.size() < 1 )
00278   {
00279     LogError("RecoVertex|AdaptiveVertexFitter")
00280       << "Supplied no tracks. Vertex is invalid.";
00281     return CachingVertex<5>(); // return invalid vertex
00282   };
00283   VertexState seed (priorPos, priorError);
00284   vector<RefCountedVertexTrack> vtContainer = linearizeTracks(tracks, seed);
00285   return fit( vtContainer, seed, true );
00286 }
00287 
00288 
00293 CachingVertex<5> AdaptiveVertexFitter::vertex(
00294                 const vector<RefCountedVertexTrack> & tracks,
00295                   const GlobalPoint& priorPos,
00296                   const GlobalError& priorError) const
00297 {
00298   if ( tracks.size() < 1 )
00299   {
00300     LogError("RecoVertex|AdaptiveVertexFitter")
00301       << "Supplied no tracks. Vertex is invalid.";
00302     return CachingVertex<5>(); // return invalid vertex
00303   };
00304   VertexState seed (priorPos, priorError);
00305   return fit(tracks, seed, true);
00306 }
00307 
00308 
00316 vector<AdaptiveVertexFitter::RefCountedVertexTrack>
00317 AdaptiveVertexFitter::linearizeTracks(const vector<reco::TransientTrack> & tracks,
00318                                       const VertexState & seed ) const
00319 {
00320   const GlobalPoint & linP ( seed.position() );
00321   vector<RefCountedLinearizedTrackState> lTracks;
00322   for(vector<reco::TransientTrack>::const_iterator i = tracks.begin();
00323       i != tracks.end(); ++i )
00324   {
00325     try {
00326       RefCountedLinearizedTrackState lTrData
00327         = theLinTrkFactory->linearizedTrackState(linP, *i);
00328       lTracks.push_back(lTrData);
00329     } catch ( exception & e ) {
00330       LogWarning("RecoVertex/AdaptiveVertexFitter") 
00331         << "Exception " << e.what() << " in ::linearizeTracks."
00332         << "Your future vertex has just lost a track.";
00333     };
00334   }
00335   return weightTracks(lTracks, seed );
00336 }
00337 
00343 vector<AdaptiveVertexFitter::RefCountedVertexTrack>
00344 AdaptiveVertexFitter::reLinearizeTracks(
00345                                 const vector<RefCountedVertexTrack> & tracks,
00346                                 const CachingVertex<5> & vertex ) const
00347 {
00348   VertexState seed = vertex.vertexState();
00349   GlobalPoint linP = seed.position();
00350   vector<RefCountedLinearizedTrackState> lTracks;
00351   for(vector<RefCountedVertexTrack>::const_iterator i = tracks.begin();
00352     i != tracks.end(); i++)
00353   {
00354     try {
00355       RefCountedLinearizedTrackState lTrData
00356         = theLinTrkFactory->linearizedTrackState( linP, (**i).linearizedTrack()->track() );
00357       /*
00358       RefCountedLinearizedTrackState lTrData =
00359               (**i).linearizedTrack()->stateWithNewLinearizationPoint(linP);
00360               */
00361       lTracks.push_back(lTrData);
00362     } catch ( exception & e ) {
00363       LogWarning("RecoVertex/AdaptiveVertexFitter") 
00364         << "Exception " << e.what() << " in ::relinearizeTracks. "
00365         << "Will not relinearize this track.";
00366       lTracks.push_back ( (**i).linearizedTrack() );
00367     };
00368   };
00369   return reWeightTracks(lTracks, vertex );
00370 }
00371 
00372 AdaptiveVertexFitter * AdaptiveVertexFitter::clone() const
00373 {
00374   return new AdaptiveVertexFitter( * this );
00375 }
00376 
00377 double AdaptiveVertexFitter::getWeight ( float chi2 ) const
00378 {
00379   double weight = theAssProbComputer->weight(chi2);
00380 
00381   if ( weight > 1.0 )
00382   {
00383     LogWarning("RecoVertex/AdaptiveVertexFitter") << "Weight " << weight << " > 1.0!";
00384     weight=1.0;
00385   };
00386 
00387   if ( weight < 1e-20 )
00388   {
00389     // LogWarning("RecoVertex/AdaptiveVertexFitter") << "Weight " << weight << " < 0.0!";
00390     weight=1e-20;
00391   };
00392   return weight;
00393 }
00394 
00395 vector<AdaptiveVertexFitter::RefCountedVertexTrack>
00396 AdaptiveVertexFitter::reWeightTracks(
00397                     const vector<RefCountedLinearizedTrackState> & lTracks,
00398                     const CachingVertex<5> & vertex ) const
00399 {
00400   VertexState seed = vertex.vertexState();
00401   theNr++;
00402   // GlobalPoint pos = seed.position();
00403 
00404   vector<RefCountedVertexTrack> finalTracks;
00405   VertexTrackFactory<5> vTrackFactory;
00406   #ifdef STORE_WEIGHTS
00407   iter++;
00408   #endif
00409   for(vector<RefCountedLinearizedTrackState>::const_iterator i
00410         = lTracks.begin(); i != lTracks.end(); i++)
00411   {
00412     double weight=0.;
00413     pair<bool, double> chi2Res =  theComp->estimate ( vertex, *i );
00414     if (!chi2Res.first) {
00415       cout << "[AdaptiveVertexFitter] aie... vertex candidate is at  " << vertex.position() << endl;
00416       LogWarning("AdaptiveVertexFitter" ) << "When reweighting, chi2<0. Will add this track with w=0.";
00417       // edm::LogWarning("AdaptiveVertexFitter" ) << "pt=" << (**i).track().pt();
00418     }else {
00419       weight = getWeight ( chi2Res.second );
00420     }
00421     
00422     RefCountedVertexTrack vTrData
00423        = vTrackFactory.vertexTrack(*i, seed, weight );
00424 
00425     #ifdef STORE_WEIGHTS
00426     map < string, dataharvester::MultiType > m;
00427     m["chi2"]=chi2;
00428     m["w"]=theAssProbComputer->weight(chi2);
00429     m["T"]=theAssProbComputer->currentTemp();
00430     m["n"]=iter;
00431     m["pos"]="reweight";
00432     m["id"]=getId ( *i );
00433     dataharvester::Writer::file("w.txt").save ( m );
00434     #endif
00435 
00436     finalTracks.push_back(vTrData);
00437   }
00438   sort ( finalTracks.begin(), finalTracks.end(), 
00439          DistanceToRefPoint ( vertex.position() ) );
00440   return finalTracks;
00441 }
00442 
00443 vector<AdaptiveVertexFitter::RefCountedVertexTrack>
00444 AdaptiveVertexFitter::weightTracks(
00445                     const vector<RefCountedLinearizedTrackState> & lTracks,
00446                     const VertexState & seed ) const
00447 {
00448   theNr++;
00449   CachingVertex<5> seedvtx ( seed, vector<RefCountedVertexTrack> (), 0. );
00452   theAssProbComputer->resetAnnealing();
00453 
00454   vector<RefCountedVertexTrack> finalTracks;
00455   VertexTrackFactory<5> vTrackFactory;
00456   #ifdef STORE_WEIGHTS
00457   iter++;
00458   #endif
00459   for(vector<RefCountedLinearizedTrackState>::const_iterator i
00460         = lTracks.begin(); i != lTracks.end(); i++)
00461   {
00462 
00463     double weight = 0.;
00464     pair<bool, double> chi2Res = theComp->estimate ( seedvtx, *i );
00465     if (!chi2Res.first) {
00466       cout << "[AdaptiveVertexFitter] Aiee! " << endl;
00467       LogWarning ("AdaptiveVertexFitter" ) << "When weighting a track, chi2 calculation failed;"
00468                                            << " will add with w=0.";
00469     } else {
00470       weight = getWeight ( chi2Res.second );
00471     }
00472     RefCountedVertexTrack vTrData
00473        = vTrackFactory.vertexTrack(*i, seed, weight );
00474     #ifdef STORE_WEIGHTS
00475     map < string, dataharvester::MultiType > m;
00476     m["chi2"]=chi2;
00477     m["w"]=theAssProbComputer->weight(chi2);
00478     m["T"]=theAssProbComputer->currentTemp();
00479     m["n"]=iter;
00480     m["id"]=getId ( *i );
00481     m["pos"]="weight";
00482     dataharvester::Writer::file("w.txt").save ( m );
00483     #endif
00484     finalTracks.push_back(vTrData);
00485   }
00486   return finalTracks;
00487 }
00488 
00494 vector<AdaptiveVertexFitter::RefCountedVertexTrack>
00495 AdaptiveVertexFitter::reWeightTracks(
00496                             const vector<RefCountedVertexTrack> & tracks,
00497                             const CachingVertex<5> & seed) const
00498 {
00499   vector<RefCountedLinearizedTrackState> lTracks;
00500   for(vector<RefCountedVertexTrack>::const_iterator i = tracks.begin();
00501     i != tracks.end(); i++)
00502   {
00503     lTracks.push_back((**i).linearizedTrack());
00504   }
00505 
00506   return reWeightTracks(lTracks, seed);
00507 }
00508 
00509 
00510 /*
00511  * The method where the vertex fit is actually done!
00512  */
00513 
00514 CachingVertex<5>
00515 AdaptiveVertexFitter::fit( const vector<RefCountedVertexTrack> & tracks,
00516                           const VertexState & priorSeed,
00517                           bool withPrior) const
00518 {
00519   theAssProbComputer->resetAnnealing();
00520 
00521   vector<RefCountedVertexTrack> initialTracks;
00522   GlobalPoint priorVertexPosition = priorSeed.position();
00523   GlobalError priorVertexError = priorSeed.error();
00524 
00525   CachingVertex<5> returnVertex( priorVertexPosition,priorVertexError,
00526                               initialTracks,0);
00527   if (withPrior)
00528   {
00529     returnVertex = CachingVertex<5>(priorVertexPosition,priorVertexError,
00530                     priorVertexPosition,priorVertexError,initialTracks,0);
00531   }
00532 
00533   // vector<RefCountedVertexTrack> globalVTracks = tracks;
00534   // sort the tracks, according to distance to seed!
00535   vector<RefCountedVertexTrack> globalVTracks ( tracks.size() );
00536 
00537   partial_sort_copy ( tracks.begin(), tracks.end(), 
00538       globalVTracks.begin(), globalVTracks.end(), DistanceToRefPoint ( priorSeed.position() ) );
00539 
00540   // main loop through all the VTracks
00541   int lpStep = 0; int step = 0;
00542 
00543   CachingVertex<5> initialVertex = returnVertex;
00544 
00545   GlobalPoint newPosition = priorVertexPosition;
00546   GlobalPoint previousPosition = newPosition;
00547 
00548   int ns_trks=0; // number of significant tracks.
00549   // If we have only two significant tracks, we return an invalid vertex
00550 
00551   do {
00552     ns_trks=0;
00553     CachingVertex<5> fVertex = initialVertex;
00554     if ((previousPosition - newPosition).transverse() > theMaxLPShift)
00555     {
00556       // relinearize and reweight.
00557       // (reLinearizeTracks also reweights tracks)
00558       if (gsfIntermediarySmoothing_) returnVertex = theSmoother->smooth(returnVertex);
00559       globalVTracks = reLinearizeTracks( globalVTracks, returnVertex );
00560       lpStep++;
00561     } else if (step) {
00562       // reweight, if it is not the first step
00563       if (gsfIntermediarySmoothing_) returnVertex = theSmoother->smooth(returnVertex);
00564       globalVTracks = reWeightTracks( globalVTracks, returnVertex );
00565     }
00566     // update sequentially the vertex estimate
00567     CachingVertex<5> nVertex;
00568     for(vector<RefCountedVertexTrack>::const_iterator i
00569           = globalVTracks.begin(); i != globalVTracks.end(); i++)
00570     {
00571       if ((**i).weight() > 0.) nVertex = theUpdator->add( fVertex, *i );
00572         else  nVertex = fVertex;
00573       if (nVertex.isValid()) {
00574         if ( (**i).weight() >= theWeightThreshold )
00575         {
00576           ns_trks++;
00577         };
00578 
00579         if ( fabs ( nVertex.position().z() ) > 10000. ||
00580              nVertex.position().perp()>120.)
00581         {
00582           // were more than 100 m off!!
00583           LogWarning ("AdaptiveVertexFitter" ) << "Vertex candidate just took off to " << nVertex.position()
00584                                             << "! Will discard this update!";
00585 //          //<< "track pt was " << (**i).linearizedTrack()->track().pt()
00586 //                                           << "track momentum was " << (**i).linearizedTrack()->track().initialFreeState().momentum()
00587 //                                           << "track position was " << (**i).linearizedTrack()->track().initialFreeState().position()
00588 //                                           << "track chi2 was " << (**i).linearizedTrack()->track().chi2()
00589 //                                           << "track ndof was " << (**i).linearizedTrack()->track().ndof()
00590 //                                           << "track w was " << (**i).weight()
00591 //                                           << "track schi2 was " << (**i).smoothedChi2();
00592         } else {
00593                 fVertex = nVertex;
00594         }
00595       } else {
00596         LogWarning("RecoVertex/AdaptiveVertexFitter") 
00597           << "The updator returned an invalid vertex when adding track "
00598           << i-globalVTracks.begin() 
00599                 << ".\n Your vertex might just have lost one good track.";
00600       };
00601     }
00602     previousPosition = newPosition;
00603     newPosition = fVertex.position();
00604     returnVertex = fVertex;
00605     theAssProbComputer->anneal();
00606     step++;
00607     if ( step >= theMaxStep ) break;
00608 
00609   } while (
00610       // repeat as long as
00611       // - vertex moved too much or
00612       // - we're not yet annealed
00613          ( ((previousPosition - newPosition).mag() > theMaxShift) ||
00614            (!(theAssProbComputer->isAnnealed()) ) ) ) ;
00615 
00616   if ( theWeightThreshold > 0. &&  ns_trks < 2 && !withPrior ) 
00617   {
00618     LogDebug("AdaptiveVertexFitter") 
00619       << "fewer than two significant tracks (w>" << theWeightThreshold << ")."
00620       << " Fitted vertex is invalid.";
00621     return CachingVertex<5>(); // return invalid vertex
00622   }
00623 
00624   #ifdef STORE_WEIGHTS
00625   map < string, dataharvester::MultiType > m;
00626   m["chi2"]=chi2;
00627   m["w"]=theAssProbComputer->weight(chi2);
00628   m["T"]=theAssProbComputer->currentTemp();
00629   m["n"]=iter;
00630   m["id"]=getId ( *i );
00631   m["pos"]="final";
00632   dataharvester::Writer::file("w.txt").save ( m );
00633   #endif
00634   return theSmoother->smooth( returnVertex );
00635 }