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
241 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex ) {
251 if (this->verbose_) {
252 std::cout <<
" a cluster melted away ? pk=" <<
vertices._pk[ ivertex ] <<
" sumw=" 259 auto osumpi = 1./sumpi;
260 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex )
266 delta += kernel_calc_z(gvertices);
280 const unsigned int nv = y.
GetSize();
286 std::vector<std::pair<double, unsigned int> > critical;
287 for (
unsigned int k = 0; (
k + 1) < nv;
k++) {
288 if (std::fabs(y.
_z[
k + 1] - y.
_z[
k]) < zmerge_) {
289 critical.push_back( make_pair( std::fabs(y.
_z[
k + 1] - y.
_z[
k]),
k) );
292 if (critical.empty())
return false;
294 std::stable_sort(critical.begin(), critical.end(), std::less<std::pair<double, unsigned int> >() );
297 for (
unsigned int ik=0; ik < critical.size(); ik++){
298 unsigned int k = critical[ik].second;
299 double rho = y.
_pk[
k]+y.
_pk[k+1];
301 double Tc = 2*swE / (y.
_sw[
k]+y.
_sw[k+1]);
304 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;}
308 y.
_z[
k] = 0.5 * (y.
_z[
k] + y.
_z[k + 1]);
327 const unsigned int nv = y.
GetSize();
334 unsigned int k0 = nv;
336 for (
unsigned int k = 0;
k < nv;
k++) {
341 double pmax = y.
_pk[
k] / (y.
_pk[
k] + rho0 * local_exp(-beta * dzCutOff_* dzCutOff_));
342 for (
unsigned int i = 0;
i <
nt;
i++) {
346 if ((p > uniquetrkweight_ * pmax) && (tks.
_pi[
i] > 0)) {
352 if ((nUnique < 2) && (sump < sumpmin)) {
361 std::cout <<
"eliminating prototype at " << std::setw(10) << std::setprecision(4) << y.
_z[
k0]
362 <<
" with sump=" << sumpmin
363 <<
" rho*nt =" << y.
_pk[
k0]*nt
382 const unsigned int nv = y.
GetSize();
384 for (
unsigned int k = 0;
k < nv;
k++) {
389 for (
unsigned int i = 0;
i <
nt;
i++) {
391 sumwz += w * tks.
_z[
i];
394 y.
_z[
k] = sumwz / sumw;
398 for (
unsigned int i = 0;
i <
nt;
i++) {
404 double Tc = 2. * a /
b;
405 if (Tc > T0) T0 = Tc;
409 std::cout <<
"DAClustrizerInZ_vect.beta0: Tc = " << T0 << std::endl;
411 std::cout <<
"DAClustrizerInZ_vect.beta0: nstep = " << coolingsteps << std::endl;
415 if (T0 > 1. / betamax) {
419 return betamax * coolingFactor_;
436 std::vector<std::pair<double, unsigned int> > critical;
437 for(
unsigned int k=0;
k<nv;
k++){
439 if (beta*Tc > threshold){
440 critical.push_back( make_pair(Tc,
k));
443 if (critical.empty())
return false;
446 std::stable_sort(critical.begin(), critical.end(), std::greater<std::pair<double, unsigned int> >() );
452 for(
unsigned int ic=0; ic<critical.size(); ic++){
453 unsigned int k=critical[ic].second;
456 double p1=0, z1=0, w1=0;
457 double p2=0, z2=0,
w2=0;
458 for(
unsigned int i=0;
i<
nt;
i++){
462 double tl = tks.
_z[
i] < y.
_z[
k] ? 1.: 0.;
467 if(std::fabs(arg) < 20){
468 double t = local_exp(-arg);
475 p1 += p*tl ; z1 += w*tl*tks.
_z[
i]; w1 += w*tl;
476 p2 += p*tr; z2 += w*tr*tks.
_z[
i];
w2 += w*tr;
480 if(w1>0){z1 = z1/w1;}
else {z1=y.
_z[
k]-
epsilon;}
484 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]; }
485 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]; }
488 if (std::fabs(y.
_z[k] - zdumpcenter_) < zdumpwidth_){
489 std::cout <<
" T= " << std::setw(8) << 1./beta
490 <<
" Tc= " << critical[ic].first
491 <<
" splitting " <<
std::fixed << std::setprecision(4) << y.
_z[
k]
492 <<
" --> " << z1 <<
"," << z2
493 <<
" [" << p1 <<
"," << p2 <<
"]" ;
494 if (std::fabs(z2-z1)>epsilon){
503 if( (z2-z1) > epsilon){
505 double pk1 = p1*y.
_pk[
k]/(p1+
p2);
506 double pk2 = p2*y.
_pk[
k]/(p1+
p2);
513 for(
unsigned int jc=ic; jc < critical.size(); jc++){
514 if (critical[jc].
second > k) {critical[jc].second++;}
525 const unsigned int nv = y.
GetSize();
532 std::cout <<
"Before Split "<< std::endl;
536 for (
unsigned int k = 0;
k < nv;
k++) {
538 ( (
k == 0) || ( y.
_z[
k - 1] < (y.
_z[
k] - zsep)) ) &&
539 ( ((
k + 1) == nv) || ( y.
_z[
k + 1] > (y.
_z[
k] + zsep)) ) )
545 double new_pk = 0.5 * y.
pk[
k];
551 else if ( (y1.
GetSize() == 0 ) ||
568 std::cout <<
"After split " << std::endl;
575 vector<TransientVertex>
584 if (tks.
GetSize() == 0)
return clusters;
595 double beta = beta0(betamax_, tks, y);
596 if ( verbose_)
std::cout <<
"Beta0 is " << beta << std::endl;
599 while ((
update(beta, tks, y,
false, rho0) > 1.
e-6) &&
600 (niter++ < maxIterations_)) {}
604 double betafreeze = betamax_ *
sqrt(coolingFactor_);
606 while (beta < betafreeze) {
608 update(beta, tks,y,
false, rho0);
609 while(
merge(y, beta)){
update(beta, tks, y,
false, rho0);}
611 beta=beta/coolingFactor_;
613 beta=beta/coolingFactor_;
619 while ((
update(beta, tks, y,
false, rho0) > 1.
e-6) &&
620 (niter++ < maxIterations_)) {}
622 if(verbose_){
dump( beta, y, tks, 0); }
628 if(verbose_){
std::cout <<
"last spliting at " << 1./beta << std::endl; }
629 update(beta, tks,y,
false, rho0);
630 while(
merge(y,beta)){
update(beta, tks,y,
false, rho0);}
633 while(
split(beta, tks, y, threshold) && (ntry++<10) ){
635 while((
update(beta, tks,y,
false, rho0)>1.
e-6) && (niter++ < maxIterations_)){}
636 while(
merge(y,beta)){
update(beta, tks,y,
false, rho0);}
638 std::cout <<
"after final splitting, try " << ntry << std::endl;
639 dump(beta, y, tks, 2);
646 while(
merge(y,beta)){
update(beta, tks,y,
false, rho0);}
650 update(beta, tks,y,
false, rho0);
651 std::cout <<
"dump after 1st merging " << endl;
652 dump(beta, y, tks, 2);
659 for(
unsigned int a=0;
a<10;
a++){
update(beta, tks, y,
true,
a*rho0/10);}
663 while ((
update(beta, tks, y,
true, rho0) > 1.
e-8) && (niter++ < maxIterations_)) {};
665 std::cout <<
"dump after noise-suppression, rho0=" << rho0 <<
" niter = " << niter << endl;
666 dump(beta, y, tks, 2);
670 while (
merge(y, beta)) {
update(beta, tks, y,
true, rho0); }
672 std::cout <<
"dump after merging " << endl;
673 dump(beta, y, tks, 2);
677 while( beta < betapurge_ ){
678 beta =
min( beta/coolingFactor_, betapurge_);
680 while ((
update(beta, tks, y,
false, rho0) > 1.
e-8) && (niter++ < maxIterations_)) {}
685 while (purge(y, tks, rho0, beta)) {
687 while ((
update(beta, tks, y,
true, rho0) > 1.
e-6) && (niter++ < maxIterations_)) {}
691 update(beta, tks,y,
true, rho0);
692 std::cout <<
" after purging " << std:: endl;
693 dump(beta, y, tks, 2);
697 while( beta < betastop_ ){
698 beta =
min( beta/coolingFactor_, betastop_);
700 while ((
update(beta, tks, y,
true, rho0) > 1.
e-8) && (niter++ < maxIterations_)) {}
705 std::cout <<
"Final result, rho0=" << std::scientific << rho0 << endl;
706 dump(beta, y, tks, 2);
710 GlobalError dummyError(0.01, 0, 0.01, 0., 0., 0.01);
713 const unsigned int nv = y.
GetSize();
714 for (
unsigned int k = 0;
k < nv;
k++)
717 for (
unsigned int i = 0;
i <
nt;
i++)
718 tks.
_Z_sum[
i] = rho0 * local_exp(-beta * dzCutOff_ * dzCutOff_);
721 for (
unsigned int k = 0;
k < nv;
k++) {
722 for (
unsigned int i = 0;
i <
nt;
i++)
727 for (
unsigned int k = 0;
k < nv;
k++) {
730 vector<reco::TransientTrack> vertexTracks;
731 for (
unsigned int i = 0;
i <
nt;
i++) {
734 double p = y.
_pk[
k] * local_exp(-beta * Eik(tks.
_z[
i], y.
_z[
k],
736 if ((tks.
_pi[
i] > 0) && (p > mintrkweight_)) {
737 vertexTracks.push_back(*(tks.
tt[
i]));
743 clusters.push_back(v);
751 const vector<reco::TransientTrack> &
tracks)
const {
754 std::cout <<
"###################################################" << endl;
755 std::cout <<
"# vectorized DAClusterizerInZ_vect::clusterize nt=" << tracks.size() << endl;
756 std::cout <<
"###################################################" << endl;
759 vector<vector<reco::TransientTrack> >
clusters;
760 vector<TransientVertex> &&
pv =
vertices(tracks);
763 std::cout <<
"# DAClusterizerInZ::clusterize pv.size=" << pv.size()
771 vector<reco::TransientTrack> aCluster = pv.begin()->originalTracks();
773 for (
auto k = pv.begin() + 1;
k != pv.end();
k++) {
776 if (aCluster.size()>1){
777 clusters.push_back(aCluster);
780 std::cout <<
" one track cluster at " <<
k->position().z() <<
" suppressed" << std::endl;
785 for (
unsigned int i = 0;
i <
k->originalTracks().size();
i++) {
786 aCluster.push_back(
k->originalTracks()[
i]);
790 clusters.emplace_back(
std::move(aCluster));
801 const unsigned int nv = y.
GetSize();
804 std::vector< unsigned int > iz;
805 for(
unsigned int j=0; j<
nt; j++){ iz.push_back(j); }
806 std::sort(iz.begin(), iz.end(), [tks](
unsigned int a,
unsigned int b){
return tks.
_z[
a]<tks.
_z[
b];} );
808 std::cout <<
"-----DAClusterizerInZ::dump ----" << nv <<
" clusters " << std::endl;
811 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex) {
812 if (std::fabs(y.
_z[ivertex]-zdumpcenter_) < zdumpwidth_){
816 std::cout << endl <<
"T=" << setw(15) << 1. / beta
817 <<
" Tmin =" << setw(10) << 1./betamax_
819 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex) {
820 if (std::fabs(y.
_z[ivertex]-zdumpcenter_) < zdumpwidth_){
821 double Tc = 2*y.
_swE[ivertex]/y.
_sw[ivertex];
829 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex) {
830 sumpk += y.
_pk[ivertex];
831 if (std::fabs(y.
_z[ivertex] - zdumpcenter_) > zdumpwidth_)
continue;
837 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex) {
838 sumpk += y.
_pk[ivertex];
839 if (std::fabs(y.
_z[ivertex] - zdumpcenter_) > zdumpwidth_)
continue;
848 <<
"---- z +/- dz ip +/-dip pt phi eta weights ----" 851 for (
unsigned int i0 = 0; i0 <
nt; i0++) {
852 unsigned int i = iz[i0];
856 double tz = tks.
_z[
i];
858 if( std::fabs(tz - zdumpcenter_) > zdumpwidth_)
continue;
859 std::cout << setw(4) << i <<
")" << setw(8) <<
fixed << setprecision(4)
860 << tz <<
" +/-" << setw(6) <<
sqrt(1./tks.
_dz2[i]);
873 << tks.
tt[
i]->track().hitPattern().pixelBarrelLayersWithMeasurement();
875 << tks.
tt[
i]->track().hitPattern().pixelEndcapLayersWithMeasurement();
877 << tks.
tt[
i]->track().hitPattern().trackerLayersWithMeasurement()
878 - tks.
tt[
i]->track().hitPattern().pixelLayersWithMeasurement()
885 tks.
tt[
i]->stateAtBeamLine().transverseImpactParameter();
887 std::cout <<
" " << setw(6) << setprecision(2)
888 << tks.
tt[
i]->track().pt() * tks.
tt[
i]->track().charge();
889 std::cout <<
" " << setw(5) << setprecision(2)
890 << tks.
tt[
i]->track().phi() <<
" " << setw(5)
891 << setprecision(2) << tks.
tt[
i]->track().eta();
894 for (
unsigned int ivertex = 0; ivertex < nv; ++ ivertex) {
895 if (std::fabs(y.
_z[ivertex]-zdumpcenter_) > zdumpwidth_)
continue;
897 if ((tks.
_pi[i] > 0) && (tks.
_Z_sum[i] > 0)) {
905 E += p * Eik(tks.
_z[i], y.
_z[ivertex], tks.
_dz2[i]);
914 <<
" 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)
constexpr bool isNotFinite(T x)
track_t fill(const std::vector< reco::TransientTrack > &tracks) const
unsigned int GetSize() const
std::vector< const reco::TransientTrack * > tt
double *__restrict__ _dz2
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)
std::vector< std::vector< reco::TransientTrack > > clusterize(const std::vector< reco::TransientTrack > &tracks) const override
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)