11 #include "vdt/vdtMath.h" 32 coolingFactor_ = conf.
getParameter<
double> (
"coolingFactor");
35 coolingFactor_=-coolingFactor_;
40 uniquetrkweight_ = conf.
getParameter<
double>(
"uniquetrkweight");
44 std::cout <<
"DAClusterizerinZ_vect: mintrkweight = " << mintrkweight_ << std::endl;
45 std::cout <<
"DAClusterizerinZ_vect: uniquetrkweight = " << uniquetrkweight_ << std::endl;
46 std::cout <<
"DAClusterizerinZ_vect: zmerge = " << zmerge_ << std::endl;
47 std::cout <<
"DAClusterizerinZ_vect: Tmin = " << Tmin << std::endl;
48 std::cout <<
"DAClusterizerinZ_vect: Tpurge = " << Tpurge << std::endl;
49 std::cout <<
"DAClusterizerinZ_vect: Tstop = " << Tstop << std::endl;
50 std::cout <<
"DAClusterizerinZ_vect: vertexSize = " << vertexSize_ << std::endl;
51 std::cout <<
"DAClusterizerinZ_vect: coolingFactor = " << coolingFactor_ << std::endl;
52 std::cout <<
"DAClusterizerinZ_vect: d0CutOff = " << d0CutOff_ << std::endl;
53 std::cout <<
"DAClusterizerinZ_vect: dzCutOff = " << dzCutOff_ << std::endl;
58 edm::LogWarning(
"DAClusterizerinZ_vectorized") <<
"DAClusterizerInZ: invalid Tmin" << Tmin
59 <<
" reset do default " << 1. / betamax_;
65 if ((Tpurge > Tmin) || (Tpurge == 0)) {
66 edm::LogWarning(
"DAClusterizerinZ_vectorized") <<
"DAClusterizerInZ: invalid Tpurge" << Tpurge
67 <<
" set to " <<
Tmin;
73 if ((Tstop > Tpurge) || (Tstop == 0)) {
74 edm::LogWarning(
"DAClusterizerinZ_vectorized") <<
"DAClusterizerInZ: invalid Tstop" << Tstop
75 <<
" set to " <<
max(1., Tpurge);
76 Tstop =
max(1., Tpurge) ;
84 inline double local_exp(
double const& inp) {
85 return vdt::fast_exp( inp );
88 inline void local_exp_list(
double const * __restrict__ arg_inp,
double * __restrict__ arg_out,
const int arg_arr_size) {
89 for(
int i=0;
i!=arg_arr_size; ++
i ) arg_out[
i]=vdt::fast_exp(arg_inp[
i]);
100 for (
auto it = tracks.begin(); it!= tracks.end(); it++){
101 if (!(*it).isValid())
continue;
103 double t_z = ((*it).stateAtBeamLine().trackStateAtPCA()).
position().z();
104 if (std::fabs(t_z) > 1000.)
continue;
105 auto const & t_mom = (*it).stateAtBeamLine().trackStateAtPCA().momentum();
109 std::pow((*it).track().dzError(), 2)
116 (*it).stateAtBeamLine().transverseImpactParameter();
120 LogTrace(
"DAClusterizerinZ_vectorized") << t_z <<
' '<< t_dz2 <<
' '<< t_pi;
121 tks.
AddItem(t_z, t_dz2, &(*it), t_pi);
135 double Eik(
double t_z,
double k_z,
double t_dz2) {
136 return std::pow(t_z - k_z, 2) * t_dz2;
141 vertex_t & gvertices,
bool useRho0,
const double & rho0)
const {
147 const unsigned int nt = gtracks.
GetSize();
148 const unsigned int nv = gvertices.
GetSize();
162 Z_init = rho0 * local_exp(-beta * dzCutOff_ * dzCutOff_);
166 auto kernel_calc_exp_arg = [
beta, nv ] (
const unsigned int itrack,
169 const double track_z = tracks._z[itrack];
170 const double botrack_dz2 = -beta*tracks._dz2[itrack];
173 for (
unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
174 auto mult_res = track_z -
vertices._z[ivertex];
175 vertices._ei_cache[ivertex] = botrack_dz2 * ( mult_res * mult_res );
181 double ZTemp = Z_init;
182 for (
unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
188 auto kernel_calc_normalization = [
beta, nv ] (
const unsigned int track_num,
191 auto tmp_trk_pi = tks_vec._pi[track_num];
192 auto o_trk_Z_sum = 1./tks_vec._Z_sum[track_num];
193 auto o_trk_dz2 = tks_vec._dz2[track_num];
194 auto tmp_trk_z = tks_vec._z[track_num];
195 auto obeta = -1./
beta;
198 for (
unsigned int k = 0;
k < nv; ++
k) {
199 y_vec._se[
k] += y_vec._ei[
k] * (tmp_trk_pi* o_trk_Z_sum);
200 auto w = y_vec._pk[
k] * y_vec._ei[
k] * (tmp_trk_pi*o_trk_Z_sum *o_trk_dz2);
202 y_vec._swz[
k] +=
w * tmp_trk_z;
203 y_vec._swE[
k] +=
w * y_vec._ei_cache[
k]*obeta;
208 for (
auto ivertex = 0
U; ivertex < nv; ++ivertex) {
209 gvertices.
_se[ivertex] = 0.0;
210 gvertices.
_sw[ivertex] = 0.0;
211 gvertices.
_swz[ivertex] = 0.0;
212 gvertices.
_swE[ivertex] = 0.0;
218 for (
auto itrack = 0
U; itrack <
nt; ++itrack) {
219 kernel_calc_exp_arg(itrack, gtracks, gvertices);
222 gtracks.
_Z_sum[itrack] = kernel_add_Z(gvertices);
225 sumpi += gtracks.
_pi[itrack];
227 if (gtracks.
_Z_sum[itrack] > 1.e-100){
228 kernel_calc_normalization(itrack, gtracks, gvertices);
233 auto kernel_calc_z = [ sumpi, nv,
this, useRho0 ] (
vertex_t &
vertices ) ->
double {
237 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex ) {
247 if (this->verbose_) {
248 std::cout <<
" a cluster melted away ? pk=" <<
vertices._pk[ ivertex ] <<
" sumw=" 255 auto osumpi = 1./sumpi;
256 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex )
262 delta += kernel_calc_z(gvertices);
276 const unsigned int nv = y.
GetSize();
282 std::vector<std::pair<double, unsigned int> > critical;
283 for (
unsigned int k = 0; (
k + 1) < nv;
k++) {
284 if (std::fabs(y.
_z[
k + 1] - y.
_z[
k]) < zmerge_) {
285 critical.push_back( make_pair( std::fabs(y.
_z[
k + 1] - y.
_z[
k]),
k) );
288 if (critical.size() == 0)
return false;
290 std::stable_sort(critical.begin(), critical.end(), std::less<std::pair<double, unsigned int> >() );
293 for (
unsigned int ik=0; ik < critical.size(); ik++){
294 unsigned int k = critical[ik].second;
295 double rho = y.
_pk[
k]+y.
_pk[k+1];
297 double Tc = 2*swE / (y.
_sw[
k]+y.
_sw[k+1]);
300 if(verbose_){
std::cout <<
"merging " << y.
_z[k + 1] <<
" and " << y.
_z[
k] <<
" Tc = " << Tc <<
" sw = " << y.
_sw[
k]+y.
_sw[k+1] <<std::endl;}
304 y.
_z[
k] = 0.5 * (y.
_z[
k] + y.
_z[k + 1]);
323 const unsigned int nv = y.
GetSize();
330 unsigned int k0 = nv;
332 for (
unsigned int k = 0;
k < nv;
k++) {
337 double pmax = y.
_pk[
k] / (y.
_pk[
k] + rho0 * local_exp(-beta * dzCutOff_* dzCutOff_));
338 for (
unsigned int i = 0;
i <
nt;
i++) {
342 if ((p > uniquetrkweight_ * pmax) && (tks.
_pi[
i] > 0)) {
348 if ((nUnique < 2) && (sump < sumpmin)) {
357 std::cout <<
"eliminating prototype at " << std::setw(10) << std::setprecision(4) << y.
_z[
k0]
358 <<
" with sump=" << sumpmin
359 <<
" rho*nt =" << y.
_pk[
k0]*nt
378 const unsigned int nv = y.
GetSize();
380 for (
unsigned int k = 0;
k < nv;
k++) {
385 for (
unsigned int i = 0;
i <
nt;
i++) {
387 sumwz += w * tks.
_z[
i];
390 y.
_z[
k] = sumwz / sumw;
394 for (
unsigned int i = 0;
i <
nt;
i++) {
395 double dx = tks.
_z[
i] - y.
_z[
k];
400 double Tc = 2. * a /
b;
401 if (Tc > T0) T0 = Tc;
405 std::cout <<
"DAClustrizerInZ_vect.beta0: Tc = " << T0 << std::endl;
407 std::cout <<
"DAClustrizerInZ_vect.beta0: nstep = " << coolingsteps << std::endl;
411 if (T0 > 1. / betamax) {
415 return betamax * coolingFactor_;
432 std::vector<std::pair<double, unsigned int> > critical;
433 for(
unsigned int k=0;
k<nv;
k++){
435 if (beta*Tc > threshold){
436 critical.push_back( make_pair(Tc,
k));
439 if (critical.size()==0)
return false;
442 std::stable_sort(critical.begin(), critical.end(), std::greater<std::pair<double, unsigned int> >() );
448 for(
unsigned int ic=0; ic<critical.size(); ic++){
449 unsigned int k=critical[ic].second;
452 double p1=0, z1=0, w1=0;
453 double p2=0, z2=0,
w2=0;
454 for(
unsigned int i=0;
i<
nt;
i++){
458 double tl = tks.
_z[
i] < y.
_z[
k] ? 1.: 0.;
463 if(std::fabs(arg) < 20){
464 double t = local_exp(-arg);
471 p1 += p*tl ; z1 += w*tl*tks.
_z[
i]; w1 += w*tl;
472 p2 += p*tr; z2 += w*tr*tks.
_z[
i];
w2 += w*tr;
476 if(w1>0){z1 = z1/w1;}
else {z1=y.
_z[
k]-
epsilon;}
480 if( ( k > 0 ) && ( z1 < (0.6*y.
_z[k] + 0.4*y.
_z[k-1])) ){ z1 = 0.6*y.
_z[
k] + 0.4*y.
_z[k-1]; }
481 if( ( k+1 < nv) && ( z2 > (0.6*y.
_z[k] + 0.4*y.
_z[k+1])) ){ z2 = 0.6*y.
_z[
k] + 0.4*y.
_z[k+1]; }
484 if (std::fabs(y.
_z[k] - zdumpcenter_) < zdumpwidth_){
485 std::cout <<
" T= " << std::setw(8) << 1./beta
486 <<
" Tc= " << critical[ic].first
487 <<
" splitting " <<
std::fixed << std::setprecision(4) << y.
_z[
k]
488 <<
" --> " << z1 <<
"," << z2
489 <<
" [" << p1 <<
"," << p2 <<
"]" ;
490 if (std::fabs(z2-z1)>epsilon){
499 if( (z2-z1) > epsilon){
501 double pk1 = p1*y.
_pk[
k]/(p1+
p2);
502 double pk2 = p2*y.
_pk[
k]/(p1+
p2);
509 for(
unsigned int jc=ic; jc < critical.size(); jc++){
510 if (critical[jc].
second > k) {critical[jc].second++;}
521 const unsigned int nv = y.
GetSize();
528 std::cout <<
"Before Split "<< std::endl;
532 for (
unsigned int k = 0;
k < nv;
k++) {
534 ( (
k == 0) || ( y.
_z[
k - 1] < (y.
_z[
k] - zsep)) ) &&
535 ( ((
k + 1) == nv) || ( y.
_z[
k + 1] > (y.
_z[
k] + zsep)) ) )
541 double new_pk = 0.5 * y.
pk[
k];
547 else if ( (y1.
GetSize() == 0 ) ||
564 std::cout <<
"After split " << std::endl;
571 vector<TransientVertex>
580 if (tks.
GetSize() == 0)
return clusters;
591 double beta = beta0(betamax_, tks, y);
592 if ( verbose_)
std::cout <<
"Beta0 is " << beta << std::endl;
595 while ((
update(beta, tks, y,
false, rho0) > 1.
e-6) &&
596 (niter++ < maxIterations_)) {}
600 double betafreeze = betamax_ *
sqrt(coolingFactor_);
602 while (beta < betafreeze) {
604 update(beta, tks,y,
false, rho0);
605 while(
merge(y, beta)){
update(beta, tks, y,
false, rho0);}
607 beta=beta/coolingFactor_;
609 beta=beta/coolingFactor_;
615 while ((
update(beta, tks, y,
false, rho0) > 1.
e-6) &&
616 (niter++ < maxIterations_)) {}
618 if(verbose_){
dump( beta, y, tks, 0); }
624 if(verbose_){
std::cout <<
"last spliting at " << 1./beta << std::endl; }
625 update(beta, tks,y,
false, rho0);
626 while(
merge(y,beta)){
update(beta, tks,y,
false, rho0);}
629 while(
split(beta, tks, y, threshold) && (ntry++<10) ){
631 while((
update(beta, tks,y,
false, rho0)>1.
e-6) && (niter++ < maxIterations_)){}
632 while(
merge(y,beta)){
update(beta, tks,y,
false, rho0);}
634 std::cout <<
"after final splitting, try " << ntry << std::endl;
635 dump(beta, y, tks, 2);
642 while(
merge(y,beta)){
update(beta, tks,y,
false, rho0);}
646 update(beta, tks,y,
false, rho0);
647 std::cout <<
"dump after 1st merging " << endl;
648 dump(beta, y, tks, 2);
655 for(
unsigned int a=0;
a<10;
a++){
update(beta, tks, y,
true,
a*rho0/10);}
659 while ((
update(beta, tks, y,
true, rho0) > 1.
e-8) && (niter++ < maxIterations_)) {};
661 std::cout <<
"dump after noise-suppression, rho0=" << rho0 <<
" niter = " << niter << endl;
662 dump(beta, y, tks, 2);
666 while (
merge(y, beta)) {
update(beta, tks, y,
true, rho0); }
668 std::cout <<
"dump after merging " << endl;
669 dump(beta, y, tks, 2);
673 while( beta < betapurge_ ){
674 beta =
min( beta/coolingFactor_, betapurge_);
676 while ((
update(beta, tks, y,
false, rho0) > 1.
e-8) && (niter++ < maxIterations_)) {}
681 while (purge(y, tks, rho0, beta)) {
683 while ((
update(beta, tks, y,
true, rho0) > 1.
e-6) && (niter++ < maxIterations_)) {}
687 update(beta, tks,y,
true, rho0);
688 std::cout <<
" after purging " << std:: endl;
689 dump(beta, y, tks, 2);
693 while( beta < betastop_ ){
694 beta =
min( beta/coolingFactor_, betastop_);
696 while ((
update(beta, tks, y,
true, rho0) > 1.
e-8) && (niter++ < maxIterations_)) {}
701 std::cout <<
"Final result, rho0=" << std::scientific << rho0 << endl;
702 dump(beta, y, tks, 2);
706 GlobalError dummyError(0.01, 0, 0.01, 0., 0., 0.01);
709 const unsigned int nv = y.
GetSize();
710 for (
unsigned int k = 0;
k < nv;
k++)
713 for (
unsigned int i = 0;
i <
nt;
i++)
714 tks.
_Z_sum[
i] = rho0 * local_exp(-beta * dzCutOff_ * dzCutOff_);
717 for (
unsigned int k = 0;
k < nv;
k++) {
718 for (
unsigned int i = 0;
i <
nt;
i++)
723 for (
unsigned int k = 0;
k < nv;
k++) {
726 vector<reco::TransientTrack> vertexTracks;
727 for (
unsigned int i = 0;
i <
nt;
i++) {
730 double p = y.
_pk[
k] * local_exp(-beta * Eik(tks.
_z[
i], y.
_z[
k],
732 if ((tks.
_pi[
i] > 0) && (p > mintrkweight_)) {
733 vertexTracks.push_back(*(tks.
tt[
i]));
739 clusters.push_back(v);
747 const vector<reco::TransientTrack> &
tracks)
const {
750 std::cout <<
"###################################################" << endl;
751 std::cout <<
"# vectorized DAClusterizerInZ_vect::clusterize nt=" << tracks.size() << endl;
752 std::cout <<
"###################################################" << endl;
755 vector<vector<reco::TransientTrack> >
clusters;
756 vector<TransientVertex> &&
pv =
vertices(tracks);
759 std::cout <<
"# DAClusterizerInZ::clusterize pv.size=" << pv.size()
762 if (pv.size() == 0) {
767 vector<reco::TransientTrack> aCluster = pv.begin()->originalTracks();
769 for (
auto k = pv.begin() + 1;
k != pv.end();
k++) {
772 if (aCluster.size()>1){
773 clusters.push_back(aCluster);
776 std::cout <<
" one track cluster at " <<
k->position().z() <<
" suppressed" << std::endl;
781 for (
unsigned int i = 0;
i <
k->originalTracks().size();
i++) {
782 aCluster.push_back(
k->originalTracks()[
i]);
786 clusters.emplace_back(
std::move(aCluster));
797 const unsigned int nv = y.
GetSize();
800 std::vector< unsigned int > iz;
801 for(
unsigned int j=0; j<
nt; j++){ iz.push_back(j); }
802 std::sort(iz.begin(), iz.end(), [tks](
unsigned int a,
unsigned int b){
return tks.
_z[
a]<tks.
_z[
b];} );
804 std::cout <<
"-----DAClusterizerInZ::dump ----" << nv <<
" clusters " << std::endl;
807 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex) {
808 if (std::fabs(y.
_z[ivertex]-zdumpcenter_) < zdumpwidth_){
812 std::cout << endl <<
"T=" << setw(15) << 1. / beta
813 <<
" Tmin =" << setw(10) << 1./betamax_
815 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex) {
816 if (std::fabs(y.
_z[ivertex]-zdumpcenter_) < zdumpwidth_){
817 double Tc = 2*y.
_swE[ivertex]/y.
_sw[ivertex];
825 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex) {
826 sumpk += y.
_pk[ivertex];
827 if (std::fabs(y.
_z[ivertex] - zdumpcenter_) > zdumpwidth_)
continue;
833 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex) {
834 sumpk += y.
_pk[ivertex];
835 if (std::fabs(y.
_z[ivertex] - zdumpcenter_) > zdumpwidth_)
continue;
844 <<
"---- z +/- dz ip +/-dip pt phi eta weights ----" 847 for (
unsigned int i0 = 0; i0 <
nt; i0++) {
848 unsigned int i = iz[i0];
852 double tz = tks.
_z[
i];
854 if( std::fabs(tz - zdumpcenter_) > zdumpwidth_)
continue;
855 std::cout << setw(4) << i <<
")" << setw(8) <<
fixed << setprecision(4)
856 << tz <<
" +/-" << setw(6) <<
sqrt(1./tks.
_dz2[i]);
869 << tks.
tt[
i]->track().hitPattern().pixelBarrelLayersWithMeasurement();
871 << tks.
tt[
i]->track().hitPattern().pixelEndcapLayersWithMeasurement();
873 << tks.
tt[
i]->track().hitPattern().trackerLayersWithMeasurement()
874 - tks.
tt[
i]->track().hitPattern().pixelLayersWithMeasurement()
881 tks.
tt[
i]->stateAtBeamLine().transverseImpactParameter();
883 std::cout <<
" " << setw(6) << setprecision(2)
884 << tks.
tt[
i]->track().pt() * tks.
tt[
i]->track().charge();
885 std::cout <<
" " << setw(5) << setprecision(2)
886 << tks.
tt[
i]->track().phi() <<
" " << setw(5)
887 << setprecision(2) << tks.
tt[
i]->track().eta();
890 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex) {
891 if (std::fabs(y.
_z[ivertex]-zdumpcenter_) > zdumpwidth_)
continue;
893 if ((tks.
_pi[i] > 0) && (tks.
_Z_sum[i] > 0)) {
901 E += p * Eik(tks.
_z[i], y.
_z[ivertex], tks.
_dz2[i]);
910 <<
" F= " <<
F << endl <<
"----------" << endl;
double *__restrict__ _ei_cache
void AddItem(double new_z, double new_dz2, const reco::TransientTrack *new_tt, double new_pi)
double *__restrict__ _swE
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
common ppss p3p6s2 common epss epspn46 common const1 w2
bool split(const double beta, track_t &t, vertex_t &y, double threshold=1.) const
void splitAll(vertex_t &y) const
void AddItem(double new_z, double new_pk)
track_t fill(const std::vector< reco::TransientTrack > &tracks) const
unsigned int GetSize() const
std::vector< const reco::TransientTrack * > tt
double *__restrict__ _dz2
std::vector< std::vector< reco::TransientTrack > > clusterize(const std::vector< reco::TransientTrack > &tracks) const
U second(std::pair< T, U > const &p)
void InsertItem(unsigned int i, double new_z, double new_pk)
double *__restrict__ _swz
Abs< T >::type abs(const T &t)
double BeamWidthX() const
beam width X
double beta0(const double betamax, track_t const &tks, vertex_t const &y) const
void RemoveItem(unsigned int i)
double update(double beta, track_t >racks, vertex_t &gvertices, bool useRho0, const double &rho0) const
bool merge(vertex_t &y, double &beta) const
DAClusterizerInZ_vect(const edm::ParameterSet &conf)
void dump(const double beta, const vertex_t &y, const track_t &tks, const int verbosity=0) const
double BeamWidthY() const
beam width Y
std::vector< TransientVertex > vertices(const std::vector< reco::TransientTrack > &tracks, const int verbosity=0) const
static int position[264][3]
unsigned int GetSize() const
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
bool purge(vertex_t &, track_t &, double &, const double) const
Power< A, B >::type pow(const A &a, const B &b)
double *__restrict__ _Z_sum
def merge(dictlist, TELL=False)