Fork me on GitHub

Changeset 341014c in git for modules/VertexFinderDA4D.cc


Ignore:
Timestamp:
Feb 12, 2019, 9:29:17 PM (6 years ago)
Author:
Pavel Demin <pavel-demin@…>
Branches:
ImprovedOutputFile, Timing, llp, master
Children:
6455202
Parents:
45e58be
Message:

apply .clang-format to all .h, .cc and .cpp files

File:
1 edited

Legend:

Unmodified
Added
Removed
  • modules/VertexFinderDA4D.cc

    r45e58be r341014c  
    77 */
    88
    9 
    109#include "modules/VertexFinderDA4D.h"
    1110#include "classes/DelphesClasses.h"
     
    1413#include "classes/DelphesPileUpReader.h"
    1514
     15#include "ExRootAnalysis/ExRootClassifier.h"
     16#include "ExRootAnalysis/ExRootFilter.h"
    1617#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"
    2022#include "TMath.h"
     23#include "TMatrixT.h"
     24#include "TObjArray.h"
     25#include "TRandom3.h"
    2126#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"
    2827#include "TVector3.h"
    2928
     29#include <algorithm>
     30#include <iostream>
     31#include <stdexcept>
    3032#include <utility>
    31 #include <algorithm>
    32 #include <stdexcept>
    33 #include <iostream>
    3433#include <vector>
    3534
    3635using namespace std;
    3736
    38 static const Double_t mm  = 1.;
    39 static const Double_t m = 1000.*mm;
    40 static const Double_t ns  = 1.;
    41 static const Double_t s = 1.e+9 *ns;
    42 static const Double_t c_light   = 2.99792458e+8 * m/s;
     37static const Double_t mm = 1.;
     38static const Double_t m = 1000. * mm;
     39static const Double_t ns = 1.;
     40static const Double_t s = 1.e+9 * ns;
     41static const Double_t c_light = 2.99792458e+8 * m / s;
    4342
    4443struct track_t
    4544{
    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)
     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)
    5150  Candidate *tt; // a pointer to the Candidate Track
    52   double Z;      // Z[i]   for DA clustering
    53   double pi;     // track weight
     51  double Z; // Z[i]   for DA clustering
     52  double pi; // track weight
    5453  double pt;
    5554  double eta;
     
    6160  double z;
    6261  double t;
    63   double pk;     // vertex weight for "constrained" clustering
     62  double pk; // vertex weight for "constrained" clustering
    6463  // --- temporary numbers, used during update
    6564  double ei;
     
    7675static double update1(double beta, std::vector<track_t> &tks, std::vector<vertex_t> &y);
    7776static 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);
     77static void dump(const double beta, const std::vector<vertex_t> &y, const std::vector<track_t> &tks);
    7978static bool merge(std::vector<vertex_t> &);
    8079static bool merge(std::vector<vertex_t> &, double &);
    81 static bool purge(std::vector<vertex_t> &, std::vector<track_t> & , double &, const double, const double);
     80static bool purge(std::vector<vertex_t> &, std::vector<track_t> &, double &, const double, const double);
    8281static void splitAll(std::vector<vertex_t> &y);
    8382static double beta0(const double betamax, std::vector<track_t> &tks, std::vector<vertex_t> &y, const double coolingFactor);
    8483static double Eik(const track_t &t, const vertex_t &k);
    8584
    86 static bool recTrackLessZ1(const track_t & tk1, const track_t & tk2)
     85static bool recTrackLessZ1(const track_t &tk1, const track_t &tk2)
    8786{
    8887  return tk1.z < tk2.z;
     
    115114  fVertexSpaceSize = GetDouble("VertexSpaceSize", 0.5); //in mm
    116115  fVertexTimeSize = GetDouble("VertexTimeSize", 10E-12); //in s
    117   fUseTc         = GetBool("UseTc", 1);
    118   fBetaMax       = GetDouble("BetaMax ", 0.1);
    119   fBetaStop      = GetDouble("BetaStop", 1.0);
     116  fUseTc = GetBool("UseTc", 1);
     117  fBetaMax = GetDouble("BetaMax ", 0.1);
     118  fBetaStop = GetDouble("BetaStop", 1.0);
    120119  fCoolingFactor = GetDouble("CoolingFactor", 0.8);
    121120  fMaxIterations = GetInt("MaxIterations", 100);
    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
     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
    125124
    126125  // convert stuff in cm, ns
    127126  fVertexSpaceSize /= 10.0;
    128127  fVertexTimeSize *= 1E9;
    129   fDzCutOff       /= 10.0;  // Adaptive Fitter uses 3.0 but that appears to be a bit tight here sometimes
    130   fD0CutOff       /= 10.0;
     128  fDzCutOff /= 10.0; // Adaptive Fitter uses 3.0 but that appears to be a bit tight here sometimes
     129  fD0CutOff /= 10.0;
    131130
    132131  fInputArray = ImportArray(GetString("InputArray", "TrackSmearing/tracks"));
     
    157156
    158157  TLorentzVector pos, mom;
    159   if (fVerbose)
    160   {
    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      }
     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    }
    172171  }
    173172
     
    175174  clusterize(*fInputArray, *ClusterArray);
    176175
    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  }
    178180
    179181  //loop over vertex candidates
    180182  ItClusterArray = ClusterArray->MakeIterator();
    181183  ItClusterArray->Reset();
    182   while((candidate = static_cast<Candidate*>(ItClusterArray->Next())))
    183   {
    184 
    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){
     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){
    278280      sort(pvs.begin(), pvs.end(), VertexHigherPtSquared());
    279281    }
     
    281283
    282284  delete ClusterArray;
    283 
    284285}
    285286
     
    288289void VertexFinderDA4D::clusterize(const TObjArray &tracks, TObjArray &clusters)
    289290{
    290   if(fVerbose) {
     291  if(fVerbose)
     292  {
    291293    cout << "###################################################" << endl;
    292     cout << "# VertexFinderDA4D::clusterize   nt="<<tracks.GetEntriesFast() << endl;
     294    cout << "# VertexFinderDA4D::clusterize   nt=" << tracks.GetEntriesFast() << endl;
    293295    cout << "###################################################" << endl;
    294296  }
    295297
    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  }
    300308
    301309  // convert into vector of candidates
    302310  //TObjArray *ClusterArray = pv.begin()->GetCandidates();
    303311  //Candidate *aCluster = static_cast<Candidate*>(&(pv.at(0)));
    304    Candidate *aCluster = pv.at(0);
     312  Candidate *aCluster = pv.at(0);
    305313
    306314  // fill into clusters and merge
    307315
    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);
    317327      std::cout << ' ' << (*k)->Position.Z() << ' ' << (*k)->Position.T() << std::endl;
    318328    }
    319329
    320 
    321330    // 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    {
    324333      // close a cluster
    325334      clusters.Add(aCluster);
     
    327336    }
    328337    //for(unsigned int i=0; i<k->GetCandidates().GetEntriesFast(); i++){
    329       aCluster = *k;
     338    aCluster = *k;
    330339    //}
    331 
    332340  }
    333341  clusters.Add(aCluster);
    334342
    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
     351vector<Candidate *> VertexFinderDA4D::vertices()
    342352{
    343353  Candidate *candidate;
    344354  UInt_t clusterIndex = 0;
    345   vector< Candidate* > clusters;
     355  vector<Candidate *> clusters;
    346356
    347357  vector<track_t> tks;
     
    351361  // loop over input tracks
    352362  fItInputArray->Reset();
    353   while((candidate = static_cast<Candidate*>(fItInputArray->Next())))
     363  while((candidate = static_cast<Candidate *>(fItInputArray->Next())))
    354364  {
    355365    //TBC everything in cm
    356     z = candidate->DZ/10;
     366    z = candidate->DZ / 10;
    357367    tr.z = z;
    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
     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
    363373
    364374    // TBC: the time is in ns for now TBC
    365375    //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;
    368378    double pt = candidate->Momentum.Pt();
    369379    double eta = candidate->Momentum.Eta();
     
    375385    tr.t = t; //
    376386    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
    387396    }
    388397    else
    389398    {
    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.;
    394403
    395404    // TBC now putting track selection here (> fPTMin)
     
    404413  if(fVerbose)
    405414  {
    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;
    408417    //loop over input tracks
    409418
    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;
     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;
    426435
    427436  vector<vertex_t> y; // the vertex prototypes
     
    429438  // initialize:single vertex at infinite temperature
    430439  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.;
    434443  y.push_back(vstart);
    435   int niter=0;      // number of iterations
     444  int niter = 0; // number of iterations
    436445
    437446  // 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  }
    440452
    441453  // 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;
    451470      splitAll(y);
    452471    }
    453472
    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  {
    460482    // 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  {
    471501    // 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    }
    474511  }
    475512
    476513  // 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  }
    481528
    482529  // 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  }
    486538
    487539  // 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  }
    508566
    509567  // select significant tracks and use a TransientVertex as a container
     
    511569
    512570  // 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  {
    521582
    522583    DelphesFactory *factory = GetFactory();
     
    532593    double expv_x2 = 0.;
    533594    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        {
    539603          //std::cout << "pushing back " << i << ' ' << tks[i].tt << std::endl;
    540604          //vertexTracks.push_back(*(tks[i].tt)); tks[i].Z=0;
    541605
    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;
    547612        } // setting Z=0 excludes double assignment
    548613      }
    549614    }
    550615
    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;
    554619    const double crappy_error_guess = std::sqrt(time_var);
    555620    /*GlobalError dummyErrorWithTime(0,
     
    559624    //TransientVertex v(pos, time, dummyErrorWithTime, vertexTracks, 5);
    560625
    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);
    564629
    565630    // 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);
    567632
    568633    clusterIndex++;
     
    570635  }
    571636
    572 
    573637  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
     642static 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;
    582645}
    583646
     
    588651  // copy and sort for nicer printout
    589652  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  }
    591657  std::stable_sort(tks.begin(), tks.end(), recTrackLessZ1);
    592658
     
    595661  cout << "                                                               z= ";
    596662  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  {
    598665    //cout  <<  setw(8) << fixed << k->z;
    599666  }
    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  {
    602671    //cout  <<  setw(8) << fixed << k->t;
    603672  }
    604673  //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  {
    606676    //cout  <<  setw(8) << fixed << k->Tc ;
    607677  }
    608678
    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  {
    612684    //cout <<  setw(8) <<  setprecision(3) <<  fixed << k->pk;
    613     sumpk+=k->pk;
    614   }
    615   cout  << endl;
    616 
    617   double E=0, F=0;
     685    sumpk += k->pk;
     686  }
     687  cout << endl;
     688
     689  double E = 0, F = 0;
    618690  cout << endl;
    619691  cout << "----       z +/- dz        t +/- dt        ip +/-dip       pt    phi  eta    weights  ----" << endl;
    620692  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;
    625701    //cout <<  setw (3)<< i << ")" <<  setw (8) << fixed << setprecision(4)<<  tz << " +/-" <<  setw (6)<< sqrt(tks[i].dz2)
    626702    //     << setw(8) << fixed << setprecision(4) << tt << " +/-" << setw(6) << std::sqrt(tks[i].dt2)  ;
    627703
    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;
    647732}
    648733
     
    655740  // returns the squared sum of changes of vertex positions
    656741
    657   unsigned int nt=tks.size();
     742  unsigned int nt = tks.size();
    658743
    659744  //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  }
    666755
    667756  // loop over tracks
    668   for(unsigned int i=0; i<nt; i++){
     757  for(unsigned int i = 0; i < nt; i++)
     758  {
    669759
    670760    // update pik and Zi
    671761    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;
    677768
    678769    // normalization for pk
    679     if (tks[i].Z>0){
     770    if(tks[i].Z > 0)
     771    {
    680772      sumpi += tks[i].pi;
    681773      // 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;
    687780        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    {
    691786      sumpi += tks[i].pi;
    692787    }
    693788
    694 
    695789  } // end of track loop
    696790
    697 
    698791  // 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    {
    709806      // cout << " a cluster melted away ?  pk=" << k->pk <<  " sumw=" << k->sw <<  endl
    710       k->Tc=-1;
     807      k->Tc = -1;
    711808    }
    712809
     
    725822  // returns the squared sum of changes of vertex positions
    726823
    727   unsigned int nt=tks.size();
     824  unsigned int nt = tks.size();
    728825
    729826  //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  }
    735836
    736837  // loop over tracks
    737   for(unsigned int i=0; i<nt; i++){
     838  for(unsigned int i = 0; i < nt; i++)
     839  {
    738840
    739841    // 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)
    741843    //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;
    747850
    748851    // 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;
    756861        k->swt += w * tks[i].t;
    757   k->swE += w * Eik(tks[i],*k);
     862        k->swE += w * Eik(tks[i], *k);
    758863      }
    759864    }
     
    762867
    763868  // 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    {
    774883      // cout << " a cluster melted away ?  pk=" << k->pk <<  " sumw=" << k->sw <<  endl;
    775884      k->Tc = 0;
    776885    }
    777 
    778886  }
    779887
     
    788896  // merge clusters that collapsed or never separated, return true if vertices were merged, false otherwise
    789897
    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);
    802914      }
    803915      k->pk = rho;
    804916
    805       y.erase(k+1);
     917      y.erase(k + 1);
    806918      return true;
    807919    }
     
    818930  // only merge if the estimated critical temperature of the merged vertex is below the current temperature
    819931  // 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;
    844960      }
    845961    }
     
    851967//------------------------------------------------------------------------------
    852968
    853 static bool purge(vector<vertex_t> &y, vector<track_t> &tks, double & rho0, const double beta, const double dzCutOff)
     969static bool purge(vector<vertex_t> &y, vector<track_t> &tks, double &rho0, const double beta, const double dzCutOff)
    854970{
    855971  // 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  {
    8801004    //cout << "eliminating prototype at " << k0->z << "," << k0->t << " with sump=" << sumpmin << endl;
    8811005    //rho0+=k0->pk;
    8821006    y.erase(k0);
    8831007    return true;
    884   }else{
     1008  }
     1009  else
     1010  {
    8851011    return false;
    8861012  }
     
    8921018{
    8931019
    894   double T0=0; // max Tc for beta=0
     1020  double T0 = 0; // max Tc for beta=0
    8951021  // 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  {
    8991026
    9001027    // 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;
    9121040
    9131041    // 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);
    9201049      b += w;
    9211050    }
    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  {
    9291061    // ensure at least one annealing step
    930     return betamax/coolingFactor;
     1062    return betamax / coolingFactor;
    9311063  }
    9321064}
     
    9451077  // avoid left-right biases by splitting highest Tc first
    9461078
    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;
    9571092    // 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;
    9601095    //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    }
    9751139
    9761140    // 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    }
    9791151
    9801152    // 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;
    9831156      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  = z1;
    987       vnew.t  = t1;
     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;
    9881161      y[ik].z = z2;
    9891162      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        }
    9951172      }
    9961173    }
     
    10061183{
    10071184
    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
    10121188
    10131189  vector<vertex_t> y1;
    10141190
    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    {
    10171195      // isolated prototype, split
    10181196      vertex_t vnew;
    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;
     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;
    10251203      y1.push_back(vnew);
    10261204      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    {
    10291208      y1.push_back(*k);
    1030     }else{
     1209    }
     1210    else
     1211    {
    10311212      y1.back().z -= epsilon;
    10321213      y1.back().t -= epsilon;
     
    10351216      y1.push_back(*k);
    10361217    }
    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.