Changeset 341014c in git for modules/VertexFinderDA4D.cc
- Timestamp:
- Feb 12, 2019, 9:29:17 PM (6 years ago)
- Branches:
- ImprovedOutputFile, Timing, llp, master
- Children:
- 6455202
- Parents:
- 45e58be
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
modules/VertexFinderDA4D.cc
r45e58be r341014c 7 7 */ 8 8 9 10 9 #include "modules/VertexFinderDA4D.h" 11 10 #include "classes/DelphesClasses.h" … … 14 13 #include "classes/DelphesPileUpReader.h" 15 14 15 #include "ExRootAnalysis/ExRootClassifier.h" 16 #include "ExRootAnalysis/ExRootFilter.h" 16 17 #include "ExRootAnalysis/ExRootResult.h" 17 #include "ExRootAnalysis/ExRootFilter.h" 18 #include "ExRootAnalysis/ExRootClassifier.h" 19 18 19 #include "TDatabasePDG.h" 20 #include "TFormula.h" 21 #include "TLorentzVector.h" 20 22 #include "TMath.h" 23 #include "TMatrixT.h" 24 #include "TObjArray.h" 25 #include "TRandom3.h" 21 26 #include "TString.h" 22 #include "TFormula.h"23 #include "TRandom3.h"24 #include "TObjArray.h"25 #include "TDatabasePDG.h"26 #include "TLorentzVector.h"27 #include "TMatrixT.h"28 27 #include "TVector3.h" 29 28 29 #include <algorithm> 30 #include <iostream> 31 #include <stdexcept> 30 32 #include <utility> 31 #include <algorithm>32 #include <stdexcept>33 #include <iostream>34 33 #include <vector> 35 34 36 35 using namespace std; 37 36 38 static const Double_t mm 39 static const Double_t m = 1000. *mm;40 static const Double_t ns 41 static const Double_t s = 1.e+9 * ns;42 static const Double_t c_light = 2.99792458e+8 * m/s;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 * ns; 41 static const Double_t c_light = 2.99792458e+8 * m / s; 43 42 44 43 struct track_t 45 44 { 46 double z; 47 double t; 48 double dz2; 49 double dtz; 50 double dt2; 45 double z; // z-coordinate at point of closest approach to the beamline 46 double t; // t-coordinate at point of closest approach to the beamline 47 double dz2; // square of the error of z(pca) 48 double dtz; // covariance of z-t 49 double dt2; // square of the error of t(pca) 51 50 Candidate *tt; // a pointer to the Candidate Track 52 double Z; 53 double pi; 51 double Z; // Z[i] for DA clustering 52 double pi; // track weight 54 53 double pt; 55 54 double eta; … … 61 60 double z; 62 61 double t; 63 double pk; 62 double pk; // vertex weight for "constrained" clustering 64 63 // --- temporary numbers, used during update 65 64 double ei; … … 76 75 static double update1(double beta, std::vector<track_t> &tks, std::vector<vertex_t> &y); 77 76 static double update2(double beta, std::vector<track_t> &tks, std::vector<vertex_t> &y, double &rho0, const double dzCutOff); 78 static void dump(const double beta, const std::vector<vertex_t> & y, const std::vector<track_t> &tks);77 static void dump(const double beta, const std::vector<vertex_t> &y, const std::vector<track_t> &tks); 79 78 static bool merge(std::vector<vertex_t> &); 80 79 static bool merge(std::vector<vertex_t> &, double &); 81 static bool purge(std::vector<vertex_t> &, std::vector<track_t> & 80 static bool purge(std::vector<vertex_t> &, std::vector<track_t> &, double &, const double, const double); 82 81 static void splitAll(std::vector<vertex_t> &y); 83 82 static double beta0(const double betamax, std::vector<track_t> &tks, std::vector<vertex_t> &y, const double coolingFactor); 84 83 static double Eik(const track_t &t, const vertex_t &k); 85 84 86 static bool recTrackLessZ1(const track_t & tk1, const track_t &tk2)85 static bool recTrackLessZ1(const track_t &tk1, const track_t &tk2) 87 86 { 88 87 return tk1.z < tk2.z; … … 115 114 fVertexSpaceSize = GetDouble("VertexSpaceSize", 0.5); //in mm 116 115 fVertexTimeSize = GetDouble("VertexTimeSize", 10E-12); //in s 117 fUseTc 118 fBetaMax 119 fBetaStop 116 fUseTc = GetBool("UseTc", 1); 117 fBetaMax = GetDouble("BetaMax ", 0.1); 118 fBetaStop = GetDouble("BetaStop", 1.0); 120 119 fCoolingFactor = GetDouble("CoolingFactor", 0.8); 121 120 fMaxIterations = GetInt("MaxIterations", 100); 122 fDzCutOff = GetDouble("DzCutOff", 40);// Adaptive Fitter uses 30 mm but that appears to be a bit tight here sometimes123 fD0CutOff 124 fDtCutOff = GetDouble("DtCutOff", 100E-12);// dummy121 fDzCutOff = GetDouble("DzCutOff", 40); // Adaptive Fitter uses 30 mm but that appears to be a bit tight here sometimes 122 fD0CutOff = GetDouble("D0CutOff", 30); 123 fDtCutOff = GetDouble("DtCutOff", 100E-12); // dummy 125 124 126 125 // convert stuff in cm, ns 127 126 fVertexSpaceSize /= 10.0; 128 127 fVertexTimeSize *= 1E9; 129 fDzCutOff /= 10.0;// Adaptive Fitter uses 3.0 but that appears to be a bit tight here sometimes130 fD0CutOff 128 fDzCutOff /= 10.0; // Adaptive Fitter uses 3.0 but that appears to be a bit tight here sometimes 129 fD0CutOff /= 10.0; 131 130 132 131 fInputArray = ImportArray(GetString("InputArray", "TrackSmearing/tracks")); … … 157 156 158 157 TLorentzVector pos, mom; 159 if 160 { 161 cout<<" start processing vertices ..."<<endl;162 cout<<" Found "<<fInputArray->GetEntriesFast()<<" input tracks"<<endl;163 164 165 while((candidate = static_cast<Candidate*>(fItInputArray->Next())))166 167 168 169 170 cout<<"pt: "<<mom.Pt()<<", eta: "<<mom.Eta()<<", phi: "<<mom.Phi()<<", z: "<<candidate->DZ/10<<endl;171 158 if(fVerbose) 159 { 160 cout << " start processing vertices ..." << endl; 161 cout << " Found " << fInputArray->GetEntriesFast() << " input tracks" << endl; 162 //loop over input tracks 163 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 } 172 171 } 173 172 … … 175 174 clusterize(*fInputArray, *ClusterArray); 176 175 177 if (fVerbose){std::cout << " clustering returned "<< ClusterArray->GetEntriesFast() << " clusters from " << fInputArray->GetEntriesFast() << " selected tracks" <<std::endl;} 176 if(fVerbose) 177 { 178 std::cout << " clustering returned " << ClusterArray->GetEntriesFast() << " clusters from " << fInputArray->GetEntriesFast() << " selected tracks" << std::endl; 179 } 178 180 179 181 //loop over vertex candidates 180 182 ItClusterArray = ClusterArray->MakeIterator(); 181 183 ItClusterArray->Reset(); 182 while((candidate = static_cast<Candidate *>(ItClusterArray->Next())))183 { 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 if(fVerbose)cout<<"this vertex has: "<<candidate->GetCandidates()->GetEntriesFast()<<" tracks"<<endl;200 201 202 203 204 205 while((track = static_cast<Candidate*>(it1.Next())))206 207 208 209 210 double t = track->InitialPosition.T()/c_light;211 double dt = track->ErrorT/c_light;212 213 const double inverr = 1.0/dt;214 meantime += time*inverr;215 expv_x2 += time*time*inverr;216 normw+= inverr;217 218 219 220 const double z = track->DZ/10.0;221 222 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 229 sumpt2 += pt*pt;230 231 232 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 245 246 247 248 249 250 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 loop269 270 271 if(fVerbose){272 273 274 275 276 277 184 while((candidate = static_cast<Candidate *>(ItClusterArray->Next()))) 185 { 186 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 vertex 204 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 TBC 212 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 TBC 221 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 tracks 234 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 loop 271 272 if(fVerbose) 273 { 274 std::cout << "PrimaryVertexProducerAlgorithm::vertices candidates =" << ClusterArray->GetEntriesFast() << std::endl; 275 } 276 277 //TBC maybe this can be done later 278 // sort vertices by pt**2 vertex (aka signal vertex tagging) 279 /*if(pvs.size()>1){ 278 280 sort(pvs.begin(), pvs.end(), VertexHigherPtSquared()); 279 281 } … … 281 283 282 284 delete ClusterArray; 283 284 285 } 285 286 … … 288 289 void VertexFinderDA4D::clusterize(const TObjArray &tracks, TObjArray &clusters) 289 290 { 290 if(fVerbose) { 291 if(fVerbose) 292 { 291 293 cout << "###################################################" << endl; 292 cout << "# VertexFinderDA4D::clusterize nt=" <<tracks.GetEntriesFast() << endl;294 cout << "# VertexFinderDA4D::clusterize nt=" << tracks.GetEntriesFast() << endl; 293 295 cout << "###################################################" << endl; 294 296 } 295 297 296 vector< Candidate* > pv = vertices(); 297 298 if(fVerbose){ cout << "# VertexFinderDA4D::clusterize pv.size="<<pv.size() << endl; } 299 if (pv.size()==0){ return; } 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 } 300 308 301 309 // convert into vector of candidates 302 310 //TObjArray *ClusterArray = pv.begin()->GetCandidates(); 303 311 //Candidate *aCluster = static_cast<Candidate*>(&(pv.at(0))); 304 312 Candidate *aCluster = pv.at(0); 305 313 306 314 // fill into clusters and merge 307 315 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); 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); 317 327 std::cout << ' ' << (*k)->Position.Z() << ' ' << (*k)->Position.T() << std::endl; 318 328 } 319 329 320 321 330 // TBC - check units here 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 ){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 { 324 333 // close a cluster 325 334 clusters.Add(aCluster); … … 327 336 } 328 337 //for(unsigned int i=0; i<k->GetCandidates().GetEntriesFast(); i++){ 329 338 aCluster = *k; 330 339 //} 331 332 340 } 333 341 clusters.Add(aCluster); 334 342 335 if(fVerbose) { std::cout << "# VertexFinderDA4D::clusterize clusters.size="<<clusters.GetEntriesFast() << std::endl; } 336 337 } 338 339 //------------------------------------------------------------------------------ 340 341 vector< Candidate* > VertexFinderDA4D::vertices() 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() 342 352 { 343 353 Candidate *candidate; 344 354 UInt_t clusterIndex = 0; 345 vector< Candidate*> clusters;355 vector<Candidate *> clusters; 346 356 347 357 vector<track_t> tks; … … 351 361 // loop over input tracks 352 362 fItInputArray->Reset(); 353 while((candidate = static_cast<Candidate *>(fItInputArray->Next())))363 while((candidate = static_cast<Candidate *>(fItInputArray->Next()))) 354 364 { 355 365 //TBC everything in cm 356 z = candidate->DZ /10;366 z = candidate->DZ / 10; 357 367 tr.z = z; 358 dz = candidate->ErrorDZ /10;359 tr.dz2 = dz *dz// track error360 //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 induced362 + fVertexSpaceSize*fVertexSpaceSize; // intrinsic vertex size, safer for outliers and short lived decays368 dz = candidate->ErrorDZ / 10; 369 tr.dz2 = dz * dz // track error 370 //TBC: beamspot size induced error, take 0 for now. 371 // + (std::pow(beamspot.BeamWidthX()*cos(phi),2.)+std::pow(beamspot.BeamWidthY()*sin(phi),2.))/std::pow(tantheta,2.) // beam-width induced 372 + fVertexSpaceSize * fVertexSpaceSize; // intrinsic vertex size, safer for outliers and short lived decays 363 373 364 374 // TBC: the time is in ns for now TBC 365 375 //t = candidate->Position.T()/c_light; 366 t = candidate->InitialPosition.T() /c_light;367 l = candidate->L /c_light;376 t = candidate->InitialPosition.T() / c_light; 377 l = candidate->L / c_light; 368 378 double pt = candidate->Momentum.Pt(); 369 379 double eta = candidate->Momentum.Eta(); … … 375 385 tr.t = t; // 376 386 tr.dtz = 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) 380 { 381 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 387 dt = candidate->ErrorT / c_light; 388 tr.dt2 = dt * dt + fVertexTimeSize * fVertexTimeSize; // the ~injected~ timing error plus a small minimum vertex size in time 389 if(fD0CutOff > 0) 390 { 391 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 387 396 } 388 397 else 389 398 { 390 tr.pi =1.;391 } 392 tr.tt =&(*candidate);393 tr.Z =1.;399 tr.pi = 1.; 400 } 401 tr.tt = &(*candidate); 402 tr.Z = 1.; 394 403 395 404 // TBC now putting track selection here (> fPTMin) … … 404 413 if(fVerbose) 405 414 { 406 std::cout <<" start processing vertices ..."<<std::endl;407 std::cout <<" Found "<<tks.size()<<" input tracks"<<std::endl;415 std::cout << " start processing vertices ..." << std::endl; 416 std::cout << " Found " << tks.size() << " input tracks" << std::endl; 408 417 //loop over input tracks 409 418 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 rejection424 425 if 419 for(std::vector<track_t>::const_iterator it = tks.begin(); it != tks.end(); it++) 420 { 421 double z = it->z; 422 double pt = it->pt; 423 double eta = it->eta; 424 double phi = it->phi; 425 double t = it->t; 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 rejection 433 434 if(tks.empty()) return clusters; 426 435 427 436 vector<vertex_t> y; // the vertex prototypes … … 429 438 // initialize:single vertex at infinite temperature 430 439 vertex_t vstart; 431 vstart.z =0.;432 vstart.t =0.;433 vstart.pk =1.;440 vstart.z = 0.; 441 vstart.t = 0.; 442 vstart.pk = 1.; 434 443 y.push_back(vstart); 435 int niter =0;// number of iterations444 int niter = 0; // number of iterations 436 445 437 446 // estimate first critical temperature 438 double beta=beta0(fBetaMax, tks, y, fCoolingFactor); 439 niter=0; while((update1(beta, tks,y)>1.e-6) && (niter++ < fMaxIterations)){ } 447 double beta = beta0(fBetaMax, tks, y, fCoolingFactor); 448 niter = 0; 449 while((update1(beta, tks, y) > 1.e-6) && (niter++ < fMaxIterations)) 450 { 451 } 440 452 441 453 // annealing loop, stop when T<Tmin (i.e. beta>1/Tmin) 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; 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; 451 470 splitAll(y); 452 471 } 453 472 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){ 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 { 460 482 // last round of splitting, make sure no critical clusters are left 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{ 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 { 471 501 // merge collapsed clusters 472 while(merge(y,beta)){update1(beta, tks,y);} 473 if(fVerbose ){ cout << "dump after 1st merging " << endl; dump(beta,y,tks);} 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 } 474 511 } 475 512 476 513 // switch on outlier rejection 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 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 } 481 528 482 529 // merge again (some cluster split by outliers collapse here) 483 while(merge(y)){} 484 if(fVerbose ){ cout << "dump after 2nd merging " << endl; dump(beta,y,tks);} 485 530 while(merge(y)) 531 { 532 } 533 if(fVerbose) 534 { 535 cout << "dump after 2nd merging " << endl; 536 dump(beta, y, tks); 537 } 486 538 487 539 // continue from freeze-out to Tstop (=1) without splitting, eliminate insignificant vertices 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 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 } 508 566 509 567 // select significant tracks and use a TransientVertex as a container … … 511 569 512 570 // ensure correct normalization of probabilities, should make double assginment reasonably impossible 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++){ 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 { 521 582 522 583 DelphesFactory *factory = GetFactory(); … … 532 593 double expv_x2 = 0.; 533 594 double normw = 0.; 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 ) ){ 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 { 539 603 //std::cout << "pushing back " << i << ' ' << tks[i].tt << std::endl; 540 604 //vertexTracks.push_back(*(tks[i].tt)); tks[i].Z=0; 541 605 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; 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; 547 612 } // setting Z=0 excludes double assignment 548 613 } 549 614 } 550 615 551 mean = mean /normw;552 expv_x2 = expv_x2 /normw;553 const double time_var = expv_x2 - mean *mean;616 mean = mean / normw; 617 expv_x2 = expv_x2 / normw; 618 const double time_var = expv_x2 - mean * mean; 554 619 const double crappy_error_guess = std::sqrt(time_var); 555 620 /*GlobalError dummyErrorWithTime(0, … … 559 624 //TransientVertex v(pos, time, dummyErrorWithTime, vertexTracks, 5); 560 625 561 562 candidate->ClusterIndex = clusterIndex++;;563 candidate->Position.SetXYZT(0.0, 0.0, z *10.0 , time*c_light);626 candidate->ClusterIndex = clusterIndex++; 627 ; 628 candidate->Position.SetXYZT(0.0, 0.0, z * 10.0, time * c_light); 564 629 565 630 // TBC - fill error later ... 566 candidate->PositionError.SetXYZT(0.0, 0.0, 0.0 , crappy_error_guess*c_light);631 candidate->PositionError.SetXYZT(0.0, 0.0, 0.0, crappy_error_guess * c_light); 567 632 568 633 clusterIndex++; … … 570 635 } 571 636 572 573 637 return clusters; 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; 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; 582 645 } 583 646 … … 588 651 // copy and sort for nicer printout 589 652 vector<track_t> tks; 590 for(vector<track_t>::const_iterator t=tks0.begin(); t!=tks0.end(); t++){tks.push_back(*t); } 653 for(vector<track_t>::const_iterator t = tks0.begin(); t != tks0.end(); t++) 654 { 655 tks.push_back(*t); 656 } 591 657 std::stable_sort(tks.begin(), tks.end(), recTrackLessZ1); 592 658 … … 595 661 cout << " z= "; 596 662 cout.precision(4); 597 for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){ 663 for(vector<vertex_t>::const_iterator k = y.begin(); k != y.end(); k++) 664 { 598 665 //cout << setw(8) << fixed << k->z; 599 666 } 600 cout << endl << " t= "; 601 for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){ 667 cout << endl 668 << " t= "; 669 for(vector<vertex_t>::const_iterator k = y.begin(); k != y.end(); k++) 670 { 602 671 //cout << setw(8) << fixed << k->t; 603 672 } 604 673 //cout << endl << "T=" << setw(15) << 1./beta <<" Tc= "; 605 for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){ 674 for(vector<vertex_t>::const_iterator k = y.begin(); k != y.end(); k++) 675 { 606 676 //cout << setw(8) << fixed << k->Tc ; 607 677 } 608 678 609 cout << endl << " pk="; 610 double sumpk=0; 611 for(vector<vertex_t>::const_iterator k=y.begin(); k!=y.end(); k++){ 679 cout << endl 680 << " pk="; 681 double sumpk = 0; 682 for(vector<vertex_t>::const_iterator k = y.begin(); k != y.end(); k++) 683 { 612 684 //cout << setw(8) << setprecision(3) << fixed << k->pk; 613 sumpk +=k->pk;614 } 615 cout 616 617 double E =0, F=0;685 sumpk += k->pk; 686 } 687 cout << endl; 688 689 double E = 0, F = 0; 618 690 cout << endl; 619 691 cout << "---- z +/- dz t +/- dt ip +/-dip pt phi eta weights ----" << endl; 620 692 cout.precision(4); 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; 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; 625 701 //cout << setw (3)<< i << ")" << setw (8) << fixed << setprecision(4)<< tz << " +/-" << setw (6)<< sqrt(tks[i].dz2) 626 702 // << setw(8) << fixed << setprecision(4) << tt << " +/-" << setw(6) << std::sqrt(tks[i].dt2) ; 627 703 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 } 643 } 644 cout << endl; 645 } 646 cout << endl << "T=" << 1/beta << " E=" << E << " n="<< y.size() << " F= " << F << endl << "----------" << endl; 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; 721 } 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; 647 732 } 648 733 … … 655 740 // returns the squared sum of changes of vertex positions 656 741 657 unsigned int nt =tks.size();742 unsigned int nt = tks.size(); 658 743 659 744 //initialize sums 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 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 } 666 755 667 756 // loop over tracks 668 for(unsigned int i=0; i<nt; i++){ 757 for(unsigned int i = 0; i < nt; i++) 758 { 669 759 670 760 // update pik and Zi 671 761 double Zi = 0.; 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; 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; 677 768 678 769 // normalization for pk 679 if (tks[i].Z>0){ 770 if(tks[i].Z > 0) 771 { 680 772 sumpi += tks[i].pi; 681 773 // accumulate weighted z and weights for vertex update 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; 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; 687 780 k->swt += w * tks[i].t; 688 k->swE += w * Eik(tks[i],*k); 689 } 690 }else{ 781 k->swE += w * Eik(tks[i], *k); 782 } 783 } 784 else 785 { 691 786 sumpi += tks[i].pi; 692 787 } 693 788 694 695 789 } // end of track loop 696 790 697 698 791 // now update z and pk 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{ 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 { 709 806 // cout << " a cluster melted away ? pk=" << k->pk << " sumw=" << k->sw << endl 710 k->Tc =-1;807 k->Tc = -1; 711 808 } 712 809 … … 725 822 // returns the squared sum of changes of vertex positions 726 823 727 unsigned int nt =tks.size();824 unsigned int nt = tks.size(); 728 825 729 826 //initialize sums 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 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 } 735 836 736 837 // loop over tracks 737 for(unsigned int i=0; i<nt; i++){ 838 for(unsigned int i = 0; i < nt; i++) 839 { 738 840 739 841 // update pik and Zi and Ti 740 double Zi = rho0 *std::exp(-beta*(dzCutOff*dzCutOff));// cut-off (eventually add finite size in time)842 double Zi = rho0 * std::exp(-beta * (dzCutOff * dzCutOff)); // cut-off (eventually add finite size in time) 741 843 //double Ti = 0.; // dt0*std::exp(-beta*fDtCutOff); 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; 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; 747 850 748 851 // normalization 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; 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; 756 861 k->swt += w * tks[i].t; 757 k->swE += w * Eik(tks[i],*k);862 k->swE += w * Eik(tks[i], *k); 758 863 } 759 864 } … … 762 867 763 868 // now update z 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{ 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 { 774 883 // cout << " a cluster melted away ? pk=" << k->pk << " sumw=" << k->sw << endl; 775 884 k->Tc = 0; 776 885 } 777 778 886 } 779 887 … … 788 896 // merge clusters that collapsed or never separated, return true if vertices were merged, false otherwise 789 897 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); 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); 802 914 } 803 915 k->pk = rho; 804 916 805 y.erase(k +1);917 y.erase(k + 1); 806 918 return true; 807 919 } … … 818 930 // only merge if the estimated critical temperature of the merged vertex is below the current temperature 819 931 // return true if vertices were merged, false otherwise 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; 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; 844 960 } 845 961 } … … 851 967 //------------------------------------------------------------------------------ 852 968 853 static bool purge(vector<vertex_t> &y, vector<track_t> &tks, double & 969 static bool purge(vector<vertex_t> &y, vector<track_t> &tks, double &rho0, const double beta, const double dzCutOff) 854 970 { 855 971 // eliminate clusters with only one significant/unique track 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++; } 870 } 871 } 872 873 if((nUnique<2)&&(sump<sumpmin)){ 874 sumpmin=sump; 875 k0=k; 876 } 877 } 878 879 if(k0!=y.end()){ 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 } 992 } 993 } 994 995 if((nUnique < 2) && (sump < sumpmin)) 996 { 997 sumpmin = sump; 998 k0 = k; 999 } 1000 } 1001 1002 if(k0 != y.end()) 1003 { 880 1004 //cout << "eliminating prototype at " << k0->z << "," << k0->t << " with sump=" << sumpmin << endl; 881 1005 //rho0+=k0->pk; 882 1006 y.erase(k0); 883 1007 return true; 884 }else{ 1008 } 1009 else 1010 { 885 1011 return false; 886 1012 } … … 892 1018 { 893 1019 894 double T0 =0;// max Tc for beta=01020 double T0 = 0; // max Tc for beta=0 895 1021 // estimate critical temperature from beta=0 (T=inf) 896 unsigned int nt=tks.size(); 897 898 for(vector<vertex_t>::iterator k=y.begin(); k!=y.end(); k++){ 1022 unsigned int nt = tks.size(); 1023 1024 for(vector<vertex_t>::iterator k = y.begin(); k != y.end(); k++) 1025 { 899 1026 900 1027 // vertex fit at T=inf 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; 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; 912 1040 913 1041 // estimate Tcrit, eventually do this in the same loop 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); 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); 920 1049 b += w; 921 1050 } 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{ 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 { 929 1061 // ensure at least one annealing step 930 return betamax /coolingFactor;1062 return betamax / coolingFactor; 931 1063 } 932 1064 } … … 945 1077 // avoid left-right biases by splitting highest Tc first 946 1078 947 std::vector<std::pair<double, unsigned int> > critical; 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; 1079 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; 957 1092 // estimate subcluster positions and weight 958 double p1 =0, z1=0, t1=0, w1=0;959 double p2 =0, z2=0, t2=0, w2=0;1093 double p1 = 0, z1 = 0, t1 = 0, w1 = 0; 1094 double p2 = 0, z2 = 0, t2 = 0, w2 = 0; 960 1095 //double sumpi=0; 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 } 971 } 972 } 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;} 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 } 1117 } 1118 } 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 } 975 1139 976 1140 // reduce split size if there is not enough room 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); } 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 } 979 1151 980 1152 // split if the new subclusters are significantly separated 981 if( (z2-z1)>epsilon || std::abs(t2-t1) > epsilon){ 982 split=true; 1153 if((z2 - z1) > epsilon || std::abs(t2 - t1) > epsilon) 1154 { 1155 split = true; 983 1156 vertex_t vnew; 984 vnew.pk = p1 *y[ik].pk/(p1+p2);985 y[ik].pk = p2*y[ik].pk/(p1+p2);986 vnew.z 987 vnew.t 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; 988 1161 y[ik].z = z2; 989 1162 y[ik].t = t2; 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++;} 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 } 995 1172 } 996 1173 } … … 1006 1183 { 1007 1184 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 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 1012 1188 1013 1189 vector<vertex_t> y1; 1014 1190 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)) { 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 { 1017 1195 // isolated prototype, split 1018 1196 vertex_t vnew; 1019 vnew.z 1020 vnew.t 1021 (*k).z 1022 (*k).t 1023 vnew.pk = 0.5* (*k).pk;1024 (*k).pk = 0.5* (*k).pk;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; 1025 1203 y1.push_back(vnew); 1026 1204 y1.push_back(*k); 1027 1028 }else if( y1.empty() || (y1.back().z < k->z -zsep) || (y1.back().t < k->t - tsep) ){ 1205 } 1206 else if(y1.empty() || (y1.back().z < k->z - zsep) || (y1.back().t < k->t - tsep)) 1207 { 1029 1208 y1.push_back(*k); 1030 }else{ 1209 } 1210 else 1211 { 1031 1212 y1.back().z -= epsilon; 1032 1213 y1.back().t -= epsilon; … … 1035 1216 y1.push_back(*k); 1036 1217 } 1037 }// vertex loop 1038 1039 y=y1; 1040 } 1041 1042 1043 1218 } // vertex loop 1219 1220 y = y1; 1221 }
Note:
See TracChangeset
for help on using the changeset viewer.