9 #include <TStopwatch.h>
24 #define _OUTPUT_FILE_DEFAULT_ "simulation.root"
25 #define _MEDIA_FILE_DEFAULT_ "media.geo"
26 #define _CAVE_FILE_NAME_DEFAULT_ "cave.geo"
31 mSuppressSecondariesFlag(
false), mFluxMonitorGrid(0),
36 mCaveDefinedFlag(
false),
39 mIgnoreBlackHoleVolumes(
false), mSuppressHitProductionFlag(
false),
40 mSuppressFairRootSteppingCallFlag(
false)
44 Fatal(
"EicRunSim::EicRunSim()",
"Singleton instance already exists.");
48 if (engine) SetName(engine);
123 if (fName.IsNull()) {
124 printf(
"\n\n EicRunSim::Init(): no G3/G4 engine specified.\n\n");
129 gRandom->SetSeed(
mSeed);
170 char simparamsFile[1024];
173 snprintf(simparamsFile, 1024-1,
"/tmp/simparams-%05d.root", getpid());
174 output->
open(simparamsFile);
199 printf(
"\n Wall Time = %7.1f s, CPU Time = %7.1f s\n\n", timer.RealTime(), timer.CpuTime());
210 TFile *fpar =
new TFile(simparamsFile);
213 TIter next(fpar->GetListOfKeys());
215 while ((key = (TKey*)next())) {
218 if (!strcmp(key->GetClassName(),
"TProcessID"))
continue;
220 TObject *obj = fpar->Get(key->GetName());
231 unlink(simparamsFile);
247 Fatal(
"EicRunSim",
"EicRunSim::DefineFluxMonitorGrid() called more than once.");
265 Fatal(
"EicRunSim",
"EicRunSim::AddFluxMonitorParticleType() called prior to "
266 "EicRunSim::DefineFluxMonitorGrid().");
276 mRmax(rMax), mRdim(rDim), mZmin(zMin), mZmax(zMax), mZdim(zDim), mRadiationMapType(
false),
277 mNormalizedCrossSection(0.0), mTrials(0), mTotalOriginalStat(0)
293 if (eMin < 0.0 || eMin > eMax) {
294 Fatal(
"EicRunSim",
"FluxMonitorGrid::AddFluxMonitorParticleType(): eMin >= eMax.");
305 for(
unsigned iz=0; iz<
mZdim; iz++)
315 #include <TVirtualMC.h>
323 unsigned needed[
mParticles.size()], nCounter = 0;
324 memset(needed, 0x00,
sizeof(needed));
325 for(
unsigned pt=0; pt<
mParticles.size(); pt++) {
329 if ((!ptype->
mPDG || pdg == ptype->
mPDG) && eKin >= ptype->
mEmin &&
337 if (!nCounter)
return;
343 if (in.z() <= out.z()) {
352 if (iz1 >
mZdim || iz2 < 0)
return;
353 double dz = v2->z() - v1->z();
355 TVector3 dv = *v2 - *
v1;
double dvlen = dv.Mag();
364 for(
int iqz=iz1; iqz<=iz2; iqz++) {
365 if (iqz < 0)
continue;
366 if (iqz >=
mZdim)
break;
374 TVector3 vl = *v1 + ((zl - v1->z())/dz) * dv;
375 TVector3 vr = *v1 + ((zr - v1->z())/dz) * dv;
376 TVector3 dvlr = vr - vl;
382 std::vector<std::pair<double, double> > parts;
384 TVector2 wl(vl.x(), vl.y()), wr(vr.x(), vr.y());
385 TVector2 dw = wr - wl;
386 double t = -(wl * dw)/dw.Mod2(), rl = wl.Mod(),
rr = wr.Mod();
391 if (t <= 0.0 || t >= 1.0) {
394 parts.push_back(std::pair<double, double>(0.0, 1.0));
396 parts.push_back(std::pair<double, double>(1.0, 0.0));
401 parts.push_back(std::pair<double, double>(t, 0.0));
402 parts.push_back(std::pair<double, double>(t, 1.0));
407 for(
unsigned i=0; i<parts.size(); i++) {
408 std::pair<double, double> *
part = &parts[i];
411 TVector2 _u1 = wl + part->first*dw, _u2 = wl + part->second*dw;
412 double r1 = _u1.Mod(),
r2 = _u2.Mod();
415 if (r1 >
mRmax)
continue;
421 for(
int iqr=ir1; iqr<=ir2; iqr++) {
422 if (iqr >=
mRdim)
break;
428 double A = dw.Mod2();
429 double B = 2 * wl * dw;
434 double C = wl.Mod2() - R*
R;
437 double D = sqrt(B*B - 4*A*C);
438 double roots[2] = {(-B-D)/(2*A), (-B+D)/(2*A)};
441 for(
unsigned irt=0; irt<2; irt++) {
443 if ((roots[irt] >= part->first && roots[irt] <= part->second) ||
444 (roots[irt] >= part->second && roots[irt] <= part->first)) {
457 double C = wl.Mod2() - R*
R;
460 double D = sqrt(B*B - 4*A*C);
461 double roots[2] = {(-B-D)/(2*A), (-B+D)/(2*A)};
464 for(
unsigned irt=0; irt<2; irt++)
465 if ((roots[irt] >= part->first && roots[irt] <= part->second) ||
466 (roots[irt] >= part->second && roots[irt] <= part->first)) {
478 TVector3
s1 = vl + t1 * dvlr;
479 TVector3
s2 = vl + t2 * dvlr;
480 double crlen = (s2 -
s1).Mag();
484 for(
unsigned pt=0; pt<
mParticles.size(); pt++) {
487 if (!needed[pt])
continue;
501 Float_t fA, fZmat, fDensity, fRadl, fAbsl;
503 gMC->CurrentMaterial(fA, fZmat, fDensity, fRadl, fAbsl);
506 ptype->
mEdep[iqz*
mRdim+iqr] += dvlen ? dE*(crlen/dvlen) : dE;
545 if (chain && chain->GetListOfFiles()->GetEntriesFast() == 1) {
546 TObjString *crossSectionString(NULL), *trialsString(NULL);
548 TFile *
file = chain->GetFile();
549 file->GetObject(
"crossSection", crossSectionString); assert(crossSectionString);
550 file->GetObject(
"nEvents", trialsString); assert(trialsString);
568 double lumi_exp = 1.0/1E-15, lumi_mc =
570 double norm = (lumi_exp/lumi_mc);
572 double cVolumes[
mRdim];
586 double gev2joule = 1.6E-10;
589 for(
unsigned pt=0; pt<
mParticles.size(); pt++) {
593 for(
unsigned iz=0; iz<
mZdim; iz++)
598 char htitle[1024] =
"", hname[1024],
pname[1024] =
"neutron",
lumi[1024];
599 snprintf(hname, 1024-1,
"flux%02d", pt);
601 if (ptype->
mPDG != 2112) snprintf(
pname, 1024-1,
"PDG#%d", ptype->
mPDG);
602 snprintf(
lumi, 1024-1,
"%5.1f fb^{-1} integrated luminosity", lumi_exp*1E-15);
605 snprintf(htitle, 1024-1,
"Radiation dose in [J/cm^{3}] for %s",
lumi);
607 snprintf(htitle, 1024-1,
"%s flux above %5.1f keV in [n/cm^{2}] for %s",
pname,
609 TH2D *hh =
new TH2D(hname, htitle, mZdim,
mZmin,
mZmax, mRdim, 0.0,
mRmax);
610 hh->GetXaxis()->SetTitle(
"Z coordinate (along the beam line), [cm]");
611 hh->GetYaxis()->SetTitle(
"Radial coordinate, [cm]");
613 for(
unsigned iz=0; iz<
mZdim; iz++)
620 double cMass = cVolumes[
ir] * density[iz][
ir];
640 printf(
"FluxMonitorTask called!\n");