ROOT logo
//____________________________________________________________________
//
// $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. 
//
#include <TArrayF.h>
#include <TTree.h>
#include <TMath.h>
#include <iostream>
#include <TVirtualMC.h>
#include <TDatabasePDG.h>
#include <TString.h>
#include <TGeoManager.h>
#include <TGeoMedium.h>
#include <TGeant3.h>
#include <TGraph.h>
#include <TGraphErrors.h>
#include <TAxis.h>
#include <TFile.h>
#include <TH2.h>
#include <TLegend.h>
#include <AliRun.h>
#include <TCanvas.h>
#include <cmath>
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
/** @defgroup xsec_script X-section script 
    @ingroup FMD_script 
*/
//____________________________________________________________________
/** @ingroup xsec_script
 */
struct Mech 
{
  char* fName;
  char* fTitle;
  char* fUnit;
  int   fColor;
  int   fStyle;
};

Mech fgMechs[] = 
  {{ "HADF","FLUKA total hadronic x-section",        "cm^{-1}",1,1},
   { "INEF","FLUKA hadronic inelastic x-section",    "cm^{-1}",2,1},
   { "ELAF","FLUKA hadronic elastic x-section",      "cm^{-1}",3,1},
   { "HADG","GHEISHA total hadronic x-section",      "cm^{-1}",4,1},
   { "INEG","GHEISHA hadronic inelastic x-section",  "cm^{-1}",6,1},
   { "ELAG","GHEISHA hadronic elastic x-section",    "cm^{-1}",7,1},
   { "FISG","GHEISHA nuclear fission x-section",     "cm^{-1}",1,2},
   { "CAPG","GHEISHA neutron capture x-section",     "cm^{-1}",2,2},
   { "LOSS","stopping power",                        "MeV/cm", 3,2},
   { "PHOT","photoelectric x-section",               "cm^{-1}",4,2},
   { "ANNI","positron annihilation x-section",       "cm^{-1}",6,2},
   { "COMP","Compton effect x-section",              "cm^{-1}",7,2},
   { "BREM","bremsstrahlung x-section",              "cm^{-1}",1,3},
   { "PAIR","photon and muon direct- pair x-section","cm^{-1}",2,3},
   { "DRAY","delta-rays x-section",                  "cm^{-1}",3,3},
   { "PFIS","photo-fission x-section",               "cm^{-1}",4,3},
   { "RAYL","Rayleigh scattering x-section",         "cm^{-1}",6,3},
   { "MUNU","muon-nuclear interaction x-section",    "cm^{-1}",7,3},
   { "RANG","range",                                 "cm",     1,4},
   { "STEP","maximum step",                          "cm",     2,4},
   { 0, 0, 0, 0, 0}};

//____________________________________________________________________
/** @ingroup xsec_script
 */
struct MechValue 
{
  MechValue(const Mech& m, size_t n) 
    : fMech(m), fValues(n), fStatus(0), fELoss(0)
  {
    fGraph.SetName(fMech.fName);
    fGraph.SetTitle(fMech.fTitle);
    fGraph.GetXaxis()->SetTitle("#beta#gamma");
    fGraph.GetYaxis()->SetTitle(fMech.fUnit);
    fGraph.SetLineColor(fMech.fColor);
    fGraph.SetLineStyle(fMech.fStyle);
    fGraph.SetLineWidth(2);
    std::string name(fMech.fName);
    if (name != "LOSS") return;
    
    fELoss = new TGraphErrors(n);
    fELoss->SetName("ELOSS");
    fELoss->SetTitle(fMech.fTitle);
    fELoss->GetXaxis()->SetTitle("#beta#gamma");
    fELoss->GetYaxis()->SetTitle(fMech.fUnit);
    fELoss->SetLineColor(fMech.fColor);
    fELoss->SetLineStyle(fMech.fStyle);
    fELoss->SetLineWidth(2);
    fELoss->SetFillColor(fMech.fColor+1);
    fELoss->SetFillStyle(3001);
  }
  bool Get(TGeant3* mc, std::vector<float>& t, 
	   std::vector<float>& c, int medNo, int pidNo, 
	   float mass) 
  {
    int ixst;
    mc->Gftmat(medNo, pidNo, fMech.fName, t.size(), 
	       &(t[0]), &(fValues[0]), &(c[0]), ixst);
    fStatus = ixst;
    if (!fStatus) return false;
    fGraph.Set(t.size());
    for (size_t i = 0; i < t.size(); i++) {
      fGraph.SetPoint(i, t[i]/mass, fValues[i]);
      if (!fELoss) continue;
      fELoss->SetPoint(i, t[i]/mass, fValues[i]);
      // ~ 5 sigma
      fELoss->SetPointError(i, 0, .5 * fValues[i]);
    }
    fGraph.Write();
    if (fELoss) fELoss->Write();
    return true;
  }
  TGraph& Draw()
  {
    if (fELoss) fELoss->DrawClone("4 same");
    fGraph.DrawClone("l same");
    return fGraph;
  }
  const Mech&        fMech;
  std::vector<float> fValues;
  bool               fStatus;
  TGraph             fGraph;
  TGraphErrors*      fELoss;
};

//____________________________________________________________________
/** @ingroup xsec_script
 */
struct XSections 
{
  XSections(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]);
    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<TGeant3*>(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();
    fPDG                = pdgDb->GetParticle(pdgName.c_str());
    if (!fPDG) {
      std::cerr << "Couldn't find particle " << pdgName << std::endl;
      return;
    }
    int pdgNo = fPDG->PdgCode();
    int pidNo = mc->IdFromPDG(pdgNo);

    std::stringstream vars;
    vars << "betagamma/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, fPDG->Mass()))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] / fPDG->Mass();
      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();
  }
  void Draw() 
  {
    float min = 100000;
    float max = 0;
    std::vector<TGraph*> gs;
    float_array bg(fTKine.size());
    for (size_t i = 0; i < fTKine.size(); i++) bg[i] = fTKine[i]/fPDG->Mass();
    for (mech_array::iterator j = fMechs.begin(); j != fMechs.end(); ++j) {
      if (!(*j)->fStatus) continue;
      for (size_t i = 0; i < fTKine.size(); i++) {
	if ((*j)->fValues[i] == 0) continue;
	min = std::min(min, (*j)->fValues[i]);
	max = std::max(max, (*j)->fValues[i]);
      }
    }

    TCanvas* c = new TCanvas("c", "C", 700, 700);
    c->SetFillColor(0);
    c->SetLogy();
    c->SetLogx();
    c->SetGridy();
    c->SetGridx();
    float_array y(101);
    float ymin = log10(min);
    float dy   = (log10(max)+.5 - log10(min)) / y.size();
    for (size_t i = 1; i < y.size(); i++)  y[i] = pow(10, ymin + i * dy);
    TH2* f = new TH2F("x", "X-sec",bg.size()-1,&(bg[0]),y.size()-1,&(y[0]));
    f->SetXTitle("#beta#gamma");
    f->SetDirectory(0);
    f->SetStats(kFALSE);
    f->Draw();
    TLegend* l = new TLegend(0.45, 0.125, 0.90, 0.45);
    l->SetFillColor(0);
    // l->SetFillStyle(0);
    for (mech_array::iterator j = fMechs.begin(); j != fMechs.end(); ++j) {
      if (!(*j)->fStatus) continue;
      TGraph& g = (*j)->Draw();
      l->AddEntry(&g, g.GetTitle(), "l");
    }
    l->Draw("same");
  }
protected: 
  typedef std::vector<float> float_array;
  typedef std::vector<MechValue*> mech_array;
  float_array   fTKine;
  float_array   fCuts;
  mech_array    fMechs;
  TParticlePDG* fPDG;
};

bool init = false;

void XSection(const char* pdgName="pi-")
{
  if (!init) {
    gAlice->InitMC("$(ALICE_ROOT)/FMD/Config.C");
    init = true;
  }
  TFile* file = TFile::Open("xsec.root", "RECREATE");
  XSections xs;
  xs.Run("FMD_Si$", pdgName);
  xs.Draw();
  file->Close();
}
//____________________________________________________________________
//
// EOF
//
 XSection.C:1
 XSection.C:2
 XSection.C:3
 XSection.C:4
 XSection.C:5
 XSection.C:6
 XSection.C:7
 XSection.C:8
 XSection.C:9
 XSection.C:10
 XSection.C:11
 XSection.C:12
 XSection.C:13
 XSection.C:14
 XSection.C:15
 XSection.C:16
 XSection.C:17
 XSection.C:18
 XSection.C:19
 XSection.C:20
 XSection.C:21
 XSection.C:22
 XSection.C:23
 XSection.C:24
 XSection.C:25
 XSection.C:26
 XSection.C:27
 XSection.C:28
 XSection.C:29
 XSection.C:30
 XSection.C:31
 XSection.C:32
 XSection.C:33
 XSection.C:34
 XSection.C:35
 XSection.C:36
 XSection.C:37
 XSection.C:38
 XSection.C:39
 XSection.C:40
 XSection.C:41
 XSection.C:42
 XSection.C:43
 XSection.C:44
 XSection.C:45
 XSection.C:46
 XSection.C:47
 XSection.C:48
 XSection.C:49
 XSection.C:50
 XSection.C:51
 XSection.C:52
 XSection.C:53
 XSection.C:54
 XSection.C:55
 XSection.C:56
 XSection.C:57
 XSection.C:58
 XSection.C:59
 XSection.C:60
 XSection.C:61
 XSection.C:62
 XSection.C:63
 XSection.C:64
 XSection.C:65
 XSection.C:66
 XSection.C:67
 XSection.C:68
 XSection.C:69
 XSection.C:70
 XSection.C:71
 XSection.C:72
 XSection.C:73
 XSection.C:74
 XSection.C:75
 XSection.C:76
 XSection.C:77
 XSection.C:78
 XSection.C:79
 XSection.C:80
 XSection.C:81
 XSection.C:82
 XSection.C:83
 XSection.C:84
 XSection.C:85
 XSection.C:86
 XSection.C:87
 XSection.C:88
 XSection.C:89
 XSection.C:90
 XSection.C:91
 XSection.C:92
 XSection.C:93
 XSection.C:94
 XSection.C:95
 XSection.C:96
 XSection.C:97
 XSection.C:98
 XSection.C:99
 XSection.C:100
 XSection.C:101
 XSection.C:102
 XSection.C:103
 XSection.C:104
 XSection.C:105
 XSection.C:106
 XSection.C:107
 XSection.C:108
 XSection.C:109
 XSection.C:110
 XSection.C:111
 XSection.C:112
 XSection.C:113
 XSection.C:114
 XSection.C:115
 XSection.C:116
 XSection.C:117
 XSection.C:118
 XSection.C:119
 XSection.C:120
 XSection.C:121
 XSection.C:122
 XSection.C:123
 XSection.C:124
 XSection.C:125
 XSection.C:126
 XSection.C:127
 XSection.C:128
 XSection.C:129
 XSection.C:130
 XSection.C:131
 XSection.C:132
 XSection.C:133
 XSection.C:134
 XSection.C:135
 XSection.C:136
 XSection.C:137
 XSection.C:138
 XSection.C:139
 XSection.C:140
 XSection.C:141
 XSection.C:142
 XSection.C:143
 XSection.C:144
 XSection.C:145
 XSection.C:146
 XSection.C:147
 XSection.C:148
 XSection.C:149
 XSection.C:150
 XSection.C:151
 XSection.C:152
 XSection.C:153
 XSection.C:154
 XSection.C:155
 XSection.C:156
 XSection.C:157
 XSection.C:158
 XSection.C:159
 XSection.C:160
 XSection.C:161
 XSection.C:162
 XSection.C:163
 XSection.C:164
 XSection.C:165
 XSection.C:166
 XSection.C:167
 XSection.C:168
 XSection.C:169
 XSection.C:170
 XSection.C:171
 XSection.C:172
 XSection.C:173
 XSection.C:174
 XSection.C:175
 XSection.C:176
 XSection.C:177
 XSection.C:178
 XSection.C:179
 XSection.C:180
 XSection.C:181
 XSection.C:182
 XSection.C:183
 XSection.C:184
 XSection.C:185
 XSection.C:186
 XSection.C:187
 XSection.C:188
 XSection.C:189
 XSection.C:190
 XSection.C:191
 XSection.C:192
 XSection.C:193
 XSection.C:194
 XSection.C:195
 XSection.C:196
 XSection.C:197
 XSection.C:198
 XSection.C:199
 XSection.C:200
 XSection.C:201
 XSection.C:202
 XSection.C:203
 XSection.C:204
 XSection.C:205
 XSection.C:206
 XSection.C:207
 XSection.C:208
 XSection.C:209
 XSection.C:210
 XSection.C:211
 XSection.C:212
 XSection.C:213
 XSection.C:214
 XSection.C:215
 XSection.C:216
 XSection.C:217
 XSection.C:218
 XSection.C:219
 XSection.C:220
 XSection.C:221
 XSection.C:222
 XSection.C:223
 XSection.C:224
 XSection.C:225
 XSection.C:226
 XSection.C:227
 XSection.C:228
 XSection.C:229
 XSection.C:230
 XSection.C:231
 XSection.C:232
 XSection.C:233
 XSection.C:234
 XSection.C:235
 XSection.C:236
 XSection.C:237
 XSection.C:238
 XSection.C:239
 XSection.C:240
 XSection.C:241
 XSection.C:242
 XSection.C:243
 XSection.C:244
 XSection.C:245
 XSection.C:246
 XSection.C:247
 XSection.C:248
 XSection.C:249
 XSection.C:250
 XSection.C:251
 XSection.C:252
 XSection.C:253
 XSection.C:254
 XSection.C:255
 XSection.C:256
 XSection.C:257
 XSection.C:258
 XSection.C:259
 XSection.C:260
 XSection.C:261
 XSection.C:262
 XSection.C:263
 XSection.C:264
 XSection.C:265
 XSection.C:266
 XSection.C:267
 XSection.C:268
 XSection.C:269
 XSection.C:270
 XSection.C:271
 XSection.C:272
 XSection.C:273
 XSection.C:274
 XSection.C:275
 XSection.C:276
 XSection.C:277
 XSection.C:278
 XSection.C:279
 XSection.C:280
 XSection.C:281