//____________________________________________________________________ // // $Id$ // // Script to get the various cross sections, energy loss, and ranges // of a particular particle type in a particular medium. // // This script should be compiled to speed it up. // // It creates a tree on the current output file, with the relevant // information. // // Note, that VMC _must_ be the TGeant3TGeo VMC. // #ifdef __CINT__ XSection() { gROOT->ProcessLine(".x Compile.C(\"$(ALICE_ROOT)/FMD/scripts/XSection.C\""); gAlice->InitMC("$(ALICE_ROOT)/FMD/Config.C"); TFile* file = TFile::Open("xsec.root", "RECREATE"); GetXsection("FMD_Si$", "pi+"); file->Close(); } #else #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** @defgroup xsec_script X-section script @ingroup FMD_script */ //____________________________________________________________________ /** @ingroup xsec_script */ struct Mech { char* fName; char* fTitle; char* fUnit; }; Mech fgMechs[] = {{ "HADF","total hadronic x-section according to FLUKA", "cm^{1}"}, { "INEF","hadronic inelastic x-section according to FLUKA", "cm^{1}"}, { "ELAF","hadronic elastic x-section according to FLUKA", "cm^{1}"}, { "HADG","total hadronic x-section according to GHEISHA", "cm^{1}"}, { "INEG","hadronic inelastic x-section according to GHEISHA","cm^{1}"}, { "ELAG","hadronic elastic x-section according to GHEISHA", "cm^{1}"}, { "FISG","nuclear fission x-section according to GHEISHA", "cm^{1}"}, { "CAPG","neutron capture x-section according to GHEISHA", "cm^{1}"}, { "LOSS","stopping power", "cm^{1}"}, { "PHOT","photoelectric x-section", "MeV/cm"}, { "ANNI","positron annihilation x-section", "cm^{1}"}, { "COMP","Compton effect x-section", "cm^{1}"}, { "BREM","bremsstrahlung x-section", "cm^{1}"}, { "PAIR","photon and muon direct- pair x-section", "cm^{1}"}, { "DRAY","delta-rays x-section", "cm^{1}"}, { "PFIS","photo-fission x-section", "cm^{1}"}, { "RAYL","Rayleigh scattering x-section", "cm^{1}"}, { "MUNU","muon-nuclear interaction x-section", "cm^{1}"}, { "RANG","range", "cm"}, { "STEP","maximum step", "cm"}, { 0, 0, 0,}}; //____________________________________________________________________ /** @ingroup xsec_script */ struct MechValue { MechValue(const Mech& m, size_t n) : fMech(m), fValues(n), fStatus(0) {} bool Get(TGeant3* mc, std::vector& t, std::vector& c, int medNo, int pidNo) { TGraph g(t.size()); g.SetName(fMech.fName); g.SetTitle(fMech.fTitle); g.GetXaxis()->SetTitle("p [GeV]"); g.GetYaxis()->SetTitle(fMech.fUnit); int ixst; mc->Gftmat(medNo, pidNo, fMech.fName, t.size(), &(t[0]), &(fValues[0]), &(c[0]), ixst); fStatus = ixst; if (!fStatus) return false; for (size_t i = 0; i < t.size(); i++) g.SetPoint(i, t[i], fValues[i]); g.Write(); return true; } const Mech& fMech; std::vector fValues; bool fStatus; }; //____________________________________________________________________ /** @ingroup xsec_script */ struct XSection { XSection(size_t n=91, float emin=1e-5, float emax=1e4) : fTKine(n), fCuts(5) { float dp = 1. / log10(emax/emin); float pmin = log10(emin); fTKine[0] = emin; for (size_t i = 1; i < fTKine.size(); i++) { float el = pmin + i * dp; fTKine[i] = pow(10, el); } for (float_array::iterator i = fCuts.begin(); i != fCuts.end(); ++i) *i = 1e-4; Mech* mech = &(fgMechs[0]); size_t i = 0; while (mech->fName) { fMechs.push_back(new MechValue(*mech, n)); mech++; } } void Run(const std::string& medName, const std::string& pdgName) { TGeant3* mc = static_cast(gMC); if (!mc) { std::cerr << "Couldn't get VMC" << std::endl; return; } TGeoMedium* medium = gGeoManager->GetMedium(medName.c_str()); if (!medium) { std::cerr << "Couldn't find medium " << medName << std::endl; return; } int medNo = medium->GetMaterial()->GetUniqueID(); TDatabasePDG* pdgDb = TDatabasePDG::Instance(); TParticlePDG* pdgP = pdgDb->GetParticle(pdgName.c_str()); if (!pdgP) { std::cerr << "Couldn't find particle " << pdgName << std::endl; return; } int pdgNo = pdgP->PdgCode(); int pidNo = mc->IdFromPDG(pdgNo); std::stringstream vars; vars << "T/F"; size_t nOk = 0; // Loop over defined mechanisms for (mech_array::iterator i = fMechs.begin(); i != fMechs.end(); ++i) { if (!(*i)->Get(mc, fTKine, fCuts, medNo, pidNo))continue; vars << ":" << (*i)->fMech.fName; nOk ++; } std::stringstream tName; tName << medName << "_" << pdgName; TTree* tree = new TTree(tName.str().c_str(), tName.str().c_str()); float_array cache(nOk+1); tree->Branch("xsec", &(cache[0]), vars.str().c_str()); for (size_t i = 0; i < fTKine.size(); i++) { cache[0] = fTKine[i]; int k = 0; for (mech_array::iterator j = fMechs.begin(); j != fMechs.end(); ++j) { if (!(*j)->fStatus) continue; cache[++k] = (*j)->fValues[i]; } tree->Fill(); } tree->Write(); } protected: typedef std::vector float_array; typedef std::vector mech_array; float_array fTKine; float_array fCuts; mech_array fMechs; }; #if 0 //____________________________________________________________________ /** @ingroup xsec_script @param medName @param pdgName @param n @param emin @param emax */ void GetXsection(const char* medName, const char* pdgName, Int_t n=91, Float_t emin=1e-5, Float_t emax=1e4) { TArrayF tkine(n); Float_t dp = 1/TMath::Log10(emax/emin); Float_t pmin = TMath::Log10(emin); tkine[0] = emin; for (Int_t i=1; i < tkine.fN; i++) { Float_t el = pmin + i * dp; tkine[i] = TMath::Power(10, el); } TArrayF cuts(5); cuts.Reset(1e-4); Mech mechs[] = {{ "HADF","total hadronic x-section according to FLUKA","cm^{1}",n,0}, { "INEF","hadronic inelastic x-section according to FLUKA","cm^{1}",n,0}, { "ELAF","hadronic elastic x-section according to FLUKA","cm^{1}",n,0}, { "HADG","total hadronic x-section according to GHEISHA","cm^{1}",n,0}, { "INEG","hadronic inelastic x-section according to GHEISHA","cm^{1}",n,0}, { "ELAG","hadronic elastic x-section according to GHEISHA","cm^{1}",n,0}, { "FISG","nuclear fission x-section according to GHEISHA","cm^{1}",n,0}, { "CAPG","neutron capture x-section according to GHEISHA","cm^{1}",n,0}, { "LOSS","stopping power","cm^{1}",n,0}, { "PHOT","photoelectric x-section","MeV/cm",n,0}, { "ANNI","positron annihilation x-section","cm^{1}",n,0}, { "COMP","Compton effect x-section","cm^{1}",n,0}, { "BREM","bremsstrahlung x-section","cm^{1}",n,0}, { "PAIR","photon and muon direct- pair x-section","cm^{1}",n,0}, { "DRAY","delta-rays x-section","cm^{1}",n,0}, { "PFIS","photo-fission x-section","cm^{1}",n,0}, { "RAYL","Rayleigh scattering x-section","cm^{1}",n,0}, { "MUNU","muon-nuclear interaction x-section","cm^{1}",n,0}, { "RANG","range","cm",n,0}, { "STEP","maximum step","cm",n,0}, { 0, 0, 0, 0, 0}}; TGeant3* mc = (TGeant3*)gMC; if (!mc) { std::cerr << "Couldn't get VMC" << std::endl; return; } TGeoMedium* medium = gGeoManager->GetMedium(medName); if (!medium) { std::cerr << "Couldn't find medium " << medName << std::endl; return; } Int_t medNo = medium->GetMaterial()->GetUniqueID(); TDatabasePDG* pdgDb = TDatabasePDG::Instance(); TParticlePDG* pdgP = pdgDb->GetParticle(pdgName); if (!pdgP) { std::cerr << "Couldn't find particle " << pdgName << std::endl; return; } Int_t pdgNo = pdgP->PdgCode(); Int_t pidNo = mc->IdFromPDG(pdgNo); Mech* mech = &(mechs[0]); Int_t nMech = 0; Int_t nOk = 0; TString vars("T/F"); while (mech->name) { cout << mech->name << ": " << mech->title << " ... " << std::flush; nMech++; Int_t ixst; mc->Gftmat(medNo, pidNo, mech->name, n, tkine.fArray, mech->values.fArray, cuts.fArray, ixst); mech->status = ixst; if (ixst) { nOk++; vars.Append(Form(":%s", mech->name)); if (!strcmp("LOSS", mech->name)) { for (Int_t i = 0; i < n; i++) std::cout << i << "\t" << tkine[i] << "\t" << mech->values[i] << std::endl; } } std::cout << (ixst ? "ok" : "failed") << std::endl; mech++; } // TFile* file = TFile::Open(Form("xsec-%d.root", pdgNo), // "RECREATE"); TArrayF cache(nOk+1); TTree* tree = new TTree(Form("%s_%s", medName, pdgName), Form("%s_%s", medName, pdgName)); tree->Branch("xsec", cache.fArray, vars.Data()); for (Int_t i = 0; i < n; i++) { cache[0] = tkine[i]; Int_t k = 0; for (Int_t j = 0; j < nMech; j++) { if (mechs[j].status) { if (!strcmp(mechs[j].name, "LOSS")) std::cout << tkine[i] << "\t" << mechs[j].values[i] << std::endl; cache[k+1] = mechs[j].values[i]; k++; } } std::cout << k << "\t" << (k == nOk) << std::endl; tree->Fill(); } tree->Write(); } #endif #endif //____________________________________________________________________ // // EOF //