#include "TString.h" #include "TObjArray.h" #include "TObjString.h" #include "TFile.h" #include "TNtuple.h" #include "TSystem.h" #include "TRandom.h" #include "hphysicsconstants.h" #include "hseed.h" #include "PParticle.h" #include "PChannel.h" #include "PFixedDecay.h" #include "PFireball.h" #include "PDoubleFireball.h" #include "PReaction.h" #include "PEmbeddedParticles.h" #include "PHGeantOutput.h" #include "PVertexFile.h" #include #include #include #include #include //---------------------------------------------------------------- // DATABASE HELPERS typedef struct { TString type; TString channel; Float_t T1; Float_t T2; Float_t fracT1; Float_t blast; Float_t A2; Float_t A4; Float_t V1; Float_t V2; Float_t eta; PFireball* source; vector vch; // list of channels vector vm; // mother of decays vector > vd; // daughters of decays PChannel** cfinal; void clear(){ type = ""; channel = ""; T1 = 0; T2 = 0; fracT1 = 0; blast= 0; A2 = 0; A4 = 0; V1 = 0; V2 = 0; eta = 0; source = 0; cfinal = 0; vch.clear(); vm.clear(); for(UInt_t i = 0; i < vd.size(); i++) { vd[i].clear();} } void print(Int_t i=-1){ if(i < 0) { cout< > mEtoDecay; void print(){ cout<<"#######################################################################################"< >::iterator it; it = mEtoDecay.find(energy); if(it == mEtoDecay.end()) { cout<<"ERROR : energy = "<second.size(); i++){ if(it->second[i]->type == type){ ret = kTRUE; return it->second[i]; } } cout<<"ERROR : type = "<GetEntries(); i++){ TObjString* s = (TObjString*) a->At(i); TString t = s->GetString(); vp.push_back(new PParticle(t.Data())); if(print) cout<<"getParticle() : "<channel; channel.ReplaceAll(" ",""); // no spaces allowed in channel descriptor Ssiz_t i = channel.First(":"); // format examples: "eta:e+,e-,..." or 'pi0:dilepton[e+e-],g' TString mother = channel(0,i); // main particle for the channel channel.Remove(0, i+1); //---------------------------------------------- // looping the channel descriptor and defining the different decay levels TString l [10]; // level of decay by appearance of '[' in channel (max 10), comma separated particles as string TString ml [10]; // decay mother of level as string Int_t ind [10]; Int_t indm[10]; for(Int_t i = 0; i < 10; i++) { ind[i] = 0; indm[i] = 0; } vector vl [10]; // PParticles of decay level Int_t level = 0; Int_t max = 0; ml[0] = mother; // level 0 has the main particle as mother d->vm.push_back(new PParticle(ml[0].Data())); // create a PParticle for the main particle for(Int_t i = 0; i < channel.Length(); i++){ Char_t c = channel[i]; if (c == '[' ) { // new decay level++; if(level > max ) max = level; Int_t j = i; // loop back to last , or begin of string to find mother of decay for(; j > 0; j--){ Char_t ds = channel[j]; if (ds == ',' || ds == '[' ) { j++; break; } } ml [level] = channel(j,i-j); // mother of this decay indm[level] = ind[level-1]; // remember the index of mother particle continue; } if (c == ']' ) { // end decay level--; continue; } if (c == ',') ind[level]++; // remember the index of mother particle l[level] += channel[i]; // will end up as comma separated particle list per level } //---------------------------------------------- //---------------------------------------------- // setup Fireball or DoubleFireball source if(d->eta == 0){ d->source = new PFireball ((Char_t*)ml[0].Data() ,Energy,d->T1,d->T2,d->fracT1,d->blast, d->A2,d->A4,d->V1,d->V2); } else { d->source = new PDoubleFireball((Char_t*)ml[0].Data() ,Energy,d->T1,d->T2,d->fracT1,d->blast,d->eta,d->A2,d->A4,d->V1,d->V2); } d->source->setTrueThermal(kTRUE); d->source->Print(); PParticle *moth = d->vm[0]; // the mother of the decay is the main particle PParticle** smoth = new PParticle* [2]; // connect mother to Fireball smoth[0] = d->source; smoth[1] = moth; PChannel* cmoth = new PChannel(smoth, 1, 1); // create a channel for the Fireball d->vch.push_back(cmoth); // add to the list of channels //---------------------------------------------- if( !(max == 0 && mother == l[0])) { // not a fireball particle without decay inside PLUTO //---------------------------------------------- // analyze the level strings to build the decay channels // for PReaction for(Int_t i = 0 ; i < max+1; i++){ cout<<"decay level "< PParticles d->vd.push_back(vl[i]); if(i > 0) { // find the mother of decay d->vm.push_back(vl[i-1][indm[i]]) ; TString n = HPhysicsConstants::pid(d->vm[i]->ID()); if( n != ml[i] ){ cout<<"############################################################"<vm[i] ; // mother of this decay for(UInt_t j = 0; j < vl[i].size(); j++){ s[j+1] = vl[i][j]; // add daughters } d->vch.push_back(new PChannel(s,vl[i].size(),1)); // add to channel list //---------------------------------------------- } } //---------------------------------------------- // build the final channel from collect channels above cout<<"############################################################"<type<channel<cfinal = new PChannel* [d->vch.size()]; for(UInt_t i = 0 ; i < d->vch.size(); i++){ d->cfinal[i] = d->vch[i]; d->cfinal[i] ->PrintReaction(); } cout<<"############################################################"<AccessPathName(infile.Data()) != 0){ cout<<"############################################################"< >::iterator it; while(in.good()){ in.getline(line,800); TString tmp = line; tmp.ReplaceAll(" ",""); if(tmp.Contains("//")) continue; if(tmp.Contains("#")) continue; if(tmp.CompareTo("")==0) continue; if(tmp.Contains("beamtime")){ tmp.ReplaceAll("beamtime=",""); datBase.beamtime = tmp; continue; } if(tmp.Contains("beamenergy")){ tmp.ReplaceAll("beamenergy=",""); energy = tmp.Atof(); continue; } thermaldecay* d = new thermaldecay; d->clear(); TObjArray* a = tmp.Tokenize(";"); if(a){ for(Int_t i = 0 ; i < a->GetEntries(); i++){ TObjString* s = (TObjString*) a->At(i); TString t = s->GetString(); t.ReplaceAll(";",""); if( t.Contains("type" ) !=0){ t.ReplaceAll("type=",""); d->type = t; } else if (t.Contains("channel" )!=0){ t.ReplaceAll("channel=",""); d->channel = t; } else if (t.Contains("T1" )!=0 && t.Contains("fracT1" )==0){ t.ReplaceAll("T1=",""); d->T1 = t.Atof(); } else if (t.Contains("T2" )!=0){ t.ReplaceAll("T2=",""); d->T2 = t.Atof(); } else if (t.Contains("fracT1" )!=0){ t.ReplaceAll("fracT1=",""); d->fracT1 = t.Atof(); } else if (t.Contains("blast")!=0){ t.ReplaceAll("blast=",""); d->blast = t.Atof(); } else if (t.Contains("A2" )!=0){ t.ReplaceAll("A2=",""); d->A2 = t.Atof(); } else if (t.Contains("A4" )!=0){ t.ReplaceAll("A4=",""); d->A4 = t.Atof(); } else if (t.Contains("V1" )!=0){ t.ReplaceAll("V1=",""); d->V1 = t.Atof(); } else if (t.Contains("V2" )!=0){ t.ReplaceAll("V2=",""); d->V2 = t.Atof(); } else if (t.Contains("eta" )!=0){ t.ReplaceAll("eta=",""); d->eta = t.Atof(); } } delete a; //-------------------------------------------------------- // add decay to the list odf decays for this energy it = datBase.mEtoDecay.find(energy); if(it == datBase.mEtoDecay.end()){ // create a new Set vector vd; vd.push_back(d); datBase.mEtoDecay [energy] = vd; } else { it->second.push_back(d); } //-------------------------------------------------------- } } return kTRUE; } }; // END DATABASE HELPERS //---------------------------------------------------------------- Int_t pluto_embedded(TString outdir = "./", TString outfile = "test",TString type = "pi0", Int_t nEvents = 1000, Int_t source = 1,Float_t Energy = 1.58, TString datbasefile = "database_mar19.dat", TString vertexntuple = "") { //------------------------------------------------- // RANDOM SEED // method; 0 (default) : /dev/random, // 1 : TRandom3 (local) with systime , // 2 : TRandom3 (local) with systime + processid + iplast, // 3 : like 1 but gRandom, // 4 : like 2 but gRandom, // 5 : fixed (needs seed to be set) Int_t method = 0; HSeed hseed(method); Int_t seed = hseed.getSeed(); PUtils::SetSeed(seed); UInt_t seed2 = (Int_t)PUtils::sampleFlat()*kMaxUInt; gRandom->SetSeed(seed2); // workarround for pluto BUG (new in 5.43 fixed in 5.45) //------------------------------------------------- //---------------CONIGURATION---------------------- // Bool_t useVertex = kFALSE; if(vertexntuple.CompareTo("no") != 0 && vertexntuple.CompareTo("") != 0) useVertex = kTRUE; Int_t sourceType = source; // 0 : white single tracks , 1 : thermal source Int_t asciiOut = 0; // write pluto ascci output for HGeant (==0 if we use HGeantOutput) Int_t rootOut = 0; // write pluto root file Int_t calcVertex = useVertex ? 1 : 0; // write the vertex to the ascii output for HGeant Bool_t writeSeqNumber = useVertex ? kTRUE : kFALSE; // write eventSeqNumber in addition Bool_t writeIndex = useVertex ? kTRUE : kFALSE; // write parentIndex in addition //------------------------------------------------- // OUTPUT FILE outfile = gSystem->BaseName(outfile.Data()); TString filename = Form("%s/%s",outdir.Data(),outfile.Data()); filename.ReplaceAll("//","/"); filename.ReplaceAll(".root",""); filename.ReplaceAll(".evt",""); //filename = Form("%s_pluto_%s",filename.Data(),type.Data()); cout<<"############################################################"<AddParticle(particle); //Just add the particle to the container: if (1) { // nparticle / sector embedded->SetSamplingSector(pmin, pmax, thetamin, thetamax, phimin, phimax, phistart, numParticlePerSector ); } else { // nparticle / full acceptance embedded->SetSamplingSector(pmin, pmax, thetamin, thetamax, -180., 180., phistart, numParticlePerSector, 360., 1); } r->AddBulk(embedded); //Add our container to the reaction: } else { // thermal sources database datBase; if(!datBase.readDataBase(datBase,datbasefile)) return 1; //datBase.print(); Bool_t ret = kFALSE; thermaldecay* d = datBase.getDecayParams(ret,Energy,type); if(d){ cout<<"############################################################"<print(); cout<<"############################################################"<type == "rho0"){ // code provided by S. Harabasz 28.11.2024 cout<<"############################################################"<Add("rho0, parent"); pmodel->Add("e+, daughter"); pmodel->Add("e-, daughter"); makeDistributionManager()->Add(pmodel); //This enables the model makeDistributionManager()->Enable("rho0_ee_e-_e+"); //Enable this for removing the pi-cutoff: makeDistributionManager()->Print("decay_models"); //Finally check what we have done: } //makeDistributionManager()->Disable("eta_physics"); // Iza datBase.parseChannel(Energy,d); r = new PReaction(d->cfinal,(Char_t*)filename.Data(),d->vch.size(),rootOut,0,calcVertex,asciiOut); } r->SetWriteIndex(writeIndex); r->trackedParticles(); r->Print(); cout<<"############################################################"<OpenFile(vertexntuple); r->AddPrologueBulk(vertex); //add to prologue action } else { cout<<"############################################################"<SetWriteSeqNumber(writeSeqNumber); output->OpenFile(Form("%s.evt",filename.Data())); r->AddFileOutput(output); r->setHGeant(0); if(useVertex){ TFile *f = new TFile(vertexntuple.Data()); if(f==NULL) { cout<<"############################################################"<Get("vertex")); if(vertexnt==NULL) { cout<<"############################################################"<Loop(vertexnt->GetEntries()); // number of events } else { r->Loop(nEvents); } output->CloseFile(); return 0; }