10 #include <FairLogger.h> 
   11 #include <FairParticle.h> 
   12 #include <FairPrimaryGenerator.h> 
   13 #include <FairRunSim.h> 
   15 #include <TDatabasePDG.h> 
   16 #include <TGenPhaseSpace.h> 
   17 #include <TLorentzVector.h> 
   19 #include <TParticle.h> 
   20 #include <TParticlePDG.h> 
   33 constexpr 
float amu = 931.494;
 
   35 Int_t AtTPCIonDecay::fgNIon = 0;
 
   37 constexpr 
auto cRED = 
"\033[1;31m";
 
   40 constexpr 
auto cGREEN = 
"\033[1;32m";
 
   41 constexpr 
auto cBLUE = 
"\033[1;34m";
 
   46    : fMult(0), fPx(0.), fPy(0.), fPz(0.), fVx(0.), fVy(0.), fVz(0.), fIon(0), fParticle(0), fPType(0), fNbCases(0),
 
   47      fSepEne(0), fMasses(0), fQ(0), fPxBeam(0.), fPyBeam(0.), fPzBeam(0.)
 
   55                              std::vector<std::vector<Int_t>> *q, std::vector<std::vector<Double_t>> *mass, Int_t ZB,
 
   56                              Int_t AB, Double_t BMass, Double_t TMass, Double_t ExEnergy, std::vector<Double_t> *SepEne)
 
   57    : fMult(0), fNbCases(a->size()), fPx(0.), fPy(0.), fPz(0.), fVx(0.), fVy(0.), fVz(0.), fIon(0), fParticle(0),
 
   58      fPType(0), fSepEne(0), fMasses(0), fQ(0), fPxBeam(0.), fPyBeam(0.), fPzBeam(0.)
 
   65    for (Int_t i = 0; i < fNbCases; i++)
 
   66       fMult.push_back(a->at(i).size());
 
   67    fParticle.resize(fNbCases);
 
   68    fIon.resize(fNbCases);
 
   69    fPType.resize(fNbCases);
 
   73    fBeamMass = BMass * 
amu / 1000.0;
 
   74    fTargetMass = TMass * 
amu / 1000.0;
 
   77    fIsSequentialDecay = kFALSE;
 
   80    FairRunSim *run = FairRunSim::Instance();
 
   82       std::cout << 
"-E- FairIonGenerator: No FairRun instantised!" << std::endl;
 
   83       Fatal(
"FairIonGenerator", 
"No FairRun instantised!");
 
   87    for (Int_t k = 0; k < fNbCases; k++) {
 
   88       for (Int_t i = 0; i < fMult.at(k); i++) {
 
   90          std::unique_ptr<FairIon> IonBuff = 
nullptr;
 
   91          std::unique_ptr<FairParticle> ParticleBuff = 
nullptr;
 
   92          sprintf(buffer, 
"Product_Ion_dec%d_%d", k, i);
 
   93          if (a->at(k).at(i) != 1) {
 
   94             IonBuff = std::make_unique<FairIon>(buffer, z->at(k).at(i), a->at(k).at(i), q->at(k).at(i), 0.0,
 
   95                                                 mass->at(k).at(i) * 
amu / 1000.0);
 
   96             ParticleBuff = std::make_unique<FairParticle>(
"dummyPart", 1, 1, 1.0, 0, 0.0, 0.0);
 
   97             fPType.at(k).push_back(
"Ion");
 
   98             run->AddNewIon(IonBuff.get());
 
  100          } 
else if (a->at(k).at(i) == 1 && z->at(k).at(i) == 1) {
 
  101             IonBuff = std::make_unique<FairIon>(buffer, z->at(k).at(i), a->at(k).at(i), q->at(k).at(i), 0.0,
 
  102                                                 mass->at(k).at(i) * 
amu / 1000.0);
 
  103             auto *kProton = 
new TParticle(); 
 
  104             kProton->SetPdgCode(2212);
 
  105             ParticleBuff = std::make_unique<FairParticle>(2212, kProton);
 
  106             fPType.at(k).push_back(
"Proton");
 
  108          } 
else if (a->at(k).at(i) == 1 && z->at(k).at(i) == 0) {
 
  109             IonBuff = std::make_unique<FairIon>(buffer, z->at(k).at(i), a->at(k).at(i), q->at(k).at(i), 0.0,
 
  110                                                 mass->at(k).at(i) * 
amu / 1000.0);
 
  111             auto *kNeutron = 
new TParticle(); 
 
  112             kNeutron->SetPdgCode(2112);
 
  113             ParticleBuff = std::make_unique<FairParticle>(2112, kNeutron);
 
  114             fPType.at(k).push_back(
"Neutron");
 
  116          fIon.at(k).push_back(std::move(IonBuff));
 
  117          fParticle.at(k).push_back(std::move(ParticleBuff));
 
  127    Bool_t IsGoodCase = kFALSE;
 
  129    Double_t excitationEnergy = 0.0;
 
  131    LOG(INFO) << 
cBLUE << 
" AtTPCIonDecay - Decay energy -  Excitation energy from reaction :  " << ExEject
 
  132              << 
" and from task : " << fExEnergy
 
  134              << fIsSequentialDecay << 
cNORMAL << 
"\n";
 
  136              << 
" AtTPCIonDecay - Warning: Temporary warning message to control the flow of generators.Please, check " 
  137                 "that if the decay comes from beam fusion, the energy from reaction is 0" 
  140    if (ExEject > 0.0 && !fIsSequentialDecay) {
 
  142                 << 
" AtTPCIonDecay - Warning, Inconsistent variables: Recoil excitation energy from Vertex propagator " 
  143                    "greater than 0 but sequential decay not enabled! Continue at your own risk!" 
  146    } 
else if (fIsSequentialDecay && fExEnergy > 0.0) {
 
  149                 << 
" AtTPCIonDecay - Warning, Inconsistent variables: Sequential decay should take the Ex energy from " 
  150                    "the reaction generator! Continue at your own risk!" 
  153    } 
else if (ExEject > 0.0 && fExEnergy > 0.0) {
 
  156          << 
" AtTPCIonDecay - Warning, Inconsistent variables: Both, excitation energy from Vertex propagator and " 
  157             "excitation energy from task (introduced through the macro) are positive! Continue at your own risk!" 
  161    std::vector<Int_t> GoodCases;
 
  164    for (Int_t i = 0; i < fNbCases; i++) {
 
  167          GoodCases.push_back(i);
 
  172       int RandVar = (int)(GoodCases.size()) * gRandom->Uniform();
 
  173       auto it = GoodCases.begin();
 
  174       std::advance(it, RandVar);
 
  180       Double_t mass_1[10] = {0.0};
 
  183       TLorentzVector fEnergyImpulsionLab_beam;
 
  184       TLorentzVector fEnergyImpulsionLab_Total;
 
  185       TLorentzVector fEnergyImpulsionLab_target;
 
  186       TLorentzVector fEnergyImpulsionFinal;
 
  188       TVector3 fImpulsionLab_beam;
 
  189       std::vector<TLorentzVector *> p_vector;
 
  190       TGenPhaseSpace event1;
 
  196       fPx.resize(fMult.at(Case));
 
  197       fPy.resize(fMult.at(Case));
 
  198       fPz.resize(fMult.at(Case));
 
  204       if (fIsSequentialDecay) 
 
  211          excitationEnergy = ExEject; 
 
  217          excitationEnergy = fExEnergy; 
 
  220       TParticlePDG *thisPart0 = 
nullptr;
 
  221       thisPart0 = TDatabasePDG::Instance()->GetParticle(
 
  222          fIon.at(Case).at(0)->GetName()); 
 
  223       int pdgType0 = thisPart0->PdgCode();
 
  225       LOG(INFO) << 
cBLUE << 
" Ejectile info : " << pdgType0 << 
" " << fBeamMass << 
" " << fPxBeam << 
" " << fPyBeam
 
  226                 << 
" " << fPzBeam << 
" " << fBeamEnergy << 
" " << excitationEnergy << 
cNORMAL << 
"\n";
 
  230       fImpulsionLab_beam = TVector3(fPxBeam, fPyBeam, fPzBeam);
 
  231       fEnergyImpulsionLab_beam = TLorentzVector(fImpulsionLab_beam, fBeamMass + fBeamEnergy + ExEject);
 
  232       fEnergyImpulsionLab_target = TLorentzVector(TVector3(0, 0, 0), fTargetMass);
 
  234       if (fTargetMass > 0 && fIsSequentialDecay) {
 
  237             << 
" AtTPCIonDecay - Warning, Inconsistent variables: Target Impulsion included in sequential decay. " 
  238                "Continue at your own risk!" 
  242       fEnergyImpulsionLab_Total = fEnergyImpulsionLab_beam + fEnergyImpulsionLab_target;
 
  244       s = fEnergyImpulsionLab_Total.M2();
 
  247       for (Int_t i = 0; i < fMult.at(Case); i++) {
 
  248          M_tot += fMasses.at(Case).at(i) * 
amu / 1000.0;
 
  249          mass_1[i] = fMasses.at(Case).at(i) * 
amu / 1000.0;
 
  250          std::cout << fMasses.at(Case).at(i) * 
amu / 1000.0 << 
" " << M_tot << 
" " << fBeamMass << 
" " 
  251                    << fBeamMass - M_tot << 
" " << ExEject << 
" " << sqrt(s) << 
" " << (sqrt(s) - M_tot) * 1000.0
 
  258       if (s > pow(M_tot, 2)) {
 
  261          event1.SetDecay(fEnergyImpulsionLab_Total, fMult.at(Case), mass_1);
 
  263          std::vector<Double_t> KineticEnergy;
 
  264          std::vector<Double_t> ThetaLab;
 
  266          LOG(INFO) << 
cBLUE << 
" AtTPCIonDecay -  Phase Space Information " 
  268          for (Int_t i = 0; i < fMult.at(Case); i++) {
 
  269             p_vector.push_back(event1.GetDecay(i));
 
  270             fPx.at(i) = p_vector.at(i)->Px();
 
  271             fPy.at(i) = p_vector.at(i)->Py();
 
  272             fPz.at(i) = p_vector.at(i)->Pz();
 
  273             KineticEnergy.push_back((p_vector.at(i)->E() - mass_1[i]) * 1000.0);
 
  274             ThetaLab.push_back(p_vector.at(i)->Theta() * 180. / TMath::Pi());
 
  275             LOG(INFO) << 
" Particle " << i << 
" - TKE (MeV) : " << KineticEnergy.at(i)
 
  276                       << 
" - Lab Angle (deg) : " << ThetaLab.at(i) << 
"\n";
 
  282          LOG(INFO) << 
cYELLOW << 
"AtTPCIonDecay - Warning, kinematical conditions for decay not fulfilled " << 
cNORMAL 
  284          LOG(INFO) << 
cYELLOW << 
" s = " << s << 
" - pow(M_tot,2) = " << pow(M_tot, 2) << 
cNORMAL << 
"\n";
 
  289       for (Int_t i = 0; i < fMult.at(Case); i++) {
 
  290          TParticlePDG *thisPart = 
nullptr;
 
  292          if (fPType.at(Case).at(i) == 
"Ion")
 
  293             thisPart = TDatabasePDG::Instance()->GetParticle(fIon.at(Case).at(i)->GetName());
 
  294          else if (fPType.at(Case).at(i) == 
"Proton")
 
  295             thisPart = TDatabasePDG::Instance()->GetParticle(fParticle.at(Case).at(i)->GetName());
 
  296          else if (fPType.at(Case).at(i) == 
"Neutron")
 
  297             thisPart = TDatabasePDG::Instance()->GetParticle(fParticle.at(Case).at(i)->GetName());
 
  300             if (fPType.at(Case).at(i) == 
"Ion")
 
  301                std::cout << 
"-W- FairIonGenerator: Ion " << fIon.at(Case).at(i)->GetName() << 
" not found in database!" 
  303             else if (fPType.at(Case).at(i) == 
"Proton")
 
  304                std::cout << 
"-W- FairIonGenerator: Particle " << fParticle.at(Case).at(i)->GetName()
 
  305                          << 
" not found in database!" << std::endl;
 
  306             else if (fPType.at(Case).at(i) == 
"Neutron")
 
  307                std::cout << 
"-W- FairIonGenerator: Particle " << fParticle.at(Case).at(i)->GetName()
 
  308                          << 
" not found in database!" << std::endl;
 
  312          int pdgType = thisPart->PdgCode();
 
  332             primGen->AddTrack(pdgType, fPx.at(i), fPy.at(i), fPz.at(i), fVx, fVy, fVz);