9 #include "Pythia8/Pythia.h"
10 #include "Pythia8/HIUserHooks.h"
24 ParticleData & particleDataIn, Rndm & rndIn) {
27 particleDataPtr = &particleDataIn;
51 bool NucleusModel::init() {
60 Particle NucleusModel::produceIon(
bool istarg) {
61 double e = max(A(), 1)*(istarg?
settingsPtr->parm(
"Beams:eB"):
63 double m = particleDataPtr->m0(
id());
64 Particle p(
id(), -12);
65 double pz = sqrt(max(e*e - m*m, 0.0));
73 p.daughter1(daughter);
90 double sel = rndPtr->flat()*(intlo + inthi0 + inthi1 + inthi2);
91 if ( sel > intlo ) r -=
a()*log(rndPtr->flat());
92 if ( sel > intlo + inthi0 ) r -=
a()*log(rndPtr->flat());
93 if ( sel > intlo + inthi0 + inthi1 ) r -=
a()*log(rndPtr->flat());
95 r = R()*pow(rndPtr->flat(), 1.0/3.0);
96 if ( rndPtr->flat()*(1.0 + exp((r - R())/
a())) > 1.0 )
continue;
98 if ( rndPtr->flat()*(1.0 + exp((r - R())/
a())) > exp((r - R())/
a()) )
101 double costhe = 2.0*rndPtr->flat() - 1.0;
102 double sinthe = sqrt(max(1.0 - costhe*costhe, 0.0));
103 double phi = 2.0*M_PI*rndPtr->flat();
105 return Vec4(r*sinthe*cos(phi), r*sinthe*sin(phi), r*costhe);
124 if ( A() == 0 )
return true;
125 gaussHardCore =
settingsPtr->flag(
"HeavyIon:gaussHardCore");
128 RhSave = 0.9*femtometer;
129 RSave = (1.1*pow(
double(A()),1.0/3.0) -
130 0.656*pow(
double(A()),-1.0/3.0))*femtometer;
131 aSave = 0.459*femtometer;
133 RSave = (1.12*pow(
double(A()),1.0/3.0) -
134 0.86*pow(
double(A()),-1.0/3.0))*femtometer;
135 aSave = 0.54*femtometer;
141 RSave = (1.1*pow(
double(A()),1.0/3.0) -
142 0.656*pow(
double(A()),-1.0/3.0))*femtometer;
143 aSave = 0.459*femtometer;
145 RSave = (1.12*pow(
double(A()),1.0/3.0) -
146 0.86*pow(
double(A()),-1.0/3.0))*femtometer;
147 aSave = 0.54*femtometer;
163 int sign =
id() > 0? 1: -1;
166 vector<Nucleon> nucleons;
168 nucleons.push_back(
Nucleon(
id(), 0, Vec4()));
172 if ( Z() == 1 ) nucleons.push_back(
Nucleon(pid, 0, Vec4()));
173 else nucleons.push_back(
Nucleon(nid, 0, Vec4()));
178 vector<Vec4> positions;
179 while (
int(positions.size()) < A() ) {
182 bool overlap =
false;
183 for (
int i = 0, N = positions.size(); i < N && !overlap; ++i )
184 if ( (positions[i] - pos).pAbs() < (gaussHardCore ? RhGauss() :
Rh()) )
186 if ( overlap )
continue;
187 positions.push_back(pos);
194 nucleons.resize(A());
197 for (
int i = 0, N= positions.size(); i < N; ++i ) {
198 Vec4 pos(positions[i].px() - cms.px(),
199 positions[i].py() - cms.py());
200 if (
int(rndPtr->flat()*(Np + Nn)) >= Np ) {
202 nucleons[i] =
Nucleon(nid, i, pos);
205 nucleons[i] =
Nucleon(pid, i, pos);
221 void ImpactParameterGenerator::initPtr(SubCollisionModel & collIn,
222 NucleusModel & projIn,
223 NucleusModel & targIn,
224 Settings & settingsIn,
229 settingsPtr = &settingsIn;
239 if ( settingsPtr->isParm(
"HI:bWidth") )
240 widthSave = settingsPtr->parm(
"HI:bWidth")*femtometer;
242 widthSave = settingsPtr->parm(
"HeavyIon:bWidth")*femtometer;
244 if ( widthSave <= 0.0 ) {
246 double RA = max(Rp, projPtr->R());
247 double RB = max(Rp, targPtr->R());
248 widthSave = RA + RB + 2.0*Rp;
249 cout <<
" HeavyIon Info: Initializing impact parameter generator "
250 <<
"with width " << widthSave/femtometer <<
" fm." << endl;
261 double b = sqrt(-2.0*log(rndPtr->flat()))*
width();
262 double phi = 2.0*M_PI*rndPtr->flat();
264 return Vec4(b*sin(phi), b*cos(phi), 0.0, 0.0);
279 sigTarg[0] = sigTotPtr->sigmaTot()*millibarn;
280 sigTarg[1] = sigTotPtr->sigmaND()*millibarn;
281 sigTarg[2] = sigTotPtr->sigmaXX()*millibarn;
282 sigTarg[3] = sigTotPtr->sigmaAX()*millibarn + sigTarg[1] + sigTarg[2];
283 sigTarg[4] = sigTotPtr->sigmaXB()*millibarn + sigTarg[1] + sigTarg[2];
284 sigTarg[5] = sigTotPtr->sigmaAXB()*millibarn;
285 sigTarg[6] = sigTotPtr->sigmaEl()*millibarn;
286 sigTarg[7] = sigTotPtr->bSlopeEl();
287 NInt = settingsPtr->mode(
"HeavyIon:SigFitNInt");
288 NGen = settingsPtr->mode(
"HeavyIon:SigFitNGen");
289 NPop = settingsPtr->mode(
"HeavyIon:SigFitNPop");
290 sigErr = settingsPtr->pvec(
"HeavyIon:SigFitErr");
291 sigFuzz = settingsPtr->parm(
"HeavyIon:SigFitFuzz");
292 fitPrint = settingsPtr->flag(
"HeavyIon:SigFitPrint");
295 avNDb = 2.0*sqrt(sigTarg[1]/M_PI)*
296 settingsPtr->parm(
"Angantyr:impactFudge")/3.0;
309 for (
int i = 0, Nval = se.sig.size(); i < Nval; ++i ) {
310 if ( sigErr[i] == 0.0 )
continue;
312 chi2 += pow2(se.sig[i] - sigTarg[i])/
313 (se.dsig2[i] + pow2(sigTarg[i]*sigErr[i]));
315 return chi2/double(max(nval - npar, 1));
325 void printTarget(
string name,
double sig,
double sigerr,
326 string unit =
"mb ") {
327 cout << fixed << setprecision(2);
328 cout <<
" |" << setw(25) << name <<
": " << setw(8) << sig <<
" " << unit;
330 cout <<
" (+- " << setw(2) << int(100.0*sigerr)
333 cout <<
" not used | \n";
336 void printFit(
string name,
double fit,
double sig,
double sigerr,
337 string unit =
"mb ") {
338 cout <<
" |" << setw(25) << name <<
": "
340 << (sigerr > 0.0?
" *(":
" (")
342 <<
") " << unit <<
" | " << endl;
352 typedef vector<double> Parms;
353 Parms minp = minParm();
354 Parms maxp = maxParm();
355 int dim = minp.size();
356 if ( dim == 0 )
return true;
359 cout <<
" *------ HeavyIon fitting of SubCollisionModel to "
360 <<
"cross sections ------* " << endl;
361 printTarget(
"Total", sigTarg[0]/millibarn, sigErr[0]);
362 printTarget(
"non-diffractive", sigTarg[1]/millibarn, sigErr[1]);
363 printTarget(
"XX diffractive", sigTarg[2]/millibarn, sigErr[2]);
364 printTarget(
"wounded target (B)", sigTarg[3]/millibarn, sigErr[3]);
365 printTarget(
"wounded projectile (A)", sigTarg[4]/millibarn, sigErr[4]);
366 printTarget(
"AXB diffractive", sigTarg[5]/millibarn, sigErr[5]);
367 printTarget(
"elastic", sigTarg[6]/millibarn, sigErr[6]);
368 printTarget(
"elastic b-slope", sigTarg[7], sigErr[7],
"GeV^-2");
372 vector<Parms> pop(NPop, Parms(dim));
373 vector<double> def = settingsPtr->pvec(
"HeavyIon:SigFitDefPar");
374 if ( settingsPtr->isPVec(
"HI:SigFitDefPar") )
375 def = settingsPtr->pvec(
"HI:SigFitDefPar");
376 for (
int j = 0; j < dim; ++j )
377 pop[0][j] = max(minp[j], min(def[j], maxp[j]));
378 for (
int i = 1; i < NPop; ++i )
379 for (
int j = 0; j < dim; ++j )
380 pop[i][j] = minp[j] + rndPtr->flat()*(maxp[j] - minp[j]);
383 for (
int igen = 0; igen < NGen; ++igen ) {
385 multimap<double, Parms> chi2map;
386 double chi2max = 0.0;
387 double chi2sum = 0.0;
388 for (
int i = 0; i < NPop; ++i ) {
391 chi2map.insert(make_pair(chi2, pop[i]));
392 chi2max = max(chi2max, chi2);
398 multimap<double, Parms>::iterator it = chi2map.begin();
404 <<
" | Using a genetic algorithm "
406 <<
" | Generation best Chi2/Ndf "
408 cout <<
" |" << setw(25) << igen <<
":" << fixed << setprecision(2)
409 << setw(9) << it->first
413 for (
int i = 1; i < NPop; ++i ) {
414 pop[i] = (++it)->second;
415 if ( it->first > rndPtr->flat()*chi2max ) {
417 for (
int j = 0; j < dim; ++j )
418 pop[i][j] = minp[j] + rndPtr->flat()*(maxp[j] - minp[j]);
421 int ii = int(rndPtr->flat()*i);
422 for (
int j = 0; j < dim; ++j ) {
423 double d = pop[ii][j] - it->second[j];
424 double pl = max(minp[j], min(it->second[j] - sigFuzz*d, maxp[j]));
425 double pu = max(minp[j], min(it->second[j] +
426 (1.0 + sigFuzz)*d, maxp[j]));
427 pop[i][j] = pl + rndPtr->flat()*(pu - pl);
434 double chi2 =
Chi2(se, dim);
435 avNDb = se.avNDb*settingsPtr->parm(
"Angantyr:impactFudge");
437 infoPtr->errorMsg(
"HeavyIon Warning: Chi^2 in fitting sub-collision "
438 "model to cross sections was high.");
440 cout << fixed << setprecision(2);
444 cout <<
" | Resulting cross sections (target value) "
447 printFit(
"Total", se.sig[0]/millibarn,
448 sigTarg[0]/millibarn, sigErr[0]);
449 printFit(
"non-diffractive", se.sig[1]/millibarn,
450 sigTarg[1]/millibarn, sigErr[1]);
451 printFit(
"XX diffractive", se.sig[2]/millibarn,
452 sigTarg[2]/millibarn, sigErr[2]);
453 printFit(
"wounded target (B)", se.sig[3]/millibarn,
454 sigTarg[3]/millibarn, sigErr[3]);
455 printFit(
"wounded projectile (A)", se.sig[4]/millibarn,
456 sigTarg[4]/millibarn, sigErr[4]);
457 printFit(
"AXB diffractive", se.sig[5]/millibarn,
458 sigTarg[5]/millibarn, sigErr[5]);
459 printFit(
"elastic", se.sig[6]/millibarn,
460 sigTarg[6]/millibarn, sigErr[6]);
461 printFit(
"elastic b-slope", se.sig[7], sigTarg[7], sigErr[7],
"GeV^-2");
462 cout <<
" | Chi2/Ndf: "
468 cout <<
" | Resulting parameters: "
471 for (
int j = 0; j < dim; ++j )
472 cout <<
" |" << setw(25) << j <<
":" << setw(9) << pop[0][j]
477 cout <<
" | Resulting non-diffractive average impact parameter: "
480 cout <<
" | <b>:" << setw(9) << se.avNDb <<
" +- "
481 << setw(4) << sqrt(se.davNDb2) <<
" fm | "
487 cout <<
" *--- End HeavyIon fitting of parameters in "
488 <<
"nucleon collision model ---* "
491 cout <<
"HeavyIon Info: To avoid refitting, use the following settings "
492 <<
"for next run:\n HeavyIon:SigFitNGen = 0\n "
493 <<
"HeavyIon:SigFitDefPar = "
495 for (
int j = 1; j < dim; ++j ) cout <<
"," << pop[0][j];
496 for (
int j = dim; j < 8; ++j ) cout <<
",0.0";
514 getCollisions(vector<Nucleon> & proj, vector<Nucleon> & targ,
515 const Vec4 & bvec,
double & T) {
516 multiset<SubCollision> ret;
519 for (
int i = 0, N = proj.size(); i < N; ++i ) {
521 proj[i].bShift(bvec/2.0);
523 for (
int i = 0, N = targ.size(); i < N; ++i ) {
525 targ[i].bShift(-bvec/2.0);
543 const Vec4 & bvec,
double & T) {
546 multiset<SubCollision> ret =
551 for (
int ip = 0, Np = proj.size(); ip < Np; ++ip )
552 for (
int it = 0, Nt = targ.size(); it < Nt; ++it ) {
555 double b = (p.
bPos() - t.
bPos()).pT();
556 if ( b > sqrt(
sigTot()/M_PI) )
continue;
580 getCollisions(vector<Nucleon> & proj, vector<Nucleon> & targ,
581 const Vec4 & bvec,
double & T) {
584 multiset<SubCollision> ret =
589 for (
int ip = 0, Np = proj.size(); ip < Np; ++ip )
590 for (
int it = 0, Nt = targ.size(); it < Nt; ++it ) {
593 double b = (p.
bPos() - t.
bPos()).pT();
594 if ( b > sqrt(
sigTot()/M_PI) )
continue;
596 if ( b < sqrt(
sigND()/M_PI) ) {
634 inline double el(
double s1,
double s2,
double u1,
double u2) {
635 return s1/u1 > s2/u2? s2*u1: s1*u2;
648 for (
int n = 0; n <
NInt; ++n ) {
649 double rp1 =
gamma();
650 double rp2 =
gamma();
651 double rt1 =
gamma();
652 double rt2 =
gamma();
653 double s11 = pow2(rp1 + rt1)*M_PI;
654 double s12 = pow2(rp1 + rt2)*M_PI;
655 double s21 = pow2(rp2 + rt1)*M_PI;
656 double s22 = pow2(rp2 + rt2)*M_PI;
658 double stot = (s11 + s12 + s21 + s22)/4.0;
660 s.dsig2[0] += pow2(stot);
667 double avb = sqrt(2.0/M_PI)*(s11*sqrt(s11/(2.0*u11))*(1.0 - u11) +
668 s12*sqrt(s12/(2.0*u12))*(1.0 - u12) +
669 s21*sqrt(s21/(2.0*u21))*(1.0 - u21) +
670 s22*sqrt(s22/(2.0*u22))*(1.0 - u22))/12.0;
672 s.davNDb2 += pow2(avb);
674 double snd = (s11 - s11*u11 + s12 - s12*u12 +
675 s21 - s21*u21 + s22 - s22*u22)/4.0;
677 s.dsig2[1] += pow2(snd);
679 double sel = (el(s11, s22, u11, u22) + el(s12, s21, u12, u21))/2.0;
681 s.dsig2[6] += pow2(sel);
683 double swt = stot - (el(s11, s12, u11, u12) + el(s21, s22, u21, u22))/2.0;
684 double swp = stot - (el(s11, s21, u11, u21) + el(s12, s22, u12, u22))/2.0;
686 s.dsig2[4] += pow2(swp);
688 s.dsig2[3] += pow2(swt);
690 s.sig[2] += swt + swp - snd + sel - stot;
691 s.dsig2[2] += pow2(swt + swp - snd + sel - stot);
694 s.dsig2[5] += pow2(s11);
696 s.sig[7] += pow2(s11)/u11;
697 s.dsig2[7] += pow2(pow2(s11)/u11);
703 s.sig[0] /= double(NInt);
704 s.dsig2[0] = (s.dsig2[0]/double(NInt) - pow2(s.sig[0]))/
double(NInt);
706 s.sig[1] /= double(NInt);
707 s.dsig2[1] = (s.dsig2[1]/double(NInt) - pow2(s.sig[1]))/
double(NInt);
709 s.sig[2] /= double(NInt);
710 s.dsig2[2] = (s.dsig2[2]/double(NInt) - pow2(s.sig[2]))/
double(NInt);
712 s.sig[3] /= double(NInt);
713 s.dsig2[3] = (s.dsig2[3]/double(NInt) - pow2(s.sig[3]))/
double(NInt);
715 s.sig[4] /= double(NInt);
716 s.dsig2[4] = (s.dsig2[4]/double(NInt) - pow2(s.sig[4]))/
double(NInt);
718 s.sig[6] /= double(NInt);
719 s.dsig2[6] = (s.dsig2[6]/double(NInt) - pow2(s.sig[6]))/
double(NInt);
721 s.sig[5] /= double(NInt);
722 s.dsig2[5] /= double(NInt);
724 s.sig[7] /= double(NInt);
725 s.dsig2[7] /= double(NInt);
726 double bS = (s.sig[7]/s.sig[5])/(16.0*M_PI*pow2(0.19732697));
727 double b2S = pow2(bS)*(s.dsig2[7]/pow2(s.sig[7]) - 1.0 +
728 s.dsig2[5]/pow2(s.sig[5]) - 1.0)/double(NInt);
734 s.avNDb /= double(NInt);
735 s.davNDb2 = (s.davNDb2/double(NInt) - pow2(s.avNDb))/
double(NInt);
737 s.davNDb2 /= pow2(s.sig[1]);
748 if ( p.size() > 0 )
sigd = p[0];
749 if ( p.size() > 1 )
k0 = p[1];
750 if ( p.size() > 2 )
alpha = p[2];
755 vector<double> ret(3);
762 vector<double> DoubleStrikman::minParm()
const {
763 vector<double> ret(3);
770 vector<double> DoubleStrikman::maxParm()
const {
771 vector<double> ret(3);
784 static const double e = exp(1);
788 for (
int i = 0; i < k; ++i ) x += -log(rndPtr->flat());
790 if ( del == 0.0 )
return x*
r0;
793 double U = rndPtr->flat();
794 double V = rndPtr->flat();
795 double W = rndPtr->flat();
798 if ( U <= e/(e+del) ) {
799 xi = pow(V, 1.0/del);
800 if ( W <= exp(-xi) )
return r0*(x + xi);
803 if ( W <= pow(xi, del - 1.0) )
return r0*(x + xi);
814 void DoubleStrikman::shuffle(
double PND1,
double PND2,
815 double & PW1,
double & PW2) {
828 void DoubleStrikman::shuffel(
double & PEL11,
double P11,
829 double P12,
double P21,
double P22) {
830 double PEL12 = PEL11, PEL21 = PEL11, PEL22 = PEL11;
831 map<double, double *> ord;
836 map<double, double *>::iterator next = ord.begin();
837 map<double, double *>::iterator prev = next++;
838 while ( next != ord.end() ) {
839 if ( *prev->second > prev->first ) {
840 *next->second += *prev->second - prev->first;
841 *prev->second = prev->first;
852 getCollisions(vector<Nucleon> & proj, vector<Nucleon> & targ,
853 const Vec4 & bvec,
double & T) {
856 multiset<SubCollision> ret =
860 for (
int ip = 0, Np = proj.size(); ip < Np; ++ip ) {
864 for (
int it = 0, Nt = targ.size(); it < Nt; ++it ) {
873 for (
int ip = 0, Np = proj.size(); ip < Np; ++ip )
874 for (
int it = 0, Nt = targ.size(); it < Nt; ++it ) {
877 double b = (p.bPos() - t.bPos()).pT();
879 double T11 =
Tpt(p.state(), t.state(), b);
880 double T12 =
Tpt(p.state(), t.altState(), b);
881 double T21 =
Tpt(p.altState(), t.state(), b);
882 double T22 =
Tpt(p.altState(), t.altState(), b);
883 double S11 = 1.0 - T11;
884 double S12 = 1.0 - T12;
885 double S21 = 1.0 - T21;
886 double S22 = 1.0 - T22;
888 double PND11 = 1.0 - pow2(S11);
891 if ( PND11 > rndPtr->flat() ) {
898 double PND12 = 1.0 - pow2(S12);
899 double PND21 = 1.0 - pow2(S21);
900 double PWp11 = 1.0 - S11*S21;
901 double PWp21 = 1.0 - S11*S21;
902 shuffle(PND11, PND21, PWp11, PWp21);
903 double PWt11 = 1.0 - S11*S12;
904 double PWt12 = 1.0 - S11*S12;
905 shuffle(PND11, PND12, PWt11, PWt12);
907 bool wt = ( PWt11 - PND11 > (1.0 - PND11)*rndPtr->flat() );
908 bool wp = ( PWp11 - PND11 > (1.0 - PND11)*rndPtr->flat() );
925 double PND22 = 1.0 - pow2(S22);
926 double PWp12 = 1.0 - S12*S22;
927 double PWp22 = 1.0 - S12*S22;
928 shuffle(PND12, PND22, PWp12, PWp22);
929 double PWt21 = 1.0 - S21*S22;
930 double PWt22 = 1.0 - S21*S22;
931 shuffle(PND21, PND22, PWt21, PWt22);
933 double PNW11 = PNW(PWp11, PWt11, PND11);
934 double PNW12 = PNW(PWp12, PWt12, PND12);
935 double PNW21 = PNW(PWp21, PWt21, PND21);
936 double PNW22 = PNW(PWp22, PWt22, PND22);
938 double PEL = (T12*T21 + T11*T22)/2.0;
939 shuffel(PEL, PNW11, PNW12, PNW21, PNW22);
940 if ( PEL > PNW11*rndPtr->flat() ) {
974 for (
int ip = 0; ip <
Nr; ++ip ) {
977 for (
int it = 0; it <
Nr; ++it ) {
979 sTpt +=
c[ip]*
T0[ip]*
c[it]*
T0[it]*pow2(Rp + Rt)*
sigTot();
980 sT2pt +=
c[ip]*pow2(
T0[ip])*
c[it]*pow2(
T0[it])*pow2(Rp + Rt)*
sigTot();
982 for (
int jp = 0; jp <
Nr; ++jp ) {
985 for (
int jt = 0; jt <
Nr; ++jt ) {
987 double fac =
T0[ip]*
T0[jp]*
T0[it]*
T0[jt]*pow2(min(Rp + Rt, rp + rt))
989 if ( ip == jp ) sTp2t +=
c[ip]*
c[it]*
c[jt]*fac;
996 s.sig[0] /= double(NInt);
997 s.dsig2[0] = (s.dsig2[0]/double(NInt) - pow2(s.sig[0]))/
double(NInt);
999 s.sig[1] /= double(NInt);
1000 s.dsig2[1] = (s.dsig2[1]/double(NInt) - pow2(s.sig[1]))/
double(NInt);
1002 s.sig[2] /= double(NInt);
1003 s.dsig2[2] = (s.dsig2[2]/double(NInt) - pow2(s.sig[2]))/
double(NInt);
1005 s.sig[3] /= double(NInt);
1006 s.dsig2[3] = (s.dsig2[3]/double(NInt) - pow2(s.sig[3]))/
double(NInt);
1008 s.sig[4] /= double(NInt);
1009 s.dsig2[4] = (s.dsig2[4]/double(NInt) - pow2(s.sig[4]))/
double(NInt);
1011 s.sig[6] /= double(NInt);
1012 s.dsig2[6] = (s.dsig2[6]/double(NInt) - pow2(s.sig[6]))/
double(NInt);
1014 s.sig[5] /= double(NInt);
1015 s.dsig2[5] /= double(NInt);
1017 s.sig[7] /= double(NInt);
1018 s.dsig2[7] /= double(NInt);
1019 double bS = (s.sig[7]/s.sig[5])/(16.0*M_PI*pow2(0.19732697));
1020 double b2S = pow2(bS)*(s.dsig2[7]/pow2(s.sig[7]) - 1.0 +
1021 s.dsig2[5]/pow2(s.sig[5]) - 1.0)/double(NInt);
1036 unsigned int ip = 0;
1037 for (
int i = 0; i <
Nr; ++i ) {
1038 if ( ip < p.size() )
dR[i] = p[ip++];
1039 if ( ip < p.size() )
T0[i] = p[ip++];
1040 if ( ip < p.size() ) phi[i] = p[ip++];
1046 for (
int i = 0; i <
Nr; ++i ) {
1047 ret.push_back(
dR[i]);
1048 ret.push_back(
T0[i]);
1049 if ( i < Nr -1 ) ret.push_back(phi[i]);
1054 vector<double> MultiRadial::minParm()
const {
1055 return vector<double>(Nr*Nr*(Nr - 1), 0.0);
1058 vector<double> MultiRadial::maxParm()
const {
1059 return vector<double>(Nr*Nr*(Nr - 1), 1.0);
1062 void MultiRadial::setProbs() {
1064 for (
int i = 0; i < Nr - 1; ++i ) {
1065 c[i] = rProj*cos(phi[i]*M_PI/2.0);
1066 rProj *= sin(phi[i]*M_PI/2.0);
1073 double sel = rndPtr->flat();
1074 for (
int i = 0; i < Nr - 1; ++i )
1075 if ( sel < ( sum +=
c[i] ) )
return i;
1087 getCollisions(vector<Nucleon> & proj, vector<Nucleon> & targ,
1088 const Vec4 & bvec,
double & T) {
1091 multiset<SubCollision> ret =
1105 int HIInfo::addSubCollision(
const SubCollision & c) {
1109 return ++nCollSave[1];
1111 return ++nCollSave[2];
1113 return ++nCollSave[3];
1115 return ++nCollSave[4];
1117 return ++nCollSave[5];
1119 return ++nCollSave[6];
1129 int HIInfo::addProjectileNucleon(
const Nucleon & n) {
1131 switch ( n.status() ) {
1133 return ++nProjSave[1];
1135 return ++nProjSave[2];
1137 return ++nProjSave[3];
1143 int HIInfo::addTargetNucleon(
const Nucleon & n) {
1145 switch ( n.status() ) {
1147 return ++nTargSave[1];
1149 return ++nTargSave[2];
1151 return ++nTargSave[3];
1162 void HIInfo::addAttempt(
double T,
double bin,
double bweight) {
1164 nCollSave = nProjSave = nTargSave = vector<int>(10, 0);
1166 weightSave = bweight;
1167 weightSumSave += weightSave;
1169 double w = 2.0*T*bweight;
1170 double delta = w - sigmaTotSave;
1171 sigmaTotSave += delta/double(NSave);
1172 sigErr2TotSave += (delta*(w - sigmaTotSave) - sigErr2TotSave)/double(NSave);
1173 w = (2*T - T*T)*bweight;
1174 delta = w - sigmaNDSave;
1175 sigmaNDSave += delta/double(NSave);
1176 sigErr2NDSave += (delta*(w - sigmaNDSave) - sigErr2NDSave)/double(NSave);
1180 void HIInfo::accept() {
1181 int pc = primInfo.code();
1182 weightSumSave += weightSave;
1184 sumPrimW[pc] += weightSave;
1185 sumPrimW2[pc] += weightSave*weightSave;
1187 NamePrim[pc] = primInfo.nameProc(pc);
1200 cout <<
"Nucleon id: " <<
id() << endl;
1201 cout <<
"index: " <<
index() << endl;
1202 cout <<
"b(rel): " <<
nPos().px() <<
" " <<
nPos().py() << endl;
1203 cout <<
"b(abs): " <<
bPos().px() <<
" " <<
bPos().py() << endl;
1204 cout <<
"status: " <<
status() << (
done()?
" done":
" ") << endl;
1206 for (
int i = 0, N =
state().size(); i < N; ++i )
1207 cout <<
state()[i] <<
" ";
1209 for (
int j = 0, M = altStatesSave.size(); j < M; ++j ) {
1210 cout <<
"state " << j+1 <<
": ";
1211 for (
int i = 0, N = altStatesSave[j].size(); i < N; ++i )
1212 cout << altStatesSave[j][i] <<
" ";
The nucleon is absorptively wounded.
This is an absorptive (non-diffractive) collision.
Both excited but with central diffraction.
void debug()
Print out debugging information.
double sigd
Saturation scale of the nucleus.
double r0
The average radius of the nucleon.
Settings * settingsPtr
Pointers to useful objects.
virtual SigEst getSig() const
Calculate the cross sections for the given set of parameters.
bool done() const
Check if nucleon has been assigned.
const Vec4 & bPos() const
The absolute position in impact parameter space.
virtual bool init()
Virtual init method.
vector< double > c
The probability distribution.
double opacity(double sig) const
The opacity of the collision at a given sigma.
int id() const
Accessor functions:
int Nr
The number of radii.
virtual bool evolve()
Use a simlified genetic algorithm to fit the parameters.
Both projectile and target are diffractively excited.
vector< double > State
The state of a nucleon is a general vector of doubles.
SigEst getSig() const
Calculate the cross sections for the given set of parameters.
double sigDDE() const
The double diffractive excitation cross section.
void initPtr(int idIn, Settings &settingsIn, ParticleData &particleDataIn, Rndm &rndIn)
Init method.
vector< double > T0
The opacity for different radii.
double width() const
Get the width.
virtual multiset< SubCollision > getCollisions(vector< Nucleon > &proj, vector< Nucleon > &targ, const Vec4 &bvec, double &T)
virtual vector< Nucleon > generate() const
virtual void setParm(const vector< double > &)
Set the parameters of this model.
double sigND() const
The non-diffractive (absorptive) cross section.
virtual multiset< SubCollision > getCollisions(vector< Nucleon > &proj, vector< Nucleon > &targ, const Vec4 &bvec, double &T)=0
double Chi2(const SigEst &sigs, int npar) const
Calculate the Chi2 for the given cross section estimates.
const Vec4 & nPos() const
The position of this nucleon relative to the nucleus center.
double sigEl() const
The total cross section.
virtual multiset< SubCollision > getCollisions(vector< Nucleon > &proj, vector< Nucleon > &targ, const Vec4 &bvec, double &T)
This is an elastic scattering.
The projectile is diffractively excited.
virtual vector< double > getParm() const
double Rh() const
Accessor functions.
double sigSDEP() const
The single diffractive excitation cross section (excited projectile).
The nucleon is elastically scattered.
int ISave
Cache information about the nucleus.
double k0
The power in the Gamma distribution.
double RSave
The estimate of the nucleus radius.
virtual vector< double > getParm() const
virtual void setParm(const vector< double > &)
Set the parameters of this model.
virtual void setParm(const vector< double > &)
Set the parameters of this model.
double sigSDE() const
The single diffractive excitation cross section (both sides summed).
SigEst getSig() const
Calculate the cross sections for the given set of parameters.
SubCollisionModel * collPtr
Info from the controlling HeavyIons object.
The target is diffractively excited.
int id() const
Accessor functions.
double Tpt(const Nucleon::State &p, const Nucleon::State &t, double b) const
Vec4 generateNucleon() const
The nucleon is diffractively wounded.
int choose() const
Choose a radius.
double a() const
Accessor functions:
Status status() const
The status.
int index() const
The nucleon type.
double gamma() const
Generate a random number according to a Gamma-distribution.
virtual Vec4 generate(double &weight) const
virtual multiset< SubCollision > getCollisions(vector< Nucleon > &proj, vector< Nucleon > &targ, const Vec4 &bvec, double &T)
double sigCDE() const
The central diffractive excitation cross section.
double alpha
Power of the saturation scale.
virtual multiset< SubCollision > getCollisions(vector< Nucleon > &proj, vector< Nucleon > &targ, const Vec4 &bvec, double &T)
double sigTot() const
The total cross section.
virtual bool init()
Virtual init method.
const State & state() const
The physical state of the incoming nucleon.
vector< double > dR
The difference between radii.