78 : verboseLevel(0), eex_rest(0), on_shell(false) {
80 G4cout <<
" >>> G4CollisionOutput::G4CollisionOutput" <<
G4endl;
87 verboseLevel = right.verboseLevel;
88 outgoingParticles = right.outgoingParticles;
89 outgoingNuclei = right.outgoingNuclei;
90 theRecoilFragment = right.theRecoilFragment;
91 eex_rest = right.eex_rest;
92 on_shell = right.on_shell;
98 outgoingNuclei.clear();
99 outgoingParticles.clear();
109 theRecoilFragment = right.theRecoilFragment;
116 outgoingParticles.insert(outgoingParticles.end(),
117 particles.begin(), particles.end());
121 outgoingNuclei.insert(outgoingNuclei.end(), nuclea.begin(), nuclea.end());
131 for (
unsigned i=0; i<cparticles.size(); i++)
138 if (!rproducts)
return;
141 G4cout <<
" >>> G4CollisionOutput::addOutgoingParticles(G4RPVector)"
145 G4ReactionProductVector::const_iterator j;
146 for (j=rproducts->begin(); j!=rproducts->end(); ++j) {
156 <<
"), momentum " << mom <<
" GeV" <<
G4endl;
164 if (verboseLevel>1)
G4cout << outgoingParticles.back() <<
G4endl;
170 if (verboseLevel>1)
G4cout << outgoingNuclei.back() <<
G4endl;
180 outgoingParticles.erase(outgoingParticles.begin()+(
size_t)index);
185 outgoingNuclei.erase(outgoingNuclei.begin()+(
size_t)index);
192 std::find(outgoingParticles.begin(), outgoingParticles.end(), particle);
193 if (pos != outgoingParticles.end()) outgoingParticles.erase(pos);
198 std::find(outgoingNuclei.begin(), outgoingNuclei.end(), nuclei);
199 if (pos != outgoingNuclei.end()) outgoingNuclei.erase(pos);
206 theRecoilFragment = emptyFragment;
212 if (verboseLevel > 1)
213 G4cout <<
" >>> G4CollisionOutput::getTotalOutputMomentum" <<
G4endl;
217 for(i=0; i <
G4int(outgoingParticles.size()); i++) {
218 tot_mom += outgoingParticles[i].getMomentum();
220 for(i=0; i <
G4int(outgoingNuclei.size()); i++) {
221 tot_mom += outgoingNuclei[i].getMomentum();
229 if (verboseLevel > 1)
230 G4cout <<
" >>> G4CollisionOutput::getTotalCharge" <<
G4endl;
234 for(i=0; i <
G4int(outgoingParticles.size()); i++) {
235 charge +=
G4int(outgoingParticles[i].getCharge());
237 for(i=0; i <
G4int(outgoingNuclei.size()); i++) {
238 charge +=
G4int(outgoingNuclei[i].getCharge());
246 if (verboseLevel > 1)
247 G4cout <<
" >>> G4CollisionOutput::getTotalBaryonNumber" <<
G4endl;
251 for(i=0; i <
G4int(outgoingParticles.size()); i++) {
252 baryon += outgoingParticles[i].baryon();
254 for(i=0; i <
G4int(outgoingNuclei.size()); i++) {
255 baryon +=
G4int(outgoingNuclei[i].getA());
263 if (verboseLevel > 1)
264 G4cout <<
" >>> G4CollisionOutput::getTotalStrangeness" <<
G4endl;
268 for(i=0; i <
G4int(outgoingParticles.size()); i++) {
269 strange += outgoingParticles[i].getStrangeness();
277 os <<
" Output: " <<
G4endl
278 <<
" Outgoing Particles: " << outgoingParticles.size() <<
G4endl;
281 for(i=0; i <
G4int(outgoingParticles.size()); i++)
282 os << outgoingParticles[i] <<
G4endl;
284 os <<
" Outgoing Nuclei: " << outgoingNuclei.size() <<
G4endl;
285 for(i=0; i <
G4int(outgoingNuclei.size()); i++)
286 os << outgoingNuclei[i] <<
G4endl;
288 if (theRecoilFragment.
GetA() > 0) os << theRecoilFragment <<
G4endl;
295 if (verboseLevel > 1)
296 G4cout <<
" >>> G4CollisionOutput::boostToLabFrame" <<
G4endl;
298 if (!outgoingParticles.empty()) {
300 for(; ipart != outgoingParticles.end(); ipart++) {
304 std::sort(outgoingParticles.begin(), outgoingParticles.end(),
308 if (!outgoingNuclei.empty()) {
310 for (; inuc != outgoingNuclei.end(); inuc++) {
315 if (theRecoilFragment.
GetA() > 0.) {
325 mom = convertor.
rotate(mom);
334 if (verboseLevel > 1)
335 G4cout <<
" >>> G4CollisionOutput::rotateEvent" <<
G4endl;
338 for(; ipart != outgoingParticles.end(); ipart++)
339 ipart->setMomentum(ipart->getMomentum()*=rotate);
342 for (; inuc != outgoingNuclei.end(); inuc++)
343 inuc->setMomentum(inuc->getMomentum()*=rotate);
345 if (theRecoilFragment.
GetA() > 0.) {
355 if (verboseLevel > 1)
356 G4cout <<
" >>> G4CollisionOutput::trivialize" <<
G4endl;
361 outgoingNuclei.push_back(*nuclei_target);
365 outgoingParticles.push_back(*particle);
369 outgoingNuclei.push_back(*nuclei_bullet);
373 outgoingParticles.push_back(*particle);
380 if (verboseLevel > 1)
381 G4cout <<
" >>> G4CollisionOutput::setOnShell" <<
G4endl;
390 if(verboseLevel > 2){
391 G4cout <<
" bullet momentum = " << ini_mom.
e() <<
", "<< ini_mom.
x() <<
", "<< ini_mom.
y()<<
", "<< ini_mom.
z()<<
G4endl;
392 G4cout <<
" target momentum = " << momt.
e()<<
", "<< momt.
x()<<
", "<< momt.
y()<<
", "<< momt.
z()<<
G4endl;
393 G4cout <<
" Fstate momentum = " << out_mom.
e()<<
", "<< out_mom.
x()<<
", "<< out_mom.
y()<<
", "<< out_mom.
z()<<
G4endl;
404 if(verboseLevel > 2) {
407 <<
" e " << enc <<
" p " << pnc <<
G4endl
408 <<
" remaining exitation " << eex_rest <<
G4endl;
411 if (std::fabs(enc) <= accuracy && pnc <= accuracy) {
419 if (verboseLevel > 2)
G4cout <<
" re-balancing four-momenta" <<
G4endl;
421 G4int npart = outgoingParticles.size();
422 G4int nnuc = outgoingNuclei.size();
425 for (
G4int ip=npart-1; ip>=0; ip--) {
426 if (outgoingParticles[ip].getKineticEnergy()+enc > 0.) {
428 last_mom += mom_non_cons;
429 outgoingParticles[ip].setMomentum(last_mom);
433 }
else if (nnuc > 0) {
434 for (
G4int in=nnuc-1; in>=0; in--) {
435 if (outgoingNuclei[in].getKineticEnergy()+enc > 0.) {
437 last_mom += mom_non_cons;
438 outgoingNuclei[in].setMomentum(last_mom);
442 }
else if (theRecoilFragment.
GetA() > 0.) {
445 if ((last_mom.
e()-last_mom.
m())+enc > 0.) {
446 last_mom += mom_non_cons;
453 mom_non_cons = ini_mom - out_mom;
454 pnc = mom_non_cons.
rho();
455 enc = mom_non_cons.
e();
457 if(verboseLevel > 2){
459 G4cout <<
" momentum non conservation after (1): " <<
G4endl
460 <<
" e " << enc <<
" p " << pnc <<
G4endl;
464 G4bool need_hard_tuning =
true;
466 G4double encMeV = mom_non_cons.
e() / GeV;
467 if (theRecoilFragment.
GetA() > 0.) {
469 if (eex > 0.0 && eex + encMeV >= 0.0) {
476 need_hard_tuning =
false;
478 }
else if (outgoingNuclei.size() > 0) {
479 for (
G4int i=0; i <
G4int(outgoingNuclei.size()); i++) {
480 G4double eex = outgoingNuclei[i].getExitationEnergy();
482 if(eex > 0.0 && eex + encMeV >= 0.0) {
483 outgoingNuclei[i].setExitationEnergy(eex+encMeV);
484 need_hard_tuning =
false;
488 if (need_hard_tuning && encMeV > 0.) {
489 outgoingNuclei[0].setExitationEnergy(encMeV);
490 need_hard_tuning =
false;
494 if (!need_hard_tuning) {
500 if (verboseLevel > 2)
501 G4cout <<
" trying hard (particle-pair) tuning" <<
G4endl;
503 std::pair<std::pair<G4int, G4int>,
G4int> tune_par = selectPairToTune(mom_non_cons.
e());
504 std::pair<G4int, G4int> tune_particles = tune_par.first;
505 G4int mom_ind = tune_par.second;
507 if(verboseLevel > 2) {
508 G4cout <<
" p1 " << tune_particles.first <<
" p2 " << tune_particles.second
509 <<
" ind " << mom_ind <<
G4endl;
513 (tune_particles.first >= 0 && tune_particles.second >= 0 &&
516 if (!tuning_possible) {
517 if (verboseLevel > 2)
G4cout <<
" tuning impossible " <<
G4endl;
521 G4LorentzVector mom1 = outgoingParticles[tune_particles.first].getMomentum();
522 G4LorentzVector mom2 = outgoingParticles[tune_particles.second].getMomentum();
523 G4double newE12 = mom1.
e() + mom2.
e() + mom_non_cons.
e();
524 G4double R = 0.5 * (newE12 * newE12 + mom2.
e() * mom2.
e() - mom1.
e() * mom1.
e()) / newE12;
525 G4double Q = -(mom1[mom_ind] + mom2[mom_ind]) / newE12;
527 G4double W = (R * Q + mom2[mom_ind]) * UDQ;
528 G4double V = (mom2.
e() * mom2.
e() - R * R) * UDQ;
537 G4double x1 = -(W + std::sqrt(DET));
538 G4double x2 = -(W - std::sqrt(DET));
544 if(mom_non_cons.
e() > 0.0) {
546 if(R + Q * x1 >= 0.0) {
551 if(!xset && x2 > 0.0) {
552 if(R + Q * x2 >= 0.0) {
559 if(R + Q * x1 >= 0.) {
564 if(!xset && x2 < 0.0) {
565 if(R + Q * x2 >= 0.0) {
581 outgoingParticles[tune_particles.first ].setMomentum(mom1);
582 outgoingParticles[tune_particles.second].setMomentum(mom2);
585 mom_non_cons = ini_mom - out_mom;
586 pnc = mom_non_cons.
rho();
587 enc = mom_non_cons.
e();
589 on_shell = (std::fabs(enc) < accuracy || pnc < accuracy);
591 if(verboseLevel > 2) {
592 G4cout <<
" momentum non conservation tuning: " <<
G4endl
593 <<
" e " << enc <<
" p " << pnc
594 << (on_shell?
" success":
" FAILURE") <<
G4endl;
604 for(
G4int i=0; i <
G4int(outgoingNuclei.size()); i++)
605 eex_rest += outgoingNuclei[i].getExitationEnergyInGeV();
609std::pair<std::pair<G4int, G4int>,
G4int>
610G4CollisionOutput::selectPairToTune(
G4double de)
const {
611 if (verboseLevel > 2)
612 G4cout <<
" >>> G4CollisionOutput::selectPairToTune" <<
G4endl;
614 std::pair<G4int, G4int> tup(-1, -1);
616 std::pair<std::pair<G4int, G4int>,
G4int> tuner(tup, i3);
618 if (outgoingParticles.size() < 2)
return tuner;
623 G4double pcut = 0.3 * std::sqrt(1.88 * std::fabs(de));
626 for (
G4int i = 0; i <
G4int(outgoingParticles.size())-1; i++) {
629 for (
G4int j = i+1; j <
G4int(outgoingParticles.size()); j++) {
633 if (mom1[l]*mom2[l]<0.0) {
634 if (std::fabs(mom1[l])>pcut && std::fabs(mom2[l])>pcut) {
635 G4double psum = std::fabs(mom1[l]) + std::fabs(mom2[l]);
650 if (i3 < 0)
return tuner;
656 tuner.first.first = (p1>0.) ? ibest1 : ibest2;
657 tuner.first.second = (p1>0.) ? ibest2 : ibest1;
659 tuner.first.first = (p1<0.) ? ibest2 : ibest1;
660 tuner.first.second = (p1<0.) ? ibest1 : ibest2;
std::vector< G4InuclElementaryParticle >::iterator particleIterator
std::vector< G4InuclNuclei >::const_iterator nucleiIterator
std::vector< G4InuclNuclei >::iterator nucleiIterator
std::vector< G4InuclElementaryParticle >::iterator particleIterator
std::vector< G4ReactionProduct * > G4ReactionProductVector
G4DLLIMPORT std::ostream G4cout
void setVectM(const Hep3Vector &spatial, double mass)
const G4InuclElementaryParticle & getParticle() const
G4int numberOfOutgoingParticles() const
G4int getTotalStrangeness() const
void setRemainingExitationEnergy()
G4LorentzVector getTotalOutputMomentum() const
G4CollisionOutput & operator=(const G4CollisionOutput &right)
G4int getTotalBaryonNumber() const
void boostToLabFrame(const G4LorentzConvertor &convertor)
void rotateEvent(const G4LorentzRotation &rotate)
void removeOutgoingNucleus(G4int index)
void printCollisionOutput(std::ostream &os=G4cout) const
void addOutgoingParticle(const G4InuclElementaryParticle &particle)
G4int getTotalCharge() const
void setOnShell(G4InuclParticle *bullet, G4InuclParticle *target)
G4int numberOfOutgoingNuclei() const
void add(const G4CollisionOutput &right)
void trivialise(G4InuclParticle *bullet, G4InuclParticle *target)
void addOutgoingNuclei(const std::vector< G4InuclNuclei > &nuclea)
void removeOutgoingParticle(G4int index)
void removeRecoilFragment()
void addOutgoingParticles(const std::vector< G4InuclElementaryParticle > &particles)
G4double GetExcitationEnergy() const
const G4LorentzVector & GetMomentum() const
void SetMomentum(const G4LorentzVector &value)
G4LorentzVector getMomentum() const
G4bool reflectionNeeded() const
G4LorentzVector backToTheLab(const G4LorentzVector &mom) const
G4LorentzVector rotate(const G4LorentzVector &mom) const
G4int GetAtomicNumber() const
G4int GetAtomicMass() const
const G4String & GetParticleName() const