Fork me on GitHub

Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • modules/VertexFinderDA4D.cc

    r77e9ae1 r61569e0  
    77 */
    88
     9
    910#include "modules/VertexFinderDA4D.h"
    1011#include "classes/DelphesClasses.h"
     
    1314#include "classes/DelphesPileUpReader.h"
    1415
     16#include "ExRootAnalysis/ExRootResult.h"
     17#include "ExRootAnalysis/ExRootFilter.h"
    1518#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"
    1925#include "TDatabasePDG.h"
    20 #include "TFormula.h"
    2126#include "TLorentzVector.h"
    22 #include "TMath.h"
    2327#include "TMatrixT.h"
    24 #include "TObjArray.h"
    25 #include "TRandom3.h"
    26 #include "TString.h"
    2728#include "TVector3.h"
    2829
     30#include <utility>
    2931#include <algorithm>
     32#include <stdexcept>
    3033#include <iostream>
    31 #include <stdexcept>
    32 #include <utility>
    3334#include <vector>
    3435
    3536using namespace std;
    3637
    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;
     38static const Double_t mm  = 1.;
     39static const Double_t m = 1000.*mm;
     40static const Double_t ns  = 1.;
     41static const Double_t s = 1.e+9 *ns;
     42static const Double_t c_light   = 2.99792458e+8 * m/s;
    4243
    4344struct track_t
    4445{
    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)
     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)
    5051  Candidate *tt; // a pointer to the Candidate Track
    51   double Z; // Z[i]   for DA clustering
    52   double pi; // track weight
     52  double Z;      // Z[i]   for DA clustering
     53  double pi;     // track weight
    5354  double pt;
    5455  double eta;
     
    6061  double z;
    6162  double t;
    62   double pk; // vertex weight for "constrained" clustering
     63  double pk;     // vertex weight for "constrained" clustering
    6364  // --- temporary numbers, used during update
    6465  double ei;
     
    7576static double update1(double beta, std::vector<track_t> &tks, std::vector<vertex_t> &y);
    7677static 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);
     78static void dump(const double beta, const std::vector<vertex_t> & y, const std::vector<track_t> & tks);
    7879static bool merge(std::vector<vertex_t> &);
    7980static bool merge(std::vector<vertex_t> &, double &);
    80 static bool purge(std::vector<vertex_t> &, std::vector<track_t> &, double &, const double, const double);
     81static bool purge(std::vector<vertex_t> &, std::vector<track_t> & , double &, const double, const double);
    8182static void splitAll(std::vector<vertex_t> &y);
    8283static double beta0(const double betamax, std::vector<track_t> &tks, std::vector<vertex_t> &y, const double coolingFactor);
    8384static double Eik(const track_t &t, const vertex_t &k);
    8485
    85 static bool recTrackLessZ1(const track_t &tk1, const track_t &tk2)
     86static bool recTrackLessZ1(const track_t & tk1, const track_t & tk2)
    8687{
    8788  return tk1.z < tk2.z;
     
    114115  fVertexSpaceSize = GetDouble("VertexSpaceSize", 0.5); //in mm
    115116  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);
    119120  fCoolingFactor = GetDouble("CoolingFactor", 0.8);
    120121  fMaxIterations = GetInt("MaxIterations", 100);
    121   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
     122  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
    124125
    125126  // convert stuff in cm, ns
    126127  fVertexSpaceSize /= 10.0;
    127128  fVertexTimeSize *= 1E9;
    128   fDzCutOff /= 10.0; // Adaptive Fitter uses 3.0 but that appears to be a bit tight here sometimes
    129   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;
    130131
    131132  fInputArray = ImportArray(GetString("InputArray", "TrackSmearing/tracks"));
     
    156157
    157158  TLorentzVector pos, mom;
    158   if(fVerbose)
     159  if (fVerbose)
    159160  {
    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     }
     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     }
    171172  }
    172173
     
    174175  clusterize(*fInputArray, *ClusterArray);
    175176
    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;}
    180178
    181179  //loop over vertex candidates
    182180  ItClusterArray = ClusterArray->MakeIterator();
    183181  ItClusterArray->Reset();
    184   while((candidate = static_cast<Candidate *>(ItClusterArray->Next())))
     182  while((candidate = static_cast<Candidate*>(ItClusterArray->Next())))
    185183  {
    186184
    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){
     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){
    280278      sort(pvs.begin(), pvs.end(), VertexHigherPtSquared());
    281279    }
     
    283281
    284282  delete ClusterArray;
     283
    285284}
    286285
     
    289288void VertexFinderDA4D::clusterize(const TObjArray &tracks, TObjArray &clusters)
    290289{
    291   if(fVerbose)
    292   {
     290  if(fVerbose) {
    293291    cout << "###################################################" << endl;
    294     cout << "# VertexFinderDA4D::clusterize   nt=" << tracks.GetEntriesFast() << endl;
     292    cout << "# VertexFinderDA4D::clusterize   nt="<<tracks.GetEntriesFast() << endl;
    295293    cout << "###################################################" << endl;
    296294  }
    297295
    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;  }
    308300
    309301  // convert into vector of candidates
    310302  //TObjArray *ClusterArray = pv.begin()->GetCandidates();
    311303  //Candidate *aCluster = static_cast<Candidate*>(&(pv.at(0)));
    312   Candidate *aCluster = pv.at(0);
     304   Candidate *aCluster = pv.at(0);
    313305
    314306  // fill into clusters and merge
    315307
    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);
    327317      std::cout << ' ' << (*k)->Position.Z() << ' ' << (*k)->Position.T() << std::endl;
    328318    }
    329319
     320
    330321    // 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 ) {
    333324      // close a cluster
    334325      clusters.Add(aCluster);
     
    336327    }
    337328    //for(unsigned int i=0; i<k->GetCandidates().GetEntriesFast(); i++){
    338     aCluster = *k;
     329      aCluster = *k;
    339330    //}
     331
    340332  }
    341333  clusters.Add(aCluster);
    342334
    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
     341vector< Candidate* > VertexFinderDA4D::vertices()
    352342{
    353343  Candidate *candidate;
    354344  UInt_t clusterIndex = 0;
    355   vector<Candidate *> clusters;
     345  vector< Candidate* > clusters;
    356346
    357347  vector<track_t> tks;
     
    361351  // loop over input tracks
    362352  fItInputArray->Reset();
    363   while((candidate = static_cast<Candidate *>(fItInputArray->Next())))
     353  while((candidate = static_cast<Candidate*>(fItInputArray->Next())))
    364354  {
    365355    //TBC everything in cm
    366     z = candidate->DZ / 10;
     356    z = candidate->DZ/10;
    367357    tr.z = z;
    368     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
     358    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
    373363
    374364    // TBC: the time is in ns for now TBC
    375365    //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;
    378368    double pt = candidate->Momentum.Pt();
    379369    double eta = candidate->Momentum.Eta();
     
    385375    tr.t = t; //
    386376    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 time
    389     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)
    390380    {
    391381
    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
    396387    }
    397388    else
    398389    {
    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.;
    403394
    404395    // TBC now putting track selection here (> fPTMin)
     
    413404  if(fVerbose)
    414405  {
    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;
    417408    //loop over input tracks
    418409
    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;
     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;
    435426
    436427  vector<vertex_t> y; // the vertex prototypes
     
    438429  // initialize:single vertex at infinite temperature
    439430  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.;
    443434  y.push_back(vstart);
    444   int niter = 0; // number of iterations
     435  int niter=0;      // number of iterations
    445436
    446437  // 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)){ }
    452440
    453441  // 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;
    470451      splitAll(y);
    471452    }
    472453
    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){
    482460    // 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{
    501471    // 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);}
    511474  }
    512475
    513476  // 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
    528481
    529482  // 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
    538486
    539487  // 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
    566508
    567509  // select significant tracks and use a TransientVertex as a container
     
    569511
    570512  // 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++){
    582521
    583522    DelphesFactory *factory = GetFactory();
     
    593532    double expv_x2 = 0.;
    594533    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 ) ){
    603539          //std::cout << "pushing back " << i << ' ' << tks[i].tt << std::endl;
    604540          //vertexTracks.push_back(*(tks[i].tt)); tks[i].Z=0;
    605541
    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;
    612547        } // setting Z=0 excludes double assignment
    613548      }
    614549    }
    615550
    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;
    619554    const double crappy_error_guess = std::sqrt(time_var);
    620555    /*GlobalError dummyErrorWithTime(0,
     
    624559    //TransientVertex v(pos, time, dummyErrorWithTime, vertexTracks, 5);
    625560
    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);
    629564
    630565    // 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);
    632567
    633568    clusterIndex++;
     
    635570  }
    636571
     572
    637573  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
     579static 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;
    645582}
    646583
     
    651588  // copy and sort for nicer printout
    652589  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); }
    657591  std::stable_sort(tks.begin(), tks.end(), recTrackLessZ1);
    658592
     
    661595  cout << "                                                               z= ";
    662596  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++){
    665598    //cout  <<  setw(8) << fixed << k->z;
    666599  }
    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++){
    671602    //cout  <<  setw(8) << fixed << k->t;
    672603  }
    673604  //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++){
    676606    //cout  <<  setw(8) << fixed << k->Tc ;
    677607  }
    678608
    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++){
    684612    //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;
    690618  cout << endl;
    691619  cout << "----       z +/- dz        t +/- dt        ip +/-dip       pt    phi  eta    weights  ----" << endl;
    692620  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;
    701625    //cout <<  setw (3)<< i << ")" <<  setw (8) << fixed << setprecision(4)<<  tz << " +/-" <<  setw (6)<< sqrt(tks[i].dz2)
    702626    //     << setw(8) << fixed << setprecision(4) << tt << " +/-" << setw(6) << std::sqrt(tks[i].dt2)  ;
    703627
    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  }
    721643      }
    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;
    732647}
    733648
     
    740655  // returns the squared sum of changes of vertex positions
    741656
    742   unsigned int nt = tks.size();
     657  unsigned int nt=tks.size();
    743658
    744659  //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
    755666
    756667  // loop over tracks
    757   for(unsigned int i = 0; i < nt; i++)
    758   {
     668  for(unsigned int i=0; i<nt; i++){
    759669
    760670    // update pik and Zi
    761671    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;
    768677
    769678    // normalization for pk
    770     if(tks[i].Z > 0)
    771     {
     679    if (tks[i].Z>0){
    772680      sumpi += tks[i].pi;
    773681      // 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;
    780687        k->swt += w * tks[i].t;
    781         k->swE += w * Eik(tks[i], *k);
     688  k->swE += w * Eik(tks[i],*k);
    782689      }
    783     }
    784     else
    785     {
     690    }else{
    786691      sumpi += tks[i].pi;
    787692    }
    788693
     694
    789695  } // end of track loop
    790696
     697
    791698  // 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{
    806709      // cout << " a cluster melted away ?  pk=" << k->pk <<  " sumw=" << k->sw <<  endl
    807       k->Tc = -1;
     710      k->Tc=-1;
    808711    }
    809712
     
    822725  // returns the squared sum of changes of vertex positions
    823726
    824   unsigned int nt = tks.size();
     727  unsigned int nt=tks.size();
    825728
    826729  //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
    836735
    837736  // loop over tracks
    838   for(unsigned int i = 0; i < nt; i++)
    839   {
     737  for(unsigned int i=0; i<nt; i++){
    840738
    841739    // 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)
    843741    //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;
    850747
    851748    // 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;
    861756        k->swt += w * tks[i].t;
    862         k->swE += w * Eik(tks[i], *k);
     757  k->swE += w * Eik(tks[i],*k);
    863758      }
    864759    }
     
    867762
    868763  // 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{
    883774      // cout << " a cluster melted away ?  pk=" << k->pk <<  " sumw=" << k->sw <<  endl;
    884775      k->Tc = 0;
    885776    }
     777
    886778  }
    887779
     
    896788  // merge clusters that collapsed or never separated, return true if vertices were merged, false otherwise
    897789
    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);
    914802      }
    915803      k->pk = rho;
    916804
    917       y.erase(k + 1);
     805      y.erase(k+1);
    918806      return true;
    919807    }
     
    930818  // only merge if the estimated critical temperature of the merged vertex is below the current temperature
    931819  // 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;
    960844      }
    961845    }
     
    967851//------------------------------------------------------------------------------
    968852
    969 static bool purge(vector<vertex_t> &y, vector<track_t> &tks, double &rho0, const double beta, const double dzCutOff)
     853static bool purge(vector<vertex_t> &y, vector<track_t> &tks, double & rho0, const double beta, const double dzCutOff)
    970854{
    971855  // 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++; }
    992870      }
    993871    }
    994872
    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()){
    1004880    //cout << "eliminating prototype at " << k0->z << "," << k0->t << " with sump=" << sumpmin << endl;
    1005881    //rho0+=k0->pk;
    1006882    y.erase(k0);
    1007883    return true;
    1008   }
    1009   else
    1010   {
     884  }else{
    1011885    return false;
    1012886  }
     
    1018892{
    1019893
    1020   double T0 = 0; // max Tc for beta=0
     894  double T0=0; // max Tc for beta=0
    1021895  // 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++){
    1026899
    1027900    // 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;
    1040912
    1041913    // 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);
    1049920      b += w;
    1050921    }
    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{
    1061929    // ensure at least one annealing step
    1062     return betamax / coolingFactor;
     930    return betamax/coolingFactor;
    1063931  }
    1064932}
     
    1078946
    1079947  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;
    1092957    // 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;
    1095960    //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  }
    1117971      }
    1118972    }
    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;}
    1139975
    1140976    // 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); }
    1151979
    1152980    // 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;
    1156983      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;
    1161988      y[ik].z = z2;
    1162989      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++;}
    1172995      }
    1173996    }
     
    11831006{
    11841007
    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
    11881012
    11891013  vector<vertex_t> y1;
    11901014
    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)) {
    11951017      // isolated prototype, split
    11961018      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;
    12031025      y1.push_back(vnew);
    12041026      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) ){
    12081029      y1.push_back(*k);
    1209     }
    1210     else
    1211     {
     1030    }else{
    12121031      y1.back().z -= epsilon;
    12131032      y1.back().t -= epsilon;
     
    12161035      y1.push_back(*k);
    12171036    }
    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.