Changes in modules/VertexFinderDA4D.cc [77e9ae1:61569e0] in git
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
modules/VertexFinderDA4D.cc
r77e9ae1 r61569e0 7 7 */ 8 8 9 9 10 #include "modules/VertexFinderDA4D.h" 10 11 #include "classes/DelphesClasses.h" … … 13 14 #include "classes/DelphesPileUpReader.h" 14 15 16 #include "ExRootAnalysis/ExRootResult.h" 17 #include "ExRootAnalysis/ExRootFilter.h" 15 18 #include "ExRootAnalysis/ExRootClassifier.h" 16 #include "ExRootAnalysis/ExRootFilter.h" 17 #include "ExRootAnalysis/ExRootResult.h" 18 19 20 #include "TMath.h" 21 #include "TString.h" 22 #include "TFormula.h" 23 #include "TRandom3.h" 24 #include "TObjArray.h" 19 25 #include "TDatabasePDG.h" 20 #include "TFormula.h"21 26 #include "TLorentzVector.h" 22 #include "TMath.h"23 27 #include "TMatrixT.h" 24 #include "TObjArray.h"25 #include "TRandom3.h"26 #include "TString.h"27 28 #include "TVector3.h" 28 29 30 #include <utility> 29 31 #include <algorithm> 32 #include <stdexcept> 30 33 #include <iostream> 31 #include <stdexcept>32 #include <utility>33 34 #include <vector> 34 35 35 36 using namespace std; 36 37 37 static const Double_t mm = 1.;38 static const Double_t m = 1000. *mm;39 static const Double_t ns = 1.;40 static const Double_t s = 1.e+9 * 41 static const Double_t c_light = 2.99792458e+8 * m /s;38 static const Double_t mm = 1.; 39 static const Double_t m = 1000.*mm; 40 static const Double_t ns = 1.; 41 static const Double_t s = 1.e+9 *ns; 42 static const Double_t c_light = 2.99792458e+8 * m/s; 42 43 43 44 struct track_t 44 45 { 45 double z; // z-coordinate at point of closest approach to the beamline46 double t; // t-coordinate at point of closest approach to the beamline47 double dz2; // square of the error of z(pca)48 double dtz; // covariance of z-t49 double dt2; // square of the error of t(pca)46 double z; // z-coordinate at point of closest approach to the beamline 47 double t; // t-coordinate at point of closest approach to the beamline 48 double dz2; // square of the error of z(pca) 49 double dtz; // covariance of z-t 50 double dt2; // square of the error of t(pca) 50 51 Candidate *tt; // a pointer to the Candidate Track 51 double Z; // Z[i] for DA clustering52 double pi; // track weight52 double Z; // Z[i] for DA clustering 53 double pi; // track weight 53 54 double pt; 54 55 double eta; … … 60 61 double z; 61 62 double t; 62 double pk; // vertex weight for "constrained" clustering63 double pk; // vertex weight for "constrained" clustering 63 64 // --- temporary numbers, used during update 64 65 double ei; … … 75 76 static double update1(double beta, std::vector<track_t> &tks, std::vector<vertex_t> &y); 76 77 static double update2(double beta, std::vector<track_t> &tks, std::vector<vertex_t> &y, double &rho0, const double dzCutOff); 77 static void dump(const double beta, const std::vector<vertex_t> & y, const std::vector<track_t> &tks);78 static void dump(const double beta, const std::vector<vertex_t> & y, const std::vector<track_t> & tks); 78 79 static bool merge(std::vector<vertex_t> &); 79 80 static bool merge(std::vector<vertex_t> &, double &); 80 static bool purge(std::vector<vertex_t> &, std::vector<track_t> & , double &, const double, const double);81 static bool purge(std::vector<vertex_t> &, std::vector<track_t> & , double &, const double, const double); 81 82 static void splitAll(std::vector<vertex_t> &y); 82 83 static double beta0(const double betamax, std::vector<track_t> &tks, std::vector<vertex_t> &y, const double coolingFactor); 83 84 static double Eik(const track_t &t, const vertex_t &k); 84 85 85 static bool recTrackLessZ1(const track_t & tk1, const track_t &tk2)86 static bool recTrackLessZ1(const track_t & tk1, const track_t & tk2) 86 87 { 87 88 return tk1.z < tk2.z; … … 114 115 fVertexSpaceSize = GetDouble("VertexSpaceSize", 0.5); //in mm 115 116 fVertexTimeSize = GetDouble("VertexTimeSize", 10E-12); //in s 116 fUseTc = GetBool("UseTc", 1);117 fBetaMax = GetDouble("BetaMax ", 0.1);118 fBetaStop = GetDouble("BetaStop", 1.0);117 fUseTc = GetBool("UseTc", 1); 118 fBetaMax = GetDouble("BetaMax ", 0.1); 119 fBetaStop = GetDouble("BetaStop", 1.0); 119 120 fCoolingFactor = GetDouble("CoolingFactor", 0.8); 120 121 fMaxIterations = GetInt("MaxIterations", 100); 121 fDzCutOff = GetDouble("DzCutOff", 40);// Adaptive Fitter uses 30 mm but that appears to be a bit tight here sometimes122 fD0CutOff = GetDouble("D0CutOff", 30);123 fDtCutOff = GetDouble("DtCutOff", 100E-12);// dummy122 fDzCutOff = GetDouble("DzCutOff", 40); // Adaptive Fitter uses 30 mm but that appears to be a bit tight here sometimes 123 fD0CutOff = GetDouble("D0CutOff", 30); 124 fDtCutOff = GetDouble("DtCutOff", 100E-12); // dummy 124 125 125 126 // convert stuff in cm, ns 126 127 fVertexSpaceSize /= 10.0; 127 128 fVertexTimeSize *= 1E9; 128 fDzCutOff /= 10.0;// Adaptive Fitter uses 3.0 but that appears to be a bit tight here sometimes129 fD0CutOff /= 10.0;129 fDzCutOff /= 10.0; // Adaptive Fitter uses 3.0 but that appears to be a bit tight here sometimes 130 fD0CutOff /= 10.0; 130 131 131 132 fInputArray = ImportArray(GetString("InputArray", "TrackSmearing/tracks")); … … 156 157 157 158 TLorentzVector pos, mom; 158 if (fVerbose)159 if (fVerbose) 159 160 { 160 cout << " start processing vertices ..." <<endl;161 cout << " Found " << fInputArray->GetEntriesFast() << " input tracks" <<endl;162 //loop over input tracks163 fItInputArray->Reset();164 while((candidate = static_cast<Candidate*>(fItInputArray->Next())))165 {166 pos = candidate->InitialPosition;167 mom = candidate->Momentum;168 169 cout << "pt: " << mom.Pt() << ", eta: " << mom.Eta() << ", phi: " << mom.Phi() << ", z: " << candidate->DZ / 10 <<endl;170 }161 cout<<" start processing vertices ..."<<endl; 162 cout<<" Found "<<fInputArray->GetEntriesFast()<<" input tracks"<<endl; 163 //loop over input tracks 164 fItInputArray->Reset(); 165 while((candidate = static_cast<Candidate*>(fItInputArray->Next()))) 166 { 167 pos = candidate->InitialPosition; 168 mom = candidate->Momentum; 169 170 cout<<"pt: "<<mom.Pt()<<", eta: "<<mom.Eta()<<", phi: "<<mom.Phi()<<", z: "<<candidate->DZ/10<<endl; 171 } 171 172 } 172 173 … … 174 175 clusterize(*fInputArray, *ClusterArray); 175 176 176 if(fVerbose) 177 { 178 std::cout << " clustering returned " << ClusterArray->GetEntriesFast() << " clusters from " << fInputArray->GetEntriesFast() << " selected tracks" << std::endl; 179 } 177 if (fVerbose){std::cout << " clustering returned "<< ClusterArray->GetEntriesFast() << " clusters from " << fInputArray->GetEntriesFast() << " selected tracks" <<std::endl;} 180 178 181 179 //loop over vertex candidates 182 180 ItClusterArray = ClusterArray->MakeIterator(); 183 181 ItClusterArray->Reset(); 184 while((candidate = static_cast<Candidate 182 while((candidate = static_cast<Candidate*>(ItClusterArray->Next()))) 185 183 { 186 184 187 double meantime = 0.;188 double expv_x2 = 0.;189 double normw = 0.;190 double errtime = 0;191 192 double meanpos = 0.;193 double meanerr2 = 0.;194 double normpos = 0.;195 double errpos = 0.;196 197 double sumpt2 = 0.;198 199 int itr = 0;200 201 if(fVerbose) cout << "this vertex has: " << candidate->GetCandidates()->GetEntriesFast() << " tracks" <<endl;202 203 // loop over tracks belonging to this vertex204 TIter it1(candidate->GetCandidates());205 it1.Reset();206 207 while((track = static_cast<Candidate*>(it1.Next())))208 {209 210 itr++;211 // TBC: the time is in ns for now TBC212 double t = track->InitialPosition.T() /c_light;213 double dt = track->ErrorT /c_light;214 const double time = t;215 const double inverr = 1.0 /dt;216 meantime += time *inverr;217 expv_x2 += time * time *inverr;218 normw+= inverr;219 220 // compute error position TBC221 const double pt = track->Momentum.Pt();222 const double z = track->DZ /10.0;223 const double err_pt = track->ErrorPT;224 const double err_z = track->ErrorDZ;225 226 const double wi = (pt / (err_pt * err_z)) * (pt / (err_pt *err_z));227 meanpos += z *wi;228 229 meanerr2 += err_z * err_z *wi;230 normpos += wi;231 sumpt2 += pt *pt;232 233 // while we are here store cluster index in tracks234 track->ClusterIndex = ivtx;235 }236 237 meantime = meantime /normw;238 expv_x2 = expv_x2 /normw;239 errtime = TMath::Sqrt((expv_x2 - meantime * meantime) /itr);240 meanpos = meanpos /normpos;241 meanerr2 = meanerr2 /normpos;242 errpos = TMath::Sqrt(meanerr2 /itr);243 244 candidate->Position.SetXYZT(0.0, 0.0, meanpos * 10.0, meantime *c_light);245 candidate->PositionError.SetXYZT(0.0, 0.0, errpos * 10.0, errtime *c_light);246 candidate->SumPT2 = sumpt2;247 candidate->ClusterNDF = itr;248 candidate->ClusterIndex = ivtx;249 250 fVertexOutputArray->Add(candidate);251 252 ivtx++;253 254 if(fVerbose)255 {256 std::cout << "x,y,z";257 std::cout << ",t";258 std::cout << "=" << candidate->Position.X() / 10.0 << " " << candidate->Position.Y() / 10.0 << " " << candidate->Position.Z() / 10.0;259 std::cout << " " << candidate->Position.T() / c_light; 260 261 std::cout << std::endl;262 std::cout << "sumpt2 " << candidate->SumPT2 << endl;263 264 std::cout << "ex,ey,ez";265 std::cout << ",et";266 std::cout << "=" << candidate->PositionError.X() / 10.0 << " " << candidate->PositionError.Y() / 10.0 << " " << candidate->PositionError.Z() / 10.0;267 std::cout << " " << candidate->PositionError.T() / c_light;268 std::cout << std::endl; 269 }270 }// end of cluster loop271 272 if(fVerbose) 273 {274 std::cout << "PrimaryVertexProducerAlgorithm::vertices candidates =" << ClusterArray->GetEntriesFast() << std::endl;275 }276 277 //TBC maybe this can be done later278 // sort vertices by pt**2 vertex (aka signal vertex tagging)279 /*if(pvs.size()>1){185 double meantime = 0.; 186 double expv_x2 = 0.; 187 double normw = 0.; 188 double errtime = 0; 189 190 double meanpos = 0.; 191 double meanerr2 = 0.; 192 double normpos = 0.; 193 double errpos = 0.; 194 195 double sumpt2 = 0.; 196 197 int itr = 0; 198 199 if(fVerbose)cout<<"this vertex has: "<<candidate->GetCandidates()->GetEntriesFast()<<" tracks"<<endl; 200 201 // loop over tracks belonging to this vertex 202 TIter it1(candidate->GetCandidates()); 203 it1.Reset(); 204 205 while((track = static_cast<Candidate*>(it1.Next()))) 206 { 207 208 itr++; 209 // TBC: the time is in ns for now TBC 210 double t = track->InitialPosition.T()/c_light; 211 double dt = track->ErrorT/c_light; 212 const double time = t; 213 const double inverr = 1.0/dt; 214 meantime += time*inverr; 215 expv_x2 += time*time*inverr; 216 normw += inverr; 217 218 // compute error position TBC 219 const double pt = track->Momentum.Pt(); 220 const double z = track->DZ/10.0; 221 const double err_pt = track->ErrorPT; 222 const double err_z = track->ErrorDZ; 223 224 const double wi = (pt/(err_pt*err_z))*(pt/(err_pt*err_z)); 225 meanpos += z*wi; 226 227 meanerr2 += err_z*err_z*wi; 228 normpos += wi; 229 sumpt2 += pt*pt; 230 231 // while we are here store cluster index in tracks 232 track->ClusterIndex = ivtx; 233 } 234 235 meantime = meantime/normw; 236 expv_x2 = expv_x2/normw; 237 errtime = TMath::Sqrt((expv_x2 - meantime*meantime)/itr); 238 meanpos = meanpos/normpos; 239 meanerr2 = meanerr2/normpos; 240 errpos = TMath::Sqrt(meanerr2/itr); 241 242 candidate->Position.SetXYZT(0.0, 0.0, meanpos*10.0 , meantime*c_light); 243 candidate->PositionError.SetXYZT(0.0, 0.0, errpos*10.0 , errtime*c_light); 244 candidate->SumPT2 = sumpt2; 245 candidate->ClusterNDF = itr; 246 candidate->ClusterIndex = ivtx; 247 248 fVertexOutputArray->Add(candidate); 249 250 ivtx++; 251 252 if (fVerbose){ 253 std::cout << "x,y,z"; 254 std::cout << ",t"; 255 std::cout << "=" << candidate->Position.X()/10.0 <<" " << candidate->Position.Y()/10.0 << " " << candidate->Position.Z()/10.0; 256 std::cout << " " << candidate->Position.T()/c_light; 257 258 std::cout << std::endl; 259 std::cout << "sumpt2 " << candidate->SumPT2<<endl; 260 261 std::cout << "ex,ey,ez"; 262 std::cout << ",et"; 263 std::cout << "=" << candidate->PositionError.X()/10.0 <<" " << candidate->PositionError.Y()/10.0 << " " << candidate->PositionError.Z()/10.0; 264 std::cout << " " << candidate->PositionError.T()/c_light; 265 std::cout << std::endl; 266 267 } 268 }// end of cluster loop 269 270 271 if(fVerbose){ 272 std::cout << "PrimaryVertexProducerAlgorithm::vertices candidates =" << ClusterArray->GetEntriesFast() << std::endl; 273 } 274 275 //TBC maybe this can be done later 276 // sort vertices by pt**2 vertex (aka signal vertex tagging) 277 /*if(pvs.size()>1){ 280 278 sort(pvs.begin(), pvs.end(), VertexHigherPtSquared()); 281 279 } … … 283 281 284 282 delete ClusterArray; 283 285 284 } 286 285 … … 289 288 void VertexFinderDA4D::clusterize(const TObjArray &tracks, TObjArray &clusters) 290 289 { 291 if(fVerbose) 292 { 290 if(fVerbose) { 293 291 cout << "###################################################" << endl; 294 cout << "# VertexFinderDA4D::clusterize nt=" <<tracks.GetEntriesFast() << endl;292 cout << "# VertexFinderDA4D::clusterize nt="<<tracks.GetEntriesFast() << endl; 295 293 cout << "###################################################" << endl; 296 294 } 297 295 298 vector<Candidate *> pv = vertices(); 299 300 if(fVerbose) 301 { 302 cout << "# VertexFinderDA4D::clusterize pv.size=" << pv.size() << endl; 303 } 304 if(pv.size() == 0) 305 { 306 return; 307 } 296 vector< Candidate* > pv = vertices(); 297 298 if(fVerbose){ cout << "# VertexFinderDA4D::clusterize pv.size="<<pv.size() << endl; } 299 if (pv.size()==0){ return; } 308 300 309 301 // convert into vector of candidates 310 302 //TObjArray *ClusterArray = pv.begin()->GetCandidates(); 311 303 //Candidate *aCluster = static_cast<Candidate*>(&(pv.at(0))); 312 Candidate *aCluster = pv.at(0);304 Candidate *aCluster = pv.at(0); 313 305 314 306 // fill into clusters and merge 315 307 316 if(fVerbose) 317 { 318 std::cout << '\t' << 0; 319 std::cout << ' ' << (*pv.begin())->Position.Z() / 10.0 << ' ' << (*pv.begin())->Position.T() / c_light << std::endl; 320 } 321 322 for(vector<Candidate *>::iterator k = pv.begin() + 1; k != pv.end(); k++) 323 { 324 if(fVerbose) 325 { 326 std::cout << '\t' << std::distance(pv.begin(), k); 308 309 if( fVerbose ) { 310 std::cout << '\t' << 0; 311 std::cout << ' ' << (*pv.begin())->Position.Z()/10.0 << ' ' << (*pv.begin())->Position.T()/c_light << std::endl; 312 } 313 314 for(vector<Candidate*>::iterator k=pv.begin()+1; k!=pv.end(); k++){ 315 if( fVerbose ) { 316 std::cout << '\t' << std::distance(pv.begin(),k); 327 317 std::cout << ' ' << (*k)->Position.Z() << ' ' << (*k)->Position.T() << std::endl; 328 318 } 329 319 320 330 321 // TBC - check units here 331 if (std::abs((*k)->Position.Z() - (*(k - 1))->Position.Z()) / 10.0 > (2 * fVertexSpaceSize) || std::abs((*k)->Position.T() - (*(k - 1))->Position.Z()) / c_light > 2 * 0.010)332 {322 if ( std::abs((*k)->Position.Z() - (*(k-1))->Position.Z())/10.0 > (2*fVertexSpaceSize) || 323 std::abs((*k)->Position.T() - (*(k-1))->Position.Z())/c_light > 2*0.010 ) { 333 324 // close a cluster 334 325 clusters.Add(aCluster); … … 336 327 } 337 328 //for(unsigned int i=0; i<k->GetCandidates().GetEntriesFast(); i++){ 338 aCluster = *k;329 aCluster = *k; 339 330 //} 331 340 332 } 341 333 clusters.Add(aCluster); 342 334 343 if(fVerbose) 344 { 345 std::cout << "# VertexFinderDA4D::clusterize clusters.size=" << clusters.GetEntriesFast() << std::endl; 346 } 347 } 348 349 //------------------------------------------------------------------------------ 350 351 vector<Candidate *> VertexFinderDA4D::vertices() 335 if(fVerbose) { std::cout << "# VertexFinderDA4D::clusterize clusters.size="<<clusters.GetEntriesFast() << std::endl; } 336 337 } 338 339 //------------------------------------------------------------------------------ 340 341 vector< Candidate* > VertexFinderDA4D::vertices() 352 342 { 353 343 Candidate *candidate; 354 344 UInt_t clusterIndex = 0; 355 vector< Candidate *> clusters;345 vector< Candidate* > clusters; 356 346 357 347 vector<track_t> tks; … … 361 351 // loop over input tracks 362 352 fItInputArray->Reset(); 363 while((candidate = static_cast<Candidate 353 while((candidate = static_cast<Candidate*>(fItInputArray->Next()))) 364 354 { 365 355 //TBC everything in cm 366 z = candidate->DZ /10;356 z = candidate->DZ/10; 367 357 tr.z = z; 368 dz = candidate->ErrorDZ /10;369 tr.dz2 = dz * dz// track error370 371 372 + fVertexSpaceSize *fVertexSpaceSize; // intrinsic vertex size, safer for outliers and short lived decays358 dz = candidate->ErrorDZ/10; 359 tr.dz2 = dz*dz // track error 360 //TBC: beamspot size induced error, take 0 for now. 361 // + (std::pow(beamspot.BeamWidthX()*cos(phi),2.)+std::pow(beamspot.BeamWidthY()*sin(phi),2.))/std::pow(tantheta,2.) // beam-width induced 362 + fVertexSpaceSize*fVertexSpaceSize; // intrinsic vertex size, safer for outliers and short lived decays 373 363 374 364 // TBC: the time is in ns for now TBC 375 365 //t = candidate->Position.T()/c_light; 376 t = candidate->InitialPosition.T() /c_light;377 l = candidate->L /c_light;366 t = candidate->InitialPosition.T()/c_light; 367 l = candidate->L/c_light; 378 368 double pt = candidate->Momentum.Pt(); 379 369 double eta = candidate->Momentum.Eta(); … … 385 375 tr.t = t; // 386 376 tr.dtz = 0.; 387 dt = candidate->ErrorT /c_light;388 tr.dt2 = dt * dt + fVertexTimeSize * fVertexTimeSize;// the ~injected~ timing error plus a small minimum vertex size in time389 if(fD0CutOff >0)377 dt = candidate->ErrorT/c_light; 378 tr.dt2 = dt*dt + fVertexTimeSize*fVertexTimeSize; // the ~injected~ timing error plus a small minimum vertex size in time 379 if(fD0CutOff>0) 390 380 { 391 381 392 d0 = TMath::Abs(candidate->D0) / 10.0; 393 d0error = candidate->ErrorD0 / 10.0; 394 395 tr.pi = 1. / (1. + exp((d0 * d0) / (d0error * d0error) - fD0CutOff * fD0CutOff)); // reduce weight for high ip tracks 382 d0 = TMath::Abs(candidate->D0)/10.0; 383 d0error = candidate->ErrorD0/10.0; 384 385 tr.pi=1./(1.+exp((d0*d0)/(d0error*d0error) - fD0CutOff*fD0CutOff)); // reduce weight for high ip tracks 386 396 387 } 397 388 else 398 389 { 399 tr.pi =1.;400 } 401 tr.tt =&(*candidate);402 tr.Z =1.;390 tr.pi=1.; 391 } 392 tr.tt=&(*candidate); 393 tr.Z=1.; 403 394 404 395 // TBC now putting track selection here (> fPTMin) … … 413 404 if(fVerbose) 414 405 { 415 std::cout << " start processing vertices ..." <<std::endl;416 std::cout << " Found " << tks.size() << " input tracks" <<std::endl;406 std::cout<<" start processing vertices ..."<<std::endl; 407 std::cout<<" Found "<<tks.size()<<" input tracks"<<std::endl; 417 408 //loop over input tracks 418 409 419 for(std::vector<track_t>::const_iterator it = tks.begin(); it != tks.end(); it++) 420 421 422 double pt =it->pt;423 double eta =it->eta;424 double phi =it->phi;425 426 427 std::cout << "pt: " << pt << ", eta: " << eta << ", phi: " << phi << ", z: " << z << ", t: " << t <<std::endl;428 429 } 430 431 unsigned int nt =tks.size();432 double rho0 = 0.0;// start with no outlier rejection433 434 if (tks.empty()) return clusters;410 411 for(std::vector<track_t>::const_iterator it=tks.begin(); it!=tks.end(); it++){ 412 double z = it->z; 413 double pt=it->pt; 414 double eta=it->eta; 415 double phi=it->phi; 416 double t = it->t; 417 418 std::cout<<"pt: "<<pt<<", eta: "<<eta<<", phi: "<<phi<<", z: "<<z<<", t: "<<t<<std::endl; 419 } 420 } 421 422 unsigned int nt=tks.size(); 423 double rho0=0.0; // start with no outlier rejection 424 425 if (tks.empty()) return clusters; 435 426 436 427 vector<vertex_t> y; // the vertex prototypes … … 438 429 // initialize:single vertex at infinite temperature 439 430 vertex_t vstart; 440 vstart.z =0.;441 vstart.t =0.;442 vstart.pk =1.;431 vstart.z=0.; 432 vstart.t=0.; 433 vstart.pk=1.; 443 434 y.push_back(vstart); 444 int niter = 0;// number of iterations435 int niter=0; // number of iterations 445 436 446 437 // estimate first critical temperature 447 double beta = beta0(fBetaMax, tks, y, fCoolingFactor); 448 niter = 0; 449 while((update1(beta, tks, y) > 1.e-6) && (niter++ < fMaxIterations)) 450 { 451 } 438 double beta=beta0(fBetaMax, tks, y, fCoolingFactor); 439 niter=0; while((update1(beta, tks,y)>1.e-6) && (niter++ < fMaxIterations)){ } 452 440 453 441 // annealing loop, stop when T<Tmin (i.e. beta>1/Tmin) 454 while(beta < fBetaMax) 455 { 456 457 if(fUseTc) 458 { 459 update1(beta, tks, y); 460 while(merge(y, beta)) 461 { 462 update1(beta, tks, y); 463 } 464 split(beta, tks, y); 465 beta = beta / fCoolingFactor; 466 } 467 else 468 { 469 beta = beta / fCoolingFactor; 442 while(beta<fBetaMax){ 443 444 if(fUseTc){ 445 update1(beta, tks,y); 446 while(merge(y,beta)){update1(beta, tks,y);} 447 split(beta, tks,y); 448 beta=beta/fCoolingFactor; 449 }else{ 450 beta=beta/fCoolingFactor; 470 451 splitAll(y); 471 452 } 472 453 473 // make sure we are not too far from equilibrium before cooling further 474 niter = 0; 475 while((update1(beta, tks, y) > 1.e-6) && (niter++ < fMaxIterations)) 476 { 477 } 478 } 479 480 if(fUseTc) 481 { 454 // make sure we are not too far from equilibrium before cooling further 455 niter=0; while((update1(beta, tks,y)>1.e-6) && (niter++ < fMaxIterations)){ } 456 457 } 458 459 if(fUseTc){ 482 460 // last round of splitting, make sure no critical clusters are left 483 update1(beta, tks, y); 484 while(merge(y, beta)) 485 { 486 update1(beta, tks, y); 487 } 488 unsigned int ntry = 0; 489 while(split(beta, tks, y) && (ntry++ < 10)) 490 { 491 niter = 0; 492 while((update1(beta, tks, y) > 1.e-6) && (niter++ < fMaxIterations)) 493 { 494 } 495 merge(y, beta); 496 update1(beta, tks, y); 497 } 498 } 499 else 500 { 461 update1(beta, tks,y); 462 while(merge(y,beta)){update1(beta, tks,y);} 463 unsigned int ntry=0; 464 while( split(beta, tks,y) && (ntry++<10) ){ 465 niter=0; 466 while((update1(beta, tks,y)>1.e-6) && (niter++ < fMaxIterations)){} 467 merge(y,beta); 468 update1(beta, tks,y); 469 } 470 }else{ 501 471 // merge collapsed clusters 502 while(merge(y, beta)) 503 { 504 update1(beta, tks, y); 505 } 506 if(fVerbose) 507 { 508 cout << "dump after 1st merging " << endl; 509 dump(beta, y, tks); 510 } 472 while(merge(y,beta)){update1(beta, tks,y);} 473 if(fVerbose ){ cout << "dump after 1st merging " << endl; dump(beta,y,tks);} 511 474 } 512 475 513 476 // switch on outlier rejection 514 rho0 = 1. / nt; 515 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); k++) 516 { 517 k->pk = 1.; 518 } // democratic 519 niter = 0; 520 while((update2(beta, tks, y, rho0, fDzCutOff) > 1.e-8) && (niter++ < fMaxIterations)) 521 { 522 } 523 if(fVerbose) 524 { 525 cout << "rho0=" << rho0 << " niter=" << niter << endl; 526 dump(beta, y, tks); 527 } 477 rho0=1./nt; for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){ k->pk =1.; } // democratic 478 niter=0; while((update2(beta, tks,y,rho0, fDzCutOff) > 1.e-8) && (niter++ < fMaxIterations)){ } 479 if(fVerbose ){ cout << "rho0=" << rho0 << " niter=" << niter << endl; dump(beta,y,tks);} 480 528 481 529 482 // merge again (some cluster split by outliers collapse here) 530 while(merge(y)) 531 { 532 } 533 if(fVerbose) 534 { 535 cout << "dump after 2nd merging " << endl; 536 dump(beta, y, tks); 537 } 483 while(merge(y)){} 484 if(fVerbose ){ cout << "dump after 2nd merging " << endl; dump(beta,y,tks);} 485 538 486 539 487 // continue from freeze-out to Tstop (=1) without splitting, eliminate insignificant vertices 540 while(beta <= fBetaStop) 541 { 542 while(purge(y, tks, rho0, beta, fDzCutOff)) 543 { 544 niter = 0; 545 while((update2(beta, tks, y, rho0, fDzCutOff) > 1.e-6) && (niter++ < fMaxIterations)) 546 { 547 } 548 } 549 beta /= fCoolingFactor; 550 niter = 0; 551 while((update2(beta, tks, y, rho0, fDzCutOff) > 1.e-6) && (niter++ < fMaxIterations)) 552 { 553 } 554 } 555 556 // // new, one last round of cleaning at T=Tstop 557 // while(purge(y,tks,rho0, beta)){ 558 // niter=0; while((update2(beta, tks,y,rho0, fDzCutOff) > 1.e-6) && (niter++ < fMaxIterations)){ } 559 // } 560 561 if(fVerbose) 562 { 563 cout << "Final result, rho0=" << rho0 << endl; 564 dump(beta, y, tks); 565 } 488 while(beta<=fBetaStop){ 489 while(purge(y,tks,rho0, beta, fDzCutOff)){ 490 niter=0; while((update2(beta, tks, y, rho0, fDzCutOff) > 1.e-6) && (niter++ < fMaxIterations)){ } 491 } 492 beta/=fCoolingFactor; 493 niter=0; while((update2(beta, tks, y, rho0, fDzCutOff) > 1.e-6) && (niter++ < fMaxIterations)){ } 494 } 495 496 497 // // new, one last round of cleaning at T=Tstop 498 // while(purge(y,tks,rho0, beta)){ 499 // niter=0; while((update2(beta, tks,y,rho0, fDzCutOff) > 1.e-6) && (niter++ < fMaxIterations)){ } 500 // } 501 502 503 if(fVerbose){ 504 cout << "Final result, rho0=" << rho0 << endl; 505 dump(beta,y,tks); 506 } 507 566 508 567 509 // select significant tracks and use a TransientVertex as a container … … 569 511 570 512 // ensure correct normalization of probabilities, should make double assginment reasonably impossible 571 for(unsigned int i = 0; i < nt; i++) 572 { 573 tks[i].Z = rho0 * exp(-beta * (fDzCutOff * fDzCutOff)); 574 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); k++) 575 { 576 tks[i].Z += k->pk * exp(-beta * Eik(tks[i], *k)); 577 } 578 } 579 580 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); k++) 581 { 513 for(unsigned int i=0; i<nt; i++){ 514 tks[i].Z=rho0*exp(-beta*( fDzCutOff*fDzCutOff)); 515 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){ 516 tks[i].Z += k->pk * exp(-beta*Eik(tks[i],*k)); 517 } 518 } 519 520 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){ 582 521 583 522 DelphesFactory *factory = GetFactory(); … … 593 532 double expv_x2 = 0.; 594 533 double normw = 0.; 595 for(unsigned int i = 0; i < nt; i++) 596 { 597 const double invdt = 1.0 / std::sqrt(tks[i].dt2); 598 if(tks[i].Z > 0) 599 { 600 double p = k->pk * exp(-beta * Eik(tks[i], *k)) / tks[i].Z; 601 if((tks[i].pi > 0) && (p > 0.5)) 602 { 534 for(unsigned int i=0; i<nt; i++){ 535 const double invdt = 1.0/std::sqrt(tks[i].dt2); 536 if(tks[i].Z>0){ 537 double p = k->pk * exp(-beta*Eik(tks[i],*k)) / tks[i].Z; 538 if( (tks[i].pi>0) && ( p > 0.5 ) ){ 603 539 //std::cout << "pushing back " << i << ' ' << tks[i].tt << std::endl; 604 540 //vertexTracks.push_back(*(tks[i].tt)); tks[i].Z=0; 605 541 606 candidate->AddCandidate(tks[i].tt); 607 tks[i].Z = 0; 608 609 mean += tks[i].t * invdt * p; 610 expv_x2 += tks[i].t * tks[i].t * invdt * p; 611 normw += invdt * p; 542 candidate->AddCandidate(tks[i].tt); tks[i].Z=0; 543 544 mean += tks[i].t*invdt*p; 545 expv_x2 += tks[i].t*tks[i].t*invdt*p; 546 normw += invdt*p; 612 547 } // setting Z=0 excludes double assignment 613 548 } 614 549 } 615 550 616 mean = mean /normw;617 expv_x2 = expv_x2 /normw;618 const double time_var = expv_x2 - mean *mean;551 mean = mean/normw; 552 expv_x2 = expv_x2/normw; 553 const double time_var = expv_x2 - mean*mean; 619 554 const double crappy_error_guess = std::sqrt(time_var); 620 555 /*GlobalError dummyErrorWithTime(0, … … 624 559 //TransientVertex v(pos, time, dummyErrorWithTime, vertexTracks, 5); 625 560 626 candidate->ClusterIndex = clusterIndex++; 627 ;628 candidate->Position.SetXYZT(0.0, 0.0, z * 10.0, time *c_light);561 562 candidate->ClusterIndex = clusterIndex++;; 563 candidate->Position.SetXYZT(0.0, 0.0, z*10.0 , time*c_light); 629 564 630 565 // TBC - fill error later ... 631 candidate->PositionError.SetXYZT(0.0, 0.0, 0.0 , crappy_error_guess *c_light);566 candidate->PositionError.SetXYZT(0.0, 0.0, 0.0 , crappy_error_guess*c_light); 632 567 633 568 clusterIndex++; … … 635 570 } 636 571 572 637 573 return clusters; 638 } 639 640 //------------------------------------------------------------------------------ 641 642 static double Eik(const track_t &t, const vertex_t &k) 643 { 644 return std::pow(t.z - k.z, 2.) / t.dz2 + std::pow(t.t - k.t, 2.) / t.dt2; 574 575 } 576 577 //------------------------------------------------------------------------------ 578 579 static double Eik(const track_t & t, const vertex_t &k) 580 { 581 return std::pow(t.z-k.z,2.)/t.dz2 + std::pow(t.t - k.t,2.)/t.dt2; 645 582 } 646 583 … … 651 588 // copy and sort for nicer printout 652 589 vector<track_t> tks; 653 for(vector<track_t>::const_iterator t = tks0.begin(); t != tks0.end(); t++) 654 { 655 tks.push_back(*t); 656 } 590 for(vector<track_t>::const_iterator t=tks0.begin(); t!=tks0.end(); t++){tks.push_back(*t); } 657 591 std::stable_sort(tks.begin(), tks.end(), recTrackLessZ1); 658 592 … … 661 595 cout << " z= "; 662 596 cout.precision(4); 663 for(vector<vertex_t>::const_iterator k = y.begin(); k != y.end(); k++) 664 { 597 for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){ 665 598 //cout << setw(8) << fixed << k->z; 666 599 } 667 cout << endl 668 << " t= "; 669 for(vector<vertex_t>::const_iterator k = y.begin(); k != y.end(); k++) 670 { 600 cout << endl << " t= "; 601 for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){ 671 602 //cout << setw(8) << fixed << k->t; 672 603 } 673 604 //cout << endl << "T=" << setw(15) << 1./beta <<" Tc= "; 674 for(vector<vertex_t>::const_iterator k = y.begin(); k != y.end(); k++) 675 { 605 for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){ 676 606 //cout << setw(8) << fixed << k->Tc ; 677 607 } 678 608 679 cout << endl 680 << " pk="; 681 double sumpk = 0; 682 for(vector<vertex_t>::const_iterator k = y.begin(); k != y.end(); k++) 683 { 609 cout << endl << " pk="; 610 double sumpk=0; 611 for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){ 684 612 //cout << setw(8) << setprecision(3) << fixed << k->pk; 685 sumpk +=k->pk;686 } 687 cout << endl;688 689 double E = 0, F =0;613 sumpk+=k->pk; 614 } 615 cout << endl; 616 617 double E=0, F=0; 690 618 cout << endl; 691 619 cout << "---- z +/- dz t +/- dt ip +/-dip pt phi eta weights ----" << endl; 692 620 cout.precision(4); 693 for(unsigned int i = 0; i < tks.size(); i++) 694 { 695 if(tks[i].Z > 0) 696 { 697 F -= log(tks[i].Z) / beta; 698 } 699 double tz = tks[i].z; 700 double tt = tks[i].t; 621 for(unsigned int i=0; i<tks.size(); i++){ 622 if (tks[i].Z>0){ F-=log(tks[i].Z)/beta;} 623 double tz= tks[i].z; 624 double tt= tks[i].t; 701 625 //cout << setw (3)<< i << ")" << setw (8) << fixed << setprecision(4)<< tz << " +/-" << setw (6)<< sqrt(tks[i].dz2) 702 626 // << setw(8) << fixed << setprecision(4) << tt << " +/-" << setw(6) << std::sqrt(tks[i].dt2) ; 703 627 704 double sump = 0.; 705 for(vector<vertex_t>::const_iterator k = y.begin(); k != y.end(); k++) 706 { 707 if((tks[i].pi > 0) && (tks[i].Z > 0)) 708 { 709 //double p=pik(beta,tks[i],*k); 710 double p = k->pk * std::exp(-beta * Eik(tks[i], *k)) / tks[i].Z; 711 if(p > 0.0001) 712 { 713 //cout << setw (8) << setprecision(3) << p; 714 } 715 else 716 { 717 cout << " . "; 718 } 719 E += p * Eik(tks[i], *k); 720 sump += p; 628 double sump=0.; 629 for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){ 630 if((tks[i].pi>0)&&(tks[i].Z>0)){ 631 //double p=pik(beta,tks[i],*k); 632 double p=k->pk * std::exp(-beta*Eik(tks[i],*k)) / tks[i].Z; 633 if( p > 0.0001){ 634 //cout << setw (8) << setprecision(3) << p; 635 }else{ 636 cout << " . "; 637 } 638 E+=p*Eik(tks[i],*k); 639 sump+=p; 640 }else{ 641 cout << " "; 642 } 721 643 } 722 else 723 { 724 cout << " "; 725 } 726 } 727 cout << endl; 728 } 729 cout << endl 730 << "T=" << 1 / beta << " E=" << E << " n=" << y.size() << " F= " << F << endl 731 << "----------" << endl; 644 cout << endl; 645 } 646 cout << endl << "T=" << 1/beta << " E=" << E << " n="<< y.size() << " F= " << F << endl << "----------" << endl; 732 647 } 733 648 … … 740 655 // returns the squared sum of changes of vertex positions 741 656 742 unsigned int nt =tks.size();657 unsigned int nt=tks.size(); 743 658 744 659 //initialize sums 745 double sumpi = 0; 746 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); ++k) 747 { 748 k->sw = 0.; 749 k->swz = 0.; 750 k->swt = 0.; 751 k->se = 0.; 752 k->swE = 0.; 753 k->Tc = 0.; 754 } 660 double sumpi=0; 661 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); ++k){ 662 k->sw=0.; k->swz=0.; k->swt = 0.; k->se=0.; 663 k->swE=0.; k->Tc=0.; 664 } 665 755 666 756 667 // loop over tracks 757 for(unsigned int i = 0; i < nt; i++) 758 { 668 for(unsigned int i=0; i<nt; i++){ 759 669 760 670 // update pik and Zi 761 671 double Zi = 0.; 762 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); ++k) 763 { 764 k->ei = std::exp(-beta * Eik(tks[i], *k)); // cache exponential for one track at a time 765 Zi += k->pk * k->ei; 766 } 767 tks[i].Z = Zi; 672 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); ++k){ 673 k->ei = std::exp(-beta*Eik(tks[i],*k));// cache exponential for one track at a time 674 Zi += k->pk * k->ei; 675 } 676 tks[i].Z=Zi; 768 677 769 678 // normalization for pk 770 if(tks[i].Z > 0) 771 { 679 if (tks[i].Z>0){ 772 680 sumpi += tks[i].pi; 773 681 // accumulate weighted z and weights for vertex update 774 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); ++k) 775 { 776 k->se += tks[i].pi * k->ei / Zi; 777 const double w = k->pk * tks[i].pi * k->ei / (Zi * (tks[i].dz2 * tks[i].dt2)); 778 k->sw += w; 779 k->swz += w * tks[i].z; 682 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); ++k){ 683 k->se += tks[i].pi* k->ei / Zi; 684 const double w = k->pk * tks[i].pi* k->ei / ( Zi * ( tks[i].dz2 * tks[i].dt2 ) ); 685 k->sw += w; 686 k->swz += w * tks[i].z; 780 687 k->swt += w * tks[i].t; 781 k->swE += w * Eik(tks[i],*k);688 k->swE += w * Eik(tks[i],*k); 782 689 } 783 } 784 else 785 { 690 }else{ 786 691 sumpi += tks[i].pi; 787 692 } 788 693 694 789 695 } // end of track loop 790 696 697 791 698 // now update z and pk 792 double delta = 0; 793 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); k++) 794 { 795 if(k->sw > 0) 796 { 797 const double znew = k->swz / k->sw; 798 const double tnew = k->swt / k->sw; 799 delta += std::pow(k->z - znew, 2.) + std::pow(k->t - tnew, 2.); 800 k->z = znew; 801 k->t = tnew; 802 k->Tc = 2. * k->swE / k->sw; 803 } 804 else 805 { 699 double delta=0; 700 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){ 701 if ( k->sw > 0){ 702 const double znew = k->swz/k->sw; 703 const double tnew = k->swt/k->sw; 704 delta += std::pow(k->z-znew,2.) + std::pow(k->t-tnew,2.); 705 k->z = znew; 706 k->t = tnew; 707 k->Tc = 2.*k->swE/k->sw; 708 }else{ 806 709 // cout << " a cluster melted away ? pk=" << k->pk << " sumw=" << k->sw << endl 807 k->Tc =-1;710 k->Tc=-1; 808 711 } 809 712 … … 822 725 // returns the squared sum of changes of vertex positions 823 726 824 unsigned int nt =tks.size();727 unsigned int nt=tks.size(); 825 728 826 729 //initialize sums 827 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); k++) 828 { 829 k->sw = 0.; 830 k->swz = 0.; 831 k->swt = 0.; 832 k->se = 0.; 833 k->swE = 0.; 834 k->Tc = 0.; 835 } 730 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){ 731 k->sw = 0.; k->swz = 0.; k->swt = 0.; k->se = 0.; 732 k->swE = 0.; k->Tc=0.; 733 } 734 836 735 837 736 // loop over tracks 838 for(unsigned int i = 0; i < nt; i++) 839 { 737 for(unsigned int i=0; i<nt; i++){ 840 738 841 739 // update pik and Zi and Ti 842 double Zi = rho0 * std::exp(-beta * (dzCutOff * dzCutOff));// cut-off (eventually add finite size in time)740 double Zi = rho0*std::exp(-beta*(dzCutOff*dzCutOff));// cut-off (eventually add finite size in time) 843 741 //double Ti = 0.; // dt0*std::exp(-beta*fDtCutOff); 844 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); k++) 845 { 846 k->ei = std::exp(-beta * Eik(tks[i], *k)); // cache exponential for one track at a time 847 Zi += k->pk * k->ei; 848 } 849 tks[i].Z = Zi; 742 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){ 743 k->ei = std::exp(-beta*Eik(tks[i],*k));// cache exponential for one track at a time 744 Zi += k->pk * k->ei; 745 } 746 tks[i].Z=Zi; 850 747 851 748 // normalization 852 if(tks[i].Z > 0) 853 { 854 // accumulate weighted z and weights for vertex update 855 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); k++) 856 { 857 k->se += tks[i].pi * k->ei / Zi; 858 double w = k->pk * tks[i].pi * k->ei / (Zi * (tks[i].dz2 * tks[i].dt2)); 859 k->sw += w; 860 k->swz += w * tks[i].z; 749 if (tks[i].Z>0){ 750 // accumulate weighted z and weights for vertex update 751 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){ 752 k->se += tks[i].pi* k->ei / Zi; 753 double w = k->pk * tks[i].pi * k->ei /( Zi * ( tks[i].dz2 * tks[i].dt2 ) ); 754 k->sw += w; 755 k->swz += w * tks[i].z; 861 756 k->swt += w * tks[i].t; 862 k->swE += w * Eik(tks[i],*k);757 k->swE += w * Eik(tks[i],*k); 863 758 } 864 759 } … … 867 762 868 763 // now update z 869 double delta = 0; 870 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); k++) 871 { 872 if(k->sw > 0) 873 { 874 const double znew = k->swz / k->sw; 875 const double tnew = k->swt / k->sw; 876 delta += std::pow(k->z - znew, 2.) + std::pow(k->t - tnew, 2.); 877 k->z = znew; 878 k->t = tnew; 879 k->Tc = 2 * k->swE / k->sw; 880 } 881 else 882 { 764 double delta=0; 765 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){ 766 if ( k->sw > 0){ 767 const double znew=k->swz/k->sw; 768 const double tnew=k->swt/k->sw; 769 delta += std::pow(k->z-znew,2.) + std::pow(k->t-tnew,2.); 770 k->z = znew; 771 k->t = tnew; 772 k->Tc = 2*k->swE/k->sw; 773 }else{ 883 774 // cout << " a cluster melted away ? pk=" << k->pk << " sumw=" << k->sw << endl; 884 775 k->Tc = 0; 885 776 } 777 886 778 } 887 779 … … 896 788 // merge clusters that collapsed or never separated, return true if vertices were merged, false otherwise 897 789 898 if(y.size() < 2) return false; 899 900 for(vector<vertex_t>::iterator k = y.begin(); (k + 1) != y.end(); k++) 901 { 902 if(std::abs((k + 1)->z - k->z) < 1.e-3 && std::abs((k + 1)->t - k->t) < 1.e-3) 903 { // with fabs if only called after freeze-out (splitAll() at highter T) 904 double rho = k->pk + (k + 1)->pk; 905 if(rho > 0) 906 { 907 k->z = (k->pk * k->z + (k + 1)->z * (k + 1)->pk) / rho; 908 k->t = (k->pk * k->t + (k + 1)->t * (k + 1)->pk) / rho; 909 } 910 else 911 { 912 k->z = 0.5 * (k->z + (k + 1)->z); 913 k->t = 0.5 * (k->t + (k + 1)->t); 790 if(y.size()<2) return false; 791 792 for(vector<vertex_t>::iterator k=y.begin(); (k+1)!=y.end(); k++){ 793 if( std::abs( (k+1)->z - k->z ) < 1.e-3 && 794 std::abs( (k+1)->t - k->t ) < 1.e-3 ){ // with fabs if only called after freeze-out (splitAll() at highter T) 795 double rho = k->pk + (k+1)->pk; 796 if(rho>0){ 797 k->z = ( k->pk * k->z + (k+1)->z * (k+1)->pk)/rho; 798 k->t = ( k->pk * k->t + (k+1)->t * (k+1)->pk)/rho; 799 }else{ 800 k->z = 0.5*(k->z + (k+1)->z); 801 k->t = 0.5*(k->t + (k+1)->t); 914 802 } 915 803 k->pk = rho; 916 804 917 y.erase(k +1);805 y.erase(k+1); 918 806 return true; 919 807 } … … 930 818 // only merge if the estimated critical temperature of the merged vertex is below the current temperature 931 819 // return true if vertices were merged, false otherwise 932 if(y.size() < 2) return false; 933 934 for(vector<vertex_t>::iterator k = y.begin(); (k + 1) != y.end(); k++) 935 { 936 if(std::abs((k + 1)->z - k->z) < 2.e-3 && std::abs((k + 1)->t - k->t) < 2.e-3) 937 { 938 double rho = k->pk + (k + 1)->pk; 939 double swE = k->swE + (k + 1)->swE - k->pk * (k + 1)->pk / rho * (std::pow((k + 1)->z - k->z, 2.) + std::pow((k + 1)->t - k->t, 2.)); 940 double Tc = 2 * swE / (k->sw + (k + 1)->sw); 941 942 if(Tc * beta < 1) 943 { 944 if(rho > 0) 945 { 946 k->z = (k->pk * k->z + (k + 1)->z * (k + 1)->pk) / rho; 947 k->t = (k->pk * k->t + (k + 1)->t * (k + 1)->pk) / rho; 948 } 949 else 950 { 951 k->z = 0.5 * (k->z + (k + 1)->z); 952 k->t = 0.5 * (k->t + (k + 1)->t); 953 } 954 k->pk = rho; 955 k->sw += (k + 1)->sw; 956 k->swE = swE; 957 k->Tc = Tc; 958 y.erase(k + 1); 959 return true; 820 if(y.size()<2) return false; 821 822 for(vector<vertex_t>::iterator k=y.begin(); (k+1)!=y.end(); k++){ 823 if ( std::abs((k+1)->z - k->z) < 2.e-3 && 824 std::abs((k+1)->t - k->t) < 2.e-3 ) { 825 double rho=k->pk + (k+1)->pk; 826 double swE=k->swE+(k+1)->swE - k->pk * (k+1)->pk / rho * ( std::pow((k+1)->z - k->z,2.) + 827 std::pow((k+1)->t - k->t,2.) ); 828 double Tc=2*swE/(k->sw+(k+1)->sw); 829 830 if(Tc*beta<1){ 831 if(rho>0){ 832 k->z = ( k->pk * k->z + (k+1)->z * (k+1)->pk)/rho; 833 k->t = ( k->pk * k->t + (k+1)->t * (k+1)->pk)/rho; 834 }else{ 835 k->z = 0.5*(k->z + (k+1)->z); 836 k->t = 0.5*(k->t + (k+1)->t); 837 } 838 k->pk = rho; 839 k->sw += (k+1)->sw; 840 k->swE = swE; 841 k->Tc = Tc; 842 y.erase(k+1); 843 return true; 960 844 } 961 845 } … … 967 851 //------------------------------------------------------------------------------ 968 852 969 static bool purge(vector<vertex_t> &y, vector<track_t> &tks, double & rho0, const double beta, const double dzCutOff)853 static bool purge(vector<vertex_t> &y, vector<track_t> &tks, double & rho0, const double beta, const double dzCutOff) 970 854 { 971 855 // eliminate clusters with only one significant/unique track 972 if(y.size() < 2) return false; 973 974 unsigned int nt = tks.size(); 975 double sumpmin = nt; 976 vector<vertex_t>::iterator k0 = y.end(); 977 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); k++) 978 { 979 int nUnique = 0; 980 double sump = 0; 981 double pmax = k->pk / (k->pk + rho0 * exp(-beta * dzCutOff * dzCutOff)); 982 for(unsigned int i = 0; i < nt; i++) 983 { 984 if(tks[i].Z > 0) 985 { 986 double p = k->pk * std::exp(-beta * Eik(tks[i], *k)) / tks[i].Z; 987 sump += p; 988 if((p > 0.9 * pmax) && (tks[i].pi > 0)) 989 { 990 nUnique++; 991 } 856 if(y.size()<2) return false; 857 858 unsigned int nt=tks.size(); 859 double sumpmin=nt; 860 vector<vertex_t>::iterator k0=y.end(); 861 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){ 862 int nUnique=0; 863 double sump=0; 864 double pmax=k->pk/(k->pk+rho0*exp(-beta*dzCutOff*dzCutOff)); 865 for(unsigned int i=0; i<nt; i++){ 866 if(tks[i].Z > 0){ 867 double p = k->pk * std::exp(-beta*Eik(tks[i],*k)) / tks[i].Z ; 868 sump+=p; 869 if( (p > 0.9*pmax) && (tks[i].pi>0) ){ nUnique++; } 992 870 } 993 871 } 994 872 995 if((nUnique < 2) && (sump < sumpmin)) 996 { 997 sumpmin = sump; 998 k0 = k; 999 } 1000 } 1001 1002 if(k0 != y.end()) 1003 { 873 if((nUnique<2)&&(sump<sumpmin)){ 874 sumpmin=sump; 875 k0=k; 876 } 877 } 878 879 if(k0!=y.end()){ 1004 880 //cout << "eliminating prototype at " << k0->z << "," << k0->t << " with sump=" << sumpmin << endl; 1005 881 //rho0+=k0->pk; 1006 882 y.erase(k0); 1007 883 return true; 1008 } 1009 else 1010 { 884 }else{ 1011 885 return false; 1012 886 } … … 1018 892 { 1019 893 1020 double T0 = 0;// max Tc for beta=0894 double T0=0; // max Tc for beta=0 1021 895 // estimate critical temperature from beta=0 (T=inf) 1022 unsigned int nt = tks.size(); 1023 1024 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); k++) 1025 { 896 unsigned int nt=tks.size(); 897 898 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){ 1026 899 1027 900 // vertex fit at T=inf 1028 double sumwz = 0.; 1029 double sumwt = 0.; 1030 double sumw = 0.; 1031 for(unsigned int i = 0; i < nt; i++) 1032 { 1033 double w = tks[i].pi / (tks[i].dz2 * tks[i].dt2); 1034 sumwz += w * tks[i].z; 1035 sumwt += w * tks[i].t; 1036 sumw += w; 1037 } 1038 k->z = sumwz / sumw; 1039 k->t = sumwt / sumw; 901 double sumwz=0.; 902 double sumwt=0.; 903 double sumw=0.; 904 for(unsigned int i=0; i<nt; i++){ 905 double w = tks[i].pi/(tks[i].dz2 * tks[i].dt2); 906 sumwz += w*tks[i].z; 907 sumwt += w*tks[i].t; 908 sumw += w; 909 } 910 k->z = sumwz/sumw; 911 k->t = sumwt/sumw; 1040 912 1041 913 // estimate Tcrit, eventually do this in the same loop 1042 double a = 0, b = 0; 1043 for(unsigned int i = 0; i < nt; i++) 1044 { 1045 double dx = tks[i].z - (k->z); 1046 double dt = tks[i].t - (k->t); 1047 double w = tks[i].pi / (tks[i].dz2 * tks[i].dt2); 1048 a += w * (std::pow(dx, 2.) / tks[i].dz2 + std::pow(dt, 2.) / tks[i].dt2); 914 double a=0, b=0; 915 for(unsigned int i=0; i<nt; i++){ 916 double dx = tks[i].z-(k->z); 917 double dt = tks[i].t-(k->t); 918 double w = tks[i].pi/(tks[i].dz2 * tks[i].dt2); 919 a += w*(std::pow(dx,2.)/tks[i].dz2 + std::pow(dt,2.)/tks[i].dt2); 1049 920 b += w; 1050 921 } 1051 double Tc = 2. * a / b; // the critical temperature of this vertex 1052 if(Tc > T0) T0 = Tc; 1053 } // vertex loop (normally there should be only one vertex at beta=0) 1054 1055 if(T0 > 1. / betamax) 1056 { 1057 return betamax / pow(coolingFactor, int(std::log(T0 * betamax) / std::log(coolingFactor)) - 1); 1058 } 1059 else 1060 { 922 double Tc= 2.*a/b; // the critical temperature of this vertex 923 if(Tc>T0) T0=Tc; 924 }// vertex loop (normally there should be only one vertex at beta=0) 925 926 if (T0>1./betamax){ 927 return betamax/pow(coolingFactor, int(std::log(T0*betamax)/std::log(coolingFactor))-1 ); 928 }else{ 1061 929 // ensure at least one annealing step 1062 return betamax /coolingFactor;930 return betamax/coolingFactor; 1063 931 } 1064 932 } … … 1078 946 1079 947 std::vector<std::pair<double, unsigned int> > critical; 1080 for(unsigned int ik = 0; ik < y.size(); ik++) 1081 { 1082 if(beta * y[ik].Tc > 1.) 1083 { 1084 critical.push_back(make_pair(y[ik].Tc, ik)); 1085 } 1086 } 1087 std::stable_sort(critical.begin(), critical.end(), std::greater<std::pair<double, unsigned int> >()); 1088 1089 for(unsigned int ic = 0; ic < critical.size(); ic++) 1090 { 1091 unsigned int ik = critical[ic].second; 948 for(unsigned int ik=0; ik<y.size(); ik++){ 949 if (beta*y[ik].Tc > 1.){ 950 critical.push_back( make_pair(y[ik].Tc, ik)); 951 } 952 } 953 std::stable_sort(critical.begin(), critical.end(), std::greater<std::pair<double, unsigned int> >() ); 954 955 for(unsigned int ic=0; ic<critical.size(); ic++){ 956 unsigned int ik=critical[ic].second; 1092 957 // estimate subcluster positions and weight 1093 double p1 = 0, z1 = 0, t1 = 0, w1 =0;1094 double p2 = 0, z2 = 0, t2 = 0, w2 =0;958 double p1=0, z1=0, t1=0, w1=0; 959 double p2=0, z2=0, t2=0, w2=0; 1095 960 //double sumpi=0; 1096 for(unsigned int i = 0; i < tks.size(); i++) 1097 { 1098 if(tks[i].Z > 0) 1099 { 1100 //sumpi+=tks[i].pi; 1101 double p = y[ik].pk * exp(-beta * Eik(tks[i], y[ik])) / tks[i].Z * tks[i].pi; 1102 double w = p / (tks[i].dz2 * tks[i].dt2); 1103 if(tks[i].z < y[ik].z) 1104 { 1105 p1 += p; 1106 z1 += w * tks[i].z; 1107 t1 += w * tks[i].t; 1108 w1 += w; 1109 } 1110 else 1111 { 1112 p2 += p; 1113 z2 += w * tks[i].z; 1114 t2 += w * tks[i].t; 1115 w2 += w; 1116 } 961 for(unsigned int i=0; i<tks.size(); i++){ 962 if(tks[i].Z>0){ 963 //sumpi+=tks[i].pi; 964 double p=y[ik].pk * exp(-beta*Eik(tks[i],y[ik])) / tks[i].Z*tks[i].pi; 965 double w=p/(tks[i].dz2 * tks[i].dt2); 966 if(tks[i].z < y[ik].z){ 967 p1+=p; z1+=w*tks[i].z; t1+=w*tks[i].t; w1+=w; 968 }else{ 969 p2+=p; z2+=w*tks[i].z; t2+=w*tks[i].t; w2+=w; 970 } 1117 971 } 1118 972 } 1119 if(w1 > 0) 1120 { 1121 z1 = z1 / w1; 1122 t1 = t1 / w1; 1123 } 1124 else 1125 { 1126 z1 = y[ik].z - epsilon; 1127 t1 = y[ik].t - epsilon; 1128 } 1129 if(w2 > 0) 1130 { 1131 z2 = z2 / w2; 1132 t2 = t2 / w2; 1133 } 1134 else 1135 { 1136 z2 = y[ik].z + epsilon; 1137 t2 = y[ik].t + epsilon; 1138 } 973 if(w1>0){ z1=z1/w1; t1=t1/w1;} else{ z1=y[ik].z-epsilon; t1=y[ik].t-epsilon; } 974 if(w2>0){ z2=z2/w2; t2=t2/w2;} else{ z2=y[ik].z+epsilon; t2=y[ik].t+epsilon;} 1139 975 1140 976 // reduce split size if there is not enough room 1141 if((ik > 0) && (y[ik - 1].z >= z1)) 1142 { 1143 z1 = 0.5 * (y[ik].z + y[ik - 1].z); 1144 t1 = 0.5 * (y[ik].t + y[ik - 1].t); 1145 } 1146 if((ik + 1 < y.size()) && (y[ik + 1].z <= z2)) 1147 { 1148 z2 = 0.5 * (y[ik].z + y[ik + 1].z); 1149 t2 = 0.5 * (y[ik].t + y[ik + 1].t); 1150 } 977 if( ( ik > 0 ) && ( y[ik-1].z>=z1 ) ){ z1=0.5*(y[ik].z+y[ik-1].z); t1=0.5*(y[ik].t+y[ik-1].t); } 978 if( ( ik+1 < y.size()) && ( y[ik+1].z<=z2 ) ){ z2=0.5*(y[ik].z+y[ik+1].z); t2=0.5*(y[ik].t+y[ik+1].t); } 1151 979 1152 980 // split if the new subclusters are significantly separated 1153 if((z2 - z1) > epsilon || std::abs(t2 - t1) > epsilon) 1154 { 1155 split = true; 981 if( (z2-z1)>epsilon || std::abs(t2-t1) > epsilon){ 982 split=true; 1156 983 vertex_t vnew; 1157 vnew.pk = p1 * y[ik].pk / (p1 +p2);1158 y[ik].pk = p2 * y[ik].pk / (p1 +p2);1159 vnew.z = z1;1160 vnew.t = t1;984 vnew.pk = p1*y[ik].pk/(p1+p2); 985 y[ik].pk= p2*y[ik].pk/(p1+p2); 986 vnew.z = z1; 987 vnew.t = t1; 1161 988 y[ik].z = z2; 1162 989 y[ik].t = t2; 1163 y.insert(y.begin() + ik, vnew); 1164 1165 // adjust remaining pointers 1166 for(unsigned int jc = ic; jc < critical.size(); jc++) 1167 { 1168 if(critical[jc].second > ik) 1169 { 1170 critical[jc].second++; 1171 } 990 y.insert(y.begin()+ik, vnew); 991 992 // adjust remaining pointers 993 for(unsigned int jc=ic; jc<critical.size(); jc++){ 994 if (critical[jc].second>ik) {critical[jc].second++;} 1172 995 } 1173 996 } … … 1183 1006 { 1184 1007 1185 const double epsilon = 1e-3; // split all single vertices by 10 um 1186 const double zsep = 2 * epsilon; // split vertices that are isolated by at least zsep (vertices that haven't collapsed) 1187 const double tsep = 2 * epsilon; // check t as well 1008 1009 const double epsilon=1e-3; // split all single vertices by 10 um 1010 const double zsep=2*epsilon; // split vertices that are isolated by at least zsep (vertices that haven't collapsed) 1011 const double tsep=2*epsilon; // check t as well 1188 1012 1189 1013 vector<vertex_t> y1; 1190 1014 1191 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); k++) 1192 { 1193 if(((k == y.begin()) || (k - 1)->z < k->z - zsep) && (((k + 1) == y.end()) || (k + 1)->z > k->z + zsep)) 1194 { 1015 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){ 1016 if ( ( (k==y.begin())|| (k-1)->z < k->z - zsep) && (((k+1)==y.end() )|| (k+1)->z > k->z + zsep)) { 1195 1017 // isolated prototype, split 1196 1018 vertex_t vnew; 1197 vnew.z = k->z - epsilon;1198 vnew.t = k->t - epsilon;1199 (*k).z = k->z + epsilon;1200 (*k).t = k->t + epsilon;1201 vnew.pk = 0.5* (*k).pk;1202 (*k).pk = 0.5* (*k).pk;1019 vnew.z = k->z - epsilon; 1020 vnew.t = k->t - epsilon; 1021 (*k).z = k->z + epsilon; 1022 (*k).t = k->t + epsilon; 1023 vnew.pk= 0.5* (*k).pk; 1024 (*k).pk= 0.5* (*k).pk; 1203 1025 y1.push_back(vnew); 1204 1026 y1.push_back(*k); 1205 } 1206 else if(y1.empty() || (y1.back().z < k->z - zsep) || (y1.back().t < k->t - tsep)) 1207 { 1027 1028 }else if( y1.empty() || (y1.back().z < k->z -zsep) || (y1.back().t < k->t - tsep) ){ 1208 1029 y1.push_back(*k); 1209 } 1210 else 1211 { 1030 }else{ 1212 1031 y1.back().z -= epsilon; 1213 1032 y1.back().t -= epsilon; … … 1216 1035 y1.push_back(*k); 1217 1036 } 1218 } // vertex loop 1219 1220 y = y1; 1221 } 1037 }// vertex loop 1038 1039 y=y1; 1040 } 1041 1042 1043
Note:
See TracChangeset
for help on using the changeset viewer.