19#include "SamplerAnalysis.hh"
25double SamplerAnalysis::particleMass = 0;
27SamplerAnalysis::SamplerAnalysis():
53 int id = s->s->partID[0];
59 std::cout <<
"Primary particle: e-" << std::endl;
60 particleMass = 0.000510999;
break;}
63 std::cout <<
"Primary particle: proton" << std::endl;
64 particleMass = 0.938272;
break;}
67 std::cout <<
"Primary particle: unknown -> m=0" << std::endl;
68 particleMass = 0;
break;}
74 if ((particleName ==
"e-") || (particleName ==
"e+"))
76 std::cout <<
"Primary particle: e-" << std::endl;
77 particleMass = 0.000510999;;
79 else if (particleName ==
"proton")
81 std::cout <<
"Primary particle: proton" << std::endl;
82 particleMass = 0.938272;
86 std::cout <<
"Primary particle: unknown -> m=0" << std::endl;
96 coordinates.resize(6, 0);
112 covMats[i].resize(3);
114 {covMats[i][j].resize(3, 0);}
120 derivMats[i].resize(12);
121 for(
int j=0;j<12;++j)
122 {derivMats[i][j].resize(3, 0);}
128 powSumsFirst.resize(6);
129 cenMomsFirst.resize(6);
134 powSums[i].resize(6);
135 cenMoms[i].resize(6);
137 powSumsFirst[i].resize(6);
138 cenMomsFirst[i].resize(6);
142 powSums[i][j].resize(5);
143 cenMoms[i][j].resize(5);
145 powSumsFirst[i][j].resize(5);
146 cenMomsFirst[i][j].resize(5);
148 for(
int k=0;k<=4;++k)
150 powSums[i][j][k].resize(5, 0);
151 cenMoms[i][j][k].resize(5, 0);
153 powSumsFirst[i][j][k].resize(5, 0);
154 cenMomsFirst[i][j][k].resize(5, 0);
160SamplerAnalysis::~SamplerAnalysis()
171 {std::cout << __METHOD_NAME__ <<
"\"" << s->samplerName <<
"\" with " << s->n <<
" entries" << std::endl;}
173 double m2 = std::pow(particleMass,2);
176 for(
int i=0;i<s->n;++i)
180 if (s->parentID[i] != 0)
182 if (s->turnNumber[i] > 1)
187 coordinates[0] = s->x[i];
188 coordinates[1] = s->xp[i];
189 coordinates[2] = s->y[i];
190 coordinates[3] = s->yp[i];
191 coordinates[4] = std::sqrt(std::pow(s->energy[i],2) - m2);
192 coordinates[5] = s->T[i];
195 {offsets = coordinates;}
202 for (
int j = 0; j <= 4; ++j)
204 for (
int k = 0; k <= 4; ++k)
206 powSums[a][b][j][k] += std::pow(coordinates[a]-offsets[a],j)*std::pow(coordinates[b]-offsets[b],k);
216 bool useEmittanceFromFirstSampler)
219 {std::cout <<
" " << __METHOD_NAME__ << s->modelID <<
" " << npart << std::flush;}
222 bool nonZeroEmittanceIn = !std::all_of(emittance.begin(), emittance.end(), [](
double l) { return l==0; });
229 for (
int j = 0; j <= 4; ++j)
231 for (
int k = 0; k <= 4; ++k)
240 {printBeamCorrelationMatrix(cenMoms);}
252 optical[i][6] = cenMoms[j][j+1][1][0];
253 optical[i][7] = cenMoms[j][j+1][0][1];
254 optical[i][8] = sqrt(cenMoms[j][j+1][2][0]);
255 optical[i][9] = sqrt(cenMoms[j][j+1][0][2]);
262 optical[i][4] = (cenMoms[4][4][1][0]*cenMoms[j][4][1][1])/cenMoms[4][4][2][0];
263 optical[i][5] = (cenMoms[4][4][1][0]*cenMoms[j+1][4][1][1])/cenMoms[4][4][2][0];
266 if (!std::isfinite(
optical[i][4]))
268 if (!std::isfinite(
optical[i][5]))
272 double corrCentMom_2_0 = 0.0, corrCentMom_1_1 = 0.0;
273 double corrCentMom_0_2 = 0.0;
277 cenMoms[j][j+1][2][0] - std::pow(
optical[i][4],2)*cenMoms[4][4][2][0]/std::pow(cenMoms[4][4][1][0],2);
280 cenMoms[j][j+1][0][2] - std::pow(
optical[i][5],2)*cenMoms[4][4][2][0]/std::pow(cenMoms[4][4][1][0],2);
283 cenMoms[j][j+1][1][1] - (
optical[i][4]*
optical[i][5])*cenMoms[4][4][2][0]/std::pow(cenMoms[4][4][1][0],2);
285 if(useEmittanceFromFirstSampler && nonZeroEmittanceIn)
286 {
optical[i][0] = emittance[i];}
288 {
optical[i][0] = sqrt(corrCentMom_2_0 * corrCentMom_0_2 - std::pow(corrCentMom_1_1, 2));}
295 optical[i][11] = (double)npart;
316 for(
int j=0;j<12;++j)
328 for(
int j=0;j<12;++j)
334 varOptical[i][j] += derivMats[i][j][k]*derivMats[i][j][l]*covMats[i][k][l];
343 for(
int j=0;j<12;++j)
347 else if(j == 10 || j == 11)
351 if(useEmittanceFromFirstSampler && nonZeroEmittanceIn)
353 optical[i][j+12]=emittance[j+2];
366 double m2 = std::pow(particleMass,2);
368 optical[2][6] = std::sqrt(std::pow(meanP,2) + m2);
371 double gamma =
optical[2][6] / particleMass;
372 double beta = std::sqrt(1.0 - 1.0/std::pow(gamma,2));
374 optical[2][8] = (sigmaP/meanP)*std::pow(beta,2);
378 optical[0][24]=cenMoms[0][2][1][1]/std::sqrt(cenMoms[0][2][2][0]*cenMoms[0][2][0][2]);
381 std::vector<double> emittanceOut = {
optical[0][0],
390 long long int npartIn,
400 double npartPow1 = (double)npartIn;
404 double npartPow2 = npartPow1 * npartPow1;
405 double npartPow3 = npartPow2 * npartPow1;
406 double npartPow4 = npartPow3 * npartPow1;
408 if((m == 1 && n == 0) || (m == 0 && n == 1))
410 double s_1_0 = powSumsIn[a][b][m][n];
411 int k = m > n ? a : b;
413 moment = s_1_0/(double)npartIn+offsets[k];
416 else if((n == 2 && m == 0) || (n == 0 && m == 2))
418 double s_1_0 = 0.0, s_2_0 = 0.0;
421 s_1_0 = powSumsIn[a][b][m-1][n];
422 s_2_0 = powSumsIn[a][b][m][n];
426 s_1_0 = powSumsIn[a][b][m][n-1];
427 s_2_0 = powSumsIn[a][b][m][n];
430 moment = (npartPow1*s_2_0 - std::pow(std::abs(s_1_0),2))/(npartPow1*(npartPow1-1));
433 else if(n == 1 && m == 1)
435 double s_1_0 = 0.0, s_0_1 = 0.0, s_1_1 = 0.0;
437 s_1_0 = powSumsIn[a][b][m][n-1];
438 s_0_1 = powSumsIn[a][b][m-1][n];
439 s_1_1 = powSumsIn[a][b][m][n];
441 moment = (npartPow1*s_1_1 - s_0_1*s_1_0)/(npartPow1*(npartPow1-1));
444 else if((n == 4 && m == 0) || (n == 0 && m == 4))
446 double s_1_0 = 0.0, s_2_0 = 0.0, s_3_0 = 0.0, s_4_0 = 0.0;
449 s_1_0 = powSumsIn[a][b][m-3][n];
450 s_2_0 = powSumsIn[a][b][m-2][n];
451 s_3_0 = powSumsIn[a][b][m-1][n];
452 s_4_0 = powSumsIn[a][b][m][n];
456 s_1_0 = powSumsIn[a][b][m][n-3];
457 s_2_0 = powSumsIn[a][b][m][n-2];
458 s_3_0 = powSumsIn[a][b][m][n-1];
459 s_4_0 = powSumsIn[a][b][m][n];
462 moment = - (3*std::pow(s_1_0,4))/npartPow4 + (6*std::pow(s_1_0,2)*s_2_0)/npartPow3
463 - (4*s_1_0*s_3_0)/npartPow2 + s_4_0/npartPow1;
466 else if((m == 3 && n == 1) || (m == 1 && n ==3))
468 double s_1_0 = 0.0, s_0_1 = 0.0, s_1_1 = 0.0, s_2_0 = 0.0, s_2_1 = 0.0, s_3_0 = 0.0, s_3_1 = 0.0;
472 s_1_0 = powSumsIn[a][b][m-2][n-1];
473 s_0_1 = powSumsIn[a][b][m-3][n];
474 s_1_1 = powSumsIn[a][b][m-2][n];
475 s_2_0 = powSumsIn[a][b][m-1][n-1];
476 s_2_1 = powSumsIn[a][b][m-1][n];
477 s_3_0 = powSumsIn[a][b][m][n-1];
478 s_3_1 = powSumsIn[a][b][m][n];
482 s_1_0 = powSumsIn[a][b][m-1][n-2];
483 s_0_1 = powSumsIn[a][b][m][n-3];
484 s_1_1 = powSumsIn[a][b][m][n-2];
485 s_2_0 = powSumsIn[a][b][m-1][n-1];
486 s_2_1 = powSumsIn[a][b][m][n-1];
487 s_3_0 = powSumsIn[a][b][m-1][n];
488 s_3_1 = powSumsIn[a][b][m][n];
491 moment = - (3*s_0_1*std::pow(s_1_0,3))/npartPow4 + (3*s_1_0*s_1_0*s_1_1)/npartPow3
492 + (3*s_0_1*s_1_0*s_2_0)/npartPow3 - (3*s_1_0*s_2_1)/npartPow2
493 - (s_0_1*s_3_0)/npartPow2 + s_3_1/npartPow1;
496 else if(m == 2 && n == 2)
498 double s_1_0 = 0.0, s_0_1 = 0.0, s_1_1 = 0.0, s_2_0 = 0.0, s_0_2 = 0.0, s_1_2 = 0.0, s_2_1 = 0.0, s_2_2 = 0.0;
500 s_1_0 = powSumsIn[a][b][m-1][n-2];
501 s_0_1 = powSumsIn[a][b][m-2][n-1];
502 s_1_1 = powSumsIn[a][b][m-1][n-1];
503 s_2_0 = powSumsIn[a][b][m][n-2];
504 s_0_2 = powSumsIn[a][b][m-2][n];
505 s_1_2 = powSumsIn[a][b][m-1][n];
506 s_2_1 = powSumsIn[a][b][m][n-1];
507 s_2_2 = powSumsIn[a][b][m][n];
509 moment = - (3*std::pow(s_0_1,2)*std::pow(s_1_0,2))/npartPow4 + (s_0_2*std::pow(s_1_0,2))/npartPow3
510 + (4*s_0_1*s_1_0*s_1_1)/npartPow3 - (2*s_1_0*s_1_2)/npartPow2
511 + (std::pow(s_0_1,2)*s_2_0)/npartPow3 - (2*s_0_1*s_2_1)/npartPow2 + s_2_2/npartPow1;
518 long long int npartIn,
523 double npartInD = (double)npartIn;
530 if((i == 0 && j == 0) || (i == 1 && j == 1))
532 double m_4_0 = 0.0, m_2_0 = 0.0;
536 m_4_0 = centMoms[a][a+1][4][0];
537 m_2_0 = centMoms[a][a+1][2][0];
542 m_4_0 = centMoms[a][a+1][0][4];
543 m_2_0 = centMoms[a][a+1][0][2];
546 cov = -((npartInD-3)*std::pow(m_2_0,2))/(npartInD*(npartInD-1)) + m_4_0/npartInD;
549 else if(i == 2 && j == 2)
551 double m_1_1 = 0.0, m_2_0 = 0.0, m_0_2 = 0.0, m_2_2 = 0.0;
553 m_1_1 = centMoms[a][a+1][1][1];
554 m_2_0 = centMoms[a][a+1][2][0];
555 m_0_2 = centMoms[a][a+1][0][2];
556 m_2_2 = centMoms[a][a+1][2][2];
558 cov = -((npartInD-2)*std::pow(m_1_1,2))/(npartInD*(npartInD-1)) + (m_0_2*m_2_0)/(npartInD*(npartInD-1)) + m_2_2/npartInD;
561 else if((i == 0 && j == 2) || (i == 1 && j == 2) || (i == 2 && j == 0) || (i == 2 && j == 1))
563 double m_1_1 = 0.0, m_2_0 = 0.0, m_3_1 = 0.0;
565 if((i == 0 && j == 2) || (i == 2 && j == 0 ))
567 m_1_1 = centMoms[a][a+1][1][1];
568 m_2_0 = centMoms[a][a+1][2][0];
569 m_3_1 = centMoms[a][a+1][3][1];
571 else if((i == 1 && j == 2) || (i == 2 && j == 1))
573 m_1_1 = centMoms[a][a+1][1][1];
574 m_2_0 = centMoms[a][a+1][0][2];
575 m_3_1 = centMoms[a][a+1][1][3];
578 cov = -((npartInD-3)*m_1_1*m_2_0)/(npartInD*(npartInD-1)) + m_3_1/npartInD;
580 else if((i == 0 && j == 1) || (i == 1 && j == 0) )
582 double m_1_1 = 0.0, m_2_0 = 0.0, m_0_2 = 0.0, m_2_2 = 0.0;
584 m_1_1 = centMoms[a][a+1][1][1];
585 m_2_0 = centMoms[a][a+1][0][2];
586 m_0_2 = centMoms[a][a+1][2][0];
587 m_2_2 = centMoms[a][a+1][2][2];
589 cov = 2*std::pow(m_1_1,2)/(npartInD*(npartInD-1)) - m_2_0*m_0_2/npartInD + m_2_2/npartInD;
613 deriv = centMoms[a][a+1][0][2]/(2*sqrt(centMoms[a][a+1][2][0]*centMoms[a][a+1][0][2]-std::pow(centMoms[a][a+1][1][1],2)));
615 else if(i == 1 && k < 2)
617 deriv = centMoms[a][a+1][2][0]/(2*sqrt(centMoms[a][a+1][2][0]*centMoms[a][a+1][0][2]-std::pow(centMoms[a][a+1][1][1],2)));
619 else if(i == 2 && k < 2)
621 deriv = -centMoms[a][a+1][1][1]/(sqrt(centMoms[a][a+1][2][0]*centMoms[a][a+1][0][2]-std::pow(centMoms[a][a+1][1][1],2)));
632 deriv = centMoms[a][a+1][0][2]*centMoms[a][a+1][1][1]/(2*std::pow(centMoms[a][a+1][2][0]*centMoms[a][a+1][0][2]-std::pow(centMoms[a][a+1][1][1],2),3./2.));
634 else if(i == 1 && k < 2)
636 deriv = centMoms[a][a+1][2][0]*centMoms[a][a+1][1][1]/(2*std::pow(centMoms[a][a+1][2][0]*centMoms[a][a+1][0][2]-std::pow(centMoms[a][a+1][1][1],2),3./2.));
638 else if(i == 2 && k < 2)
640 deriv = - centMoms[a][a+1][2][0]*centMoms[a][a+1][0][2]/std::pow(centMoms[a][a+1][2][0]*centMoms[a][a+1][0][2]-std::pow(centMoms[a][a+1][1][1],2),3./2.);
651 deriv = (centMoms[a][a+1][2][0]*centMoms[a][a+1][0][2]-2*std::pow(centMoms[a][a+1][1][1],2))/(2*std::pow(centMoms[a][a+1][2][0]*centMoms[a][a+1][0][2]-std::pow(centMoms[a][a+1][1][1],2),3./2.));
653 else if(i == 1 && k < 2)
655 deriv = - std::pow(centMoms[a][a+1][2][0],2)/(2*std::pow(centMoms[a][a+1][2][0]*centMoms[a][a+1][0][2]-std::pow(centMoms[a][a+1][1][1],2),3./2.));
657 else if(i == 2 && k < 2)
659 deriv = centMoms[a][a+1][2][0]*centMoms[a][a+1][1][1]/std::pow(centMoms[a][a+1][2][0]*centMoms[a][a+1][0][2]-std::pow(centMoms[a][a+1][1][1],2),3./2.);
678 else if(i == 1 && k < 2)
680 deriv = -centMoms[a][4][1][1]/std::pow(centMoms[4][4][2][0],2);
682 else if(i == 2 && k < 2)
684 deriv = 1/centMoms[4][4][2][0];
697 else if(i == 1 && k < 2)
699 deriv = -centMoms[a+1][4][1][1]/std::pow(centMoms[4][4][2][0],2);
701 else if(i == 2 && k < 2)
703 deriv = 1/centMoms[4][4][2][0];
724 deriv = 1/(2*sqrt(centMoms[a][a+1][2][0]));
736 deriv = 1/(2*sqrt(centMoms[a][a+1][0][2]));
751void SamplerAnalysis::printBeamCorrelationMatrix(fourDArray& centMoms)
753 std::cout<<
"\nCorrelation matrix for sampler: "<<s->samplerName<<std::endl;
755 for (
int i=0; i<6; i++)
757 for(
int j=0; j<6; j++)
759 corr = centMoms[i][j][1][1]/std::sqrt(centMoms[i][j][2][0]*centMoms[i][j][0][2]);
760 std::printf(
"%- *.6e ", 12, corr);
Information stored per sampler per event.
Analysis routines for an individual sampler.
twoDArray optical
emt, alf, bta, gma, eta, etapr, mean, sigma
twoDArray varOptical
variances of optical functions
double centMomToDerivative(fourDArray ¢Moms, int k, int t, int i)
void Initialise()
Initialise variables.
static void UpdateMass(SamplerAnalysis *s)
Set primary particle mass for optical functions from sampler data.
void CommonCtor()
Initialisation of arrays for optical function calculations.
void Process(bool firstTime=false)
Loop over all entries in the sampler and accumulate power sums over variuos moments.
double centMomToCovariance(fourDArray ¢Moms, long long int npartIn, int k, int i, int j)
double powSumToCentralMoment(fourDArray &powSum, long long int npartIn, int i, int j, int m, int n)
std::vector< double > Terminate(std::vector< double > emittance, bool useEmittanceFromFirstSampler=true)
Calculate optical functions based on combinations of moments already accumulated.