00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #include <TVirtualMC.h>
00012 #include <TArrayI.h>
00013 #include <TArrayD.h>
00014 #include <TGeoManager.h>
00015 #include <TGeoNode.h>
00016 #include <TClonesArray.h>
00017 #include <TDatabasePDG.h>
00018
00019 #include "GeoGeometry/GeoStripNode.h"
00020 #include "Digitization/DigiScintHit.h"
00021 #include "Util/UtilPDG.h"
00022 #include "MCApplication/MCApplication.h"
00023 #include "ParticleTransportSim/PTSimApplication.h"
00024 #include "ParticleTransportSim/PTSimStack.h"
00025 #include "G3PTSim/TGeant3/TGeant3.h"
00026
00027 #include "MessageService/MsgService.h"
00028
00029 CVSID("$Id: PTSimApplication.cxx,v 1.67 2009/06/22 03:51:01 kasahara Exp $");
00030
00031 ClassImp(PTSimApplication)
00032
00033
00034 PTSimApplication::PTSimApplication(const char* name, const char* title)
00035 : MCAppUser(name,title),fSnarl(-1),fEvent(-1),fPrimary(-1),fNSnarls(0),
00036 fNEvents(0),fPTSimStack(0),fHitArray(0),fStdHepArray(0),fMCHit(),
00037 fExitLiner(false),fLogLevel(kInfo),fLastStackSize(0),fNHitBegEvt(0),
00038 fNSensitiveMedId(0),fCurrentPath(""),fRkVLevel(0),fRkVMinDistInCM(-1.),
00039 fRkVFactor(-1.),fRockdEdXMin(-1.) {
00040
00041
00042 MSG("PTSim",Msg::kDebug) << "PTSimApplication normal ctor @ "
00043 << this << endl;
00044
00045 fPTSimStack = new PTSimStack();
00046
00047 }
00048
00049
00050 PTSimApplication::~PTSimApplication() {
00051
00052
00053 MSG("PTSim",Msg::kDebug) << "PTSimApplication dtor @ "
00054 << this << endl;
00055
00056 if ( fPTSimStack ) delete fPTSimStack; fPTSimStack = 0;
00057 ResetEvtStdHepMap();
00058
00059 }
00060
00061
00062 void PTSimApplication::GeneratePrimaries() {
00063
00064
00065 MSG("PTSim",Msg::kDebug) << "PTSimApplication::GeneratePrimaries "
00066 << fSnarl << "/" << fEvent << endl;
00067
00068
00069 fPTSimStack->Reset();
00070
00071
00072 Int_t nevent = fEvtStdHepMap.size();
00073 if ( fEvent >= nevent ) {
00074 MSG("PTSim",Msg::kError) << "GeneratePrimaries called with Event "
00075 << fEvent << " but only " << nevent
00076 << " particles in stack. Abort." << endl;
00077 abort();
00078 }
00079
00080 std::vector<TParticle*>& stdheplist = fEvtStdHepMap[fEvent];
00081
00082 TVector3 pol;
00083 for ( unsigned int is = 0; is < stdheplist.size(); is++ ) {
00084 TParticle* prim = stdheplist[is];
00085
00086 Int_t toBeDone = 0;
00087 if ( prim->GetStatusCode() == 1 ) {
00088 if ( abs(prim->GetPdgCode()) == 311 ) {
00089
00090
00091 TGeant3* geant3 = dynamic_cast<TGeant3*>(gMC);
00092 if ( geant3 ) {
00093 Double_t randno = MCApplication::Instance().GetRandom() -> Rndm();
00094 if ( randno <= 0.5 ) prim -> SetPdgCode(130);
00095 else prim -> SetPdgCode(310);
00096 }
00097 }
00098 Int_t primPdg = prim->GetPdgCode();
00099 if ( primPdg != 28 && primPdg != 0 ) {
00100
00101 if ( gMC->IdFromPDG(primPdg) <= 0 ) {
00102
00103
00104 const TDatabasePDG& dbpdg = *(TDatabasePDG::Instance());
00105 std::string pname = "???";
00106 if (dbpdg.GetParticle(primPdg))
00107 pname = dbpdg.GetParticle(primPdg)->GetName();
00108 MSG("PTSim",Msg::kWarning) << "Particle of type "
00109 << primPdg << "/" << pname.c_str()
00110 << " not defined to Monte Carlo."
00111 << " Skipped!" << endl;
00112 }
00113 else toBeDone = 1;
00114 }
00115 }
00116
00117 Int_t parent = prim->GetMother(0);
00118 prim->GetPolarisation(pol);
00119 Int_t trkId = -1;
00120
00121 fPTSimStack -> PushTrack(toBeDone,parent,prim->GetPdgCode(),
00122 prim->Px(),prim->Py(),prim->Pz(),prim->Energy(),
00123 prim->Vx(),prim->Vy(),prim->Vz(),prim->T(),
00124 pol.X(),pol.Y(),pol.Z(),kPPrimary,trkId,
00125 prim->GetWeight(),prim->GetStatusCode());
00126
00127 }
00128
00129 if ( fLogLevel <= Msg::kDebug ) {
00130 MSG("PTSim",Msg::kDebug) << "PTSimApplication::GeneratePrimaries "
00131 << fSnarl << "/" << fEvent << " pushed "
00132 << fPTSimStack->GetNtrack() << " particles w/"
00133 << fPTSimStack->GetNprimary() << " primaries "
00134 << "to stack." << endl;
00135 fPTSimStack->Print();
00136 }
00137
00138 return;
00139
00140 }
00141
00142
00143 void PTSimApplication::BeginEvent() {
00144
00145
00146 fEvent++;
00147 fNEvents++;
00148
00149 MSG("PTSim",Msg::kDebug) << " *** PTSimApplication::BeginEvent: Snarl "
00150 << fSnarl << " Event " << fEvent
00151 << " *** " << endl;
00152 fPrimary = -1;
00153
00154 bool toswim = false;
00155 const_cast<MCApplication&>(MCApplication::Instance()).SwitchMedia(toswim);
00156
00157
00158
00159
00160 fSensitiveMedId.clear();
00161 TIter next(gGeoManager->GetListOfMedia());
00162 TGeoMedium* med = 0;
00163 fNSensitiveMedId = 0;
00164 while ((med = (TGeoMedium*)next())) {
00165 if ( med->GetParam(0) > 0 ) {
00166
00167 std::string medName = med -> GetName();
00168 if ( medName.find("_SWIM") == std::string::npos ) {
00169 fSensitiveMedId.push_back(med->GetId());
00170 fNSensitiveMedId++;
00171 }
00172 }
00173 }
00174
00175 fLogLevel = MsgService::Instance()->GetStream("PTSim")->GetLogLevel();
00176 fLastStackSize = fPTSimStack->GetNtrack();
00177 fNHitBegEvt = fHitArray->GetEntriesFast();
00178
00179
00180 }
00181
00182
00183 void PTSimApplication::BeginPrimary() {
00184
00185
00186 fPrimary++;
00187 if ( fLogLevel <= Msg::kDebug ) {
00188 const TParticle* primary = fPTSimStack->GetCurrentTrack();
00189 Int_t pdg = primary->GetPdgCode();
00190 std::string pname = primary->GetName();
00191 Int_t trkno = fPTSimStack->GetCurrentTrackNumber();
00192
00193 MSG("PTSim",Msg::kDebug) << "PTSimApplication::BeginPrimary "
00194 << fSnarl << "/" << fEvent << "/"
00195 << fPrimary << " trkno " << trkno << " pdg "
00196 << pdg << "/" << pname.c_str() << endl;
00197 }
00198
00199 }
00200
00201
00202 void PTSimApplication::PreTrack() {
00203
00204
00205 fExitLiner = false;
00206
00207 if ( fLogLevel <= Msg::kDebug ) {
00208 Int_t trkno = fPTSimStack->GetCurrentTrackNumber();
00209 TLorentzVector pos;
00210 gMC->TrackPosition(pos);
00211 TLorentzVector mom;
00212 gMC->TrackMomentum(mom);
00213 Int_t pdg = gMC->TrackPid();
00214 const TDatabasePDG& dbpdg = *(TDatabasePDG::Instance());
00215 std::string pname = "???";
00216 if (dbpdg.GetParticle(pdg)) pname = dbpdg.GetParticle(pdg)->GetName();
00217 Int_t parentno = fPTSimStack->GetCurrentParentTrackNumber();
00218
00219 if ( fLogLevel == Msg::kDebug ) {
00220 if ((fPTSimStack -> GetParticle(trkno) -> GetProcess())
00221 == kPPrimary) {
00222 MSG("PTSim",Msg::kDebug) << "PTSimApplication::PreTrack "
00223 << fSnarl << "/" << fEvent << "/" << fPrimary << "/" << trkno
00224 << " parent " << parentno
00225 << "\n " << pdg << "/" << pname.c_str()
00226 << " " << gMC->CurrentVolName() << " v: " << pos.X()
00227 << " " << pos.Y() << " " << pos.Z() << " " << pos.T()
00228 << " p: " << mom.X() << " " << mom.Y() << " " << mom.Z()
00229 << " " << mom.E() << endl;
00230 }
00231 }
00232 else {
00233 MSG("PTSim",Msg::kVerbose) << "PTSimApplication::PreTrack "
00234 << fSnarl << "/" << fEvent << "/" << fPrimary << "/" << trkno
00235 << " parent " << parentno
00236 << "\n " << pdg << "/" << pname.c_str()
00237 << " " << gMC->CurrentVolName() << " v: " << pos.X()
00238 << " " << pos.Y() << " " << pos.Z() << " " << pos.T()
00239 << " p: " << mom.X() << " " << mom.Y() << " " << mom.Z()
00240 << " " << mom.E() << endl;
00241 }
00242 }
00243
00244 }
00245
00246
00247 void PTSimApplication::Stepping() {
00248
00249
00250
00251 if ( gMC -> IsNewTrack() ) {
00252 Int_t trkno = fPTSimStack->GetCurrentTrackNumber();
00253 if ( fRkVLevel > 1 || (fRkVLevel == 1
00254 && (fPTSimStack -> GetParticle(trkno) -> GetProcess()) == kPPrimary) ) {
00255 if ( IsRockVetoed() ) {
00256 if ( fLogLevel <= Msg::kDebug ) {
00257 TLorentzVector pos;
00258 gMC->TrackPosition(pos);
00259 TLorentzVector mom;
00260 gMC->TrackMomentum(mom);
00261 Int_t pdg = gMC->TrackPid();
00262 const TDatabasePDG& dbpdg = *(TDatabasePDG::Instance());
00263 std::string pname = "???";
00264 if (dbpdg.GetParticle(pdg)) pname=dbpdg.GetParticle(pdg)->GetName();
00265 Int_t parentno = fPTSimStack->GetCurrentParentTrackNumber();
00266 MSG("PTSim",Msg::kDebug)
00267 << "Track is in rock and below required energy, call StopTrack\n"
00268 << fSnarl << "/" << fEvent << "/" << fPrimary << "/" << trkno
00269 << " parent " << parentno
00270 << "\n " << pdg << "/" << pname.c_str()
00271 << " " << gMC->CurrentVolName() << " v: " << pos.X()
00272 << " " << pos.Y() << " " << pos.Z() << " " << pos.T()
00273 << " p: " << mom.X() << " " << mom.Y() << " " << mom.Z()
00274 << " " << mom.E() << endl;
00275 }
00276 gMC -> StopTrack();
00277 return;
00278 }
00279 }
00280 }
00281
00282 if ( fLogLevel <= Msg::kVerbose ) {
00283
00284 TLorentzVector msgpos;
00285 gMC->TrackPosition(msgpos);
00286 TLorentzVector msgmom;
00287 gMC->TrackMomentum(msgmom);
00288
00289 MSG("PTSim",Msg::kVerbose) << "Stepping:\n"
00290 << "particle Id " << gMC->TrackPid() << " in vol "
00291 << gMC->CurrentVolName()
00292 << "\npos " << msgpos.X() << " " << msgpos.Y() << " " << msgpos.Z() << " "
00293 << msgpos.T() << "\nmom " << msgmom.X() << " " << msgmom.Y() << " "
00294 << msgmom.Z() << " " << msgmom.E() << "\neloss " << gMC->Edep()
00295 << ", step " << gMC->TrackStep() << endl;
00296
00297 TArrayI processlist;
00298 Int_t nprocess = gMC->StepProcesses(processlist);
00299 std::string processnamelist = "Step Processes:\n";
00300 for (int ip = 0; ip < nprocess; ip++ ) {
00301 processnamelist += std::string(TMCProcessName[processlist[ip]]) + "/";
00302 }
00303 MSG("PTSim",Msg::kVerbose) << processnamelist.c_str() << endl;
00304
00305 MSG("PTSim",Msg::kVerbose) << "Track Is:"
00306 << (gMC->IsTrackEntering() ? "Entering/" : "" )
00307 << (gMC->IsTrackExiting() ? "Exiting/" : "" )
00308 << (gMC->IsTrackOut() ? "Out/" : "" )
00309 << (gMC->IsTrackStop() ? "Stop/" : "" )
00310 << (gMC->IsNewTrack() ? "New/" : "" )
00311 << (gMC->IsTrackInside() ? "Inside/" : "" )
00312 << (gMC->IsTrackDisappeared() ? "Disappeared/" : "" )
00313 << (gMC->IsTrackAlive() ? "Alive/" : "" )
00314 << endl;
00315 }
00316
00317 Int_t nsec = gMC->NSecondaries();
00318 if ( nsec != 0 ) {
00319 if ( fLogLevel <= Msg::kVerbose ) {
00320 std::string secondarystr;
00321 if ( nsec == 1 )
00322 secondarystr = " secondary generated in this step.";
00323 else
00324 secondarystr = " secondaries generated in this step.";
00325 MSG("PTSim",Msg::kVerbose) << nsec << secondarystr.c_str() << endl;
00326 }
00327
00328 if ( fPTSimStack->GetStdHepSaveSibling() ) {
00329
00330
00331
00332
00333 TMCProcess prodprocess = gMC->ProdProcess(0);
00334 if ( prodprocess == kPDecay ) fLastStackSize++;
00335
00336 if ( nsec != (fPTSimStack->GetNtrack() - fLastStackSize) ) {
00337
00338
00339
00340
00341 MSG("PTSim",Msg::kError)
00342 << "Number of secondaries generated in this step " << nsec
00343 << "\nnot equal to difference in stack size since last addition."
00344 << "Was: " << fLastStackSize << " Now: " << fPTSimStack->GetNtrack()
00345 << " Abort." << endl;
00346 abort();
00347 }
00348 for ( Int_t isec = 0; isec < nsec; isec++ ) {
00349 Int_t secTrkId = fLastStackSize + isec;
00350
00351 PTSimParticle* secParticle = const_cast<PTSimParticle*>
00352 (fPTSimStack->GetParticle(secTrkId));
00353 for ( Int_t isec2 = 0; isec2 < nsec; isec2++ ) {
00354 if ( isec2 != isec ) {
00355 Int_t secTrkId2 = fLastStackSize + isec2;
00356 secParticle -> AddSibling(fPTSimStack->GetParticle(secTrkId2));
00357 }
00358 }
00359 }
00360 }
00361 }
00362
00363 if ( fPTSimStack->GetStdHepSaveSibling() )
00364 fLastStackSize = fPTSimStack->GetNtrack();
00365
00366
00367 if ( IsExiting() ) {
00368 MSG("PTSim",Msg::kDebug)
00369 << "Track is entering MARS from LINR, call StopTrack " << endl;
00370 gMC -> StopTrack();
00371 return;
00372 }
00373 if ( IsNeutrino() ) {
00374 MSG("PTSim",Msg::kDebug)
00375 << "Track is neutrino, call StopTrack " << endl;
00376 gMC -> StopTrack();
00377 return;
00378 }
00379
00380 if ( !(gMC->TrackCharge()) ) return;
00381
00382 bool isSensitive = false;
00383 Int_t currentMedId = gMC->CurrentMedium();
00384 for ( int imed = 0; imed < fNSensitiveMedId; imed++ ) {
00385 if ( fSensitiveMedId[imed] == currentMedId ) {
00386 isSensitive = true;
00387 MSG("PTSim",Msg::kVerbose) << "Sensitive volume" << endl;
00388 break;
00389 }
00390 }
00391
00392
00393 if ( !isSensitive ) return;
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 if ( gMC -> IsTrackStop() && fMCHit.GetTrkIndex() < 0 ) return;
00406
00407 if ( gMC -> IsTrackExiting() ) {
00408
00409
00410 fCurrentPath = gGeoManager->GetPath();
00411 gGeoManager->cd(gMC->CurrentVolPath());
00412 }
00413
00414
00415
00416 GeoStripNode* stp = dynamic_cast<GeoStripNode*>(gGeoManager->GetMother());
00417 if ( !stp ) {
00418 MSG("PTSim",Msg::kFatal) << "Stepping claims to be in sensitive volume "
00419 << " but not strip node! abort." << endl;
00420 abort();
00421 }
00422 PlexStripEndId seid = stp -> GetSEId();
00423
00424
00425 TLorentzVector pos;
00426 gMC->TrackPosition(pos);
00427 TLorentzVector mom;
00428 gMC->TrackMomentum(mom);
00429 Double_t gxyz[3] = {pos.X(),pos.Y(),pos.Z()};
00430 Double_t lxyz[3] = {0};
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 stp -> GlobalToLocal(gxyz,lxyz);
00443
00444
00445 TLorentzVector localpos;
00446 localpos.SetXYZT(lxyz[0],lxyz[1],lxyz[2],pos.T());
00447
00448 Int_t trackid = fPTSimStack->GetCurrentTrackNumber();
00449 if ( gMC -> IsTrackEntering() ) {
00450 fMCHit.Clear();
00451 fMCHit.Init(seid,gMC->TrackPid(),trackid,pos,localpos,mom);
00452 }
00453 else {
00454
00455 if ( fMCHit.GetTrkIndex() != trackid ) {
00456 MSG("PTSim",Msg::kError) << "Current track no " << trackid
00457 << " not equal to hit trk index "
00458 << fMCHit.GetTrkIndex() << ". abort." << endl;
00459 abort();
00460 }
00461 fMCHit.AddELoss(gMC->Edep());
00462 fMCHit.AddStep(gMC->TrackStep());
00463 fMCHit.SetCurrentState(pos,localpos,mom);
00464 }
00465
00466 if ( gMC -> IsTrackExiting() || gMC -> IsTrackStop()
00467 || gMC -> IsTrackDisappeared() ) {
00468 if ( fMCHit.GetTrkIndex() != trackid ) {
00469 MSG("PTSim",Msg::kError) << "Current track no " << trackid
00470 << " not equal to hit trk index "
00471 << fMCHit.GetTrkIndex() << ". abort" << endl;
00472 abort();
00473 }
00474 PTSimParticle* track = const_cast<PTSimParticle*>
00475 (fPTSimStack->GetParticle(trackid));
00476 if ( !(track->HasHitAboveThresh()) &&
00477 fMCHit.GetELoss() >= fPTSimStack->GetStdHepHitThr() ) {
00478 track -> SetHasHitAboveThresh(true);
00479 }
00480
00481 fMCHit.CreateDigiScintHit(*fHitArray);
00482 fMCHit.Clear();
00483 }
00484
00485 if ( gMC -> IsTrackExiting() ) {
00486
00487
00488 gGeoManager->cd(fCurrentPath.c_str());
00489 }
00490
00491 }
00492
00493
00494
00495 bool PTSimApplication::IsExiting() {
00496
00497
00498
00499
00500
00501 if ( gMC -> IsTrackExiting() ) {
00502 if ( std::string(gMC -> CurrentVolName() ) == "LINR" ) {
00503 fExitLiner = true;
00504 }
00505 }
00506 else if ( gMC -> IsTrackEntering() && fExitLiner ) {
00507 if ( std::string(gMC -> CurrentVolName() ) == "MARS" ) {
00508 return true;
00509 }
00510 }
00511
00512 return false;
00513
00514 }
00515
00516
00517 bool PTSimApplication::IsNeutrino() {
00518
00519
00520
00521 Int_t abspdgId = TMath::Abs(gMC -> TrackPid());
00522
00523 if ( abspdgId == 12 ) return true;
00524 else if ( abspdgId == 14 ) return true;
00525 else if ( abspdgId == 16 ) return true;
00526 else if ( abspdgId == 18 ) return true;
00527
00528 return false;
00529
00530 }
00531
00532
00533 void PTSimApplication::PostTrack() {
00534
00535
00536 MSG("PTSim",Msg::kVerbose) << "PTSimApplication::PostTrack" << endl;
00537
00538 }
00539
00540
00541 void PTSimApplication::FinishPrimary() {
00542
00543
00544 MSG("PTSim",Msg::kDebug) << "PTSimApplication::FinishPrimary "
00545 << fSnarl << "/" << fEvent << "/" << fPrimary << endl;
00546
00547 }
00548
00549
00550 void PTSimApplication::FinishEvent() {
00551
00552
00553 MSG("PTSim",Msg::kDebug) << "PTSimApplication::FinishEvent "
00554 << fSnarl << "/" << fEvent << endl;
00555
00556
00557
00558
00559 fPTSimStack -> FillStdHepArray(fStdHepArray,fSnarl,fHitArray,fNHitBegEvt);
00560 fPTSimStack -> Reset();
00561
00562 }
00563
00564
00565 void PTSimApplication::InitSnarl(Int_t snarl, TClonesArray* stdheparray,
00566 Int_t nevent) {
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 const MCApplication& mcapp = MCApplication::Instance();
00586 std::string evtstr = " event.";
00587 if ( nevent > 1 ) evtstr = " events.";
00588
00589 MSG("PTSim",Msg::kInfo) << "***** PTSimApplication::InitSnarl: Snarl "
00590 << snarl << " with " << nevent << evtstr.c_str()
00591 << " Starting seed "
00592 << mcapp.GetRandom()->GetSeed() << " *****" << endl;
00593
00594 if ( fRkVLevel > 0 && fRockdEdXMin < 0. ) InitRockdEdXMin();
00595
00596 ResetEvtStdHepMap();
00597 fSnarl = snarl;
00598 fNSnarls++;
00599 fEvent=-1;
00600
00601 fStdHepArray = stdheparray;
00602
00603 if ( nevent <= 0 ) return;
00604
00605 Int_t nstdhep = fStdHepArray->GetEntriesFast();
00606
00607 Int_t mcindex = -1;
00608 Int_t nprim = 0;
00609 Int_t idx0 = 0;
00610 bool prevchild = true;
00611 std::map<int,int> indexmap;
00612
00613 for ( Int_t istd = 0; istd < nstdhep; istd++ ) {
00614 TParticle* simstdhep = dynamic_cast<TParticle*>(fStdHepArray->At(istd));
00615
00616 if ( simstdhep->GetMother(0) == -1 && simstdhep->GetMother(1) == -1 ) {
00617
00618 nprim++;
00619 if ( nprim > 2 || prevchild ) {
00620 if ( mcindex != -1 ) {
00621
00622
00623 std::vector<TParticle*>& particlelist = fEvtStdHepMap[mcindex];
00624 Int_t nsize = particlelist.size();
00625 for ( int ip = 0; ip < nsize; ip++ ) {
00626 TParticle* particle = particlelist[ip];
00627 if ( particle->GetFirstMother() != -1 ) {
00628
00629 std::map<int,int>::iterator inditr
00630 = indexmap.find(particle->GetFirstMother());
00631 if (inditr == indexmap.end() ) {
00632 MSG("PTSim",Msg::kError) << "No mother index in map. Abort"
00633 << endl;
00634 abort();
00635 }
00636 particle->SetFirstMother(inditr->second);
00637 }
00638 if ( particle->GetSecondMother() != -1 ) {
00639
00640 std::map<int,int>::iterator inditr
00641 = indexmap.find(particle->GetSecondMother());
00642 if (inditr == indexmap.end() ) {
00643 MSG("PTSim",Msg::kError) << "No mother index in map. Abort"
00644 << endl;
00645 abort();
00646 }
00647 particle->SetLastMother(inditr->second);
00648 }
00649 if ( particle->GetFirstDaughter() != -1 ) {
00650
00651 std::map<int,int>::iterator inditr
00652 = indexmap.find(particle->GetFirstDaughter());
00653 if (inditr != indexmap.end() )
00654 particle->SetFirstDaughter(inditr->second);
00655 else
00656 particle->SetFirstDaughter(-1);
00657 }
00658 if ( particle->GetLastDaughter() != -1 ) {
00659
00660 std::map<int,int>::iterator inditr
00661 = indexmap.find(particle->GetLastDaughter());
00662 if (inditr != indexmap.end() )
00663 particle->SetLastDaughter(inditr->second);
00664 else
00665 particle->SetLastDaughter(-1);
00666 }
00667 }
00668 indexmap.clear();
00669 }
00670
00671 mcindex++;
00672 nprim = 1;
00673 idx0 = istd;
00674 if ( mcindex >= nevent ) {
00675 MSG("PTSim",Msg::kError)
00676 << "PTSimModule::BuildEvtStdHepMap:\nBreakdown in procedure "
00677 << "to match stdhep to associated mc entry.\n"
00678 << "Unable to process snarl. Abort." << endl;
00679 abort();
00680 }
00681 }
00682
00683 prevchild = false;
00684 }
00685
00686 else {
00687 prevchild = true;
00688 nprim = 0;
00689 }
00690
00691
00692 Int_t statuscode = simstdhep->GetStatusCode();
00693 bool isprimary = false;
00694 if ( statuscode < 200 || statuscode == 999 ) {
00695
00696 isprimary = true;
00697 }
00698 else if ( statuscode == 1205 ) {
00699
00700 TParticle* child = dynamic_cast<TParticle*>
00701 (fStdHepArray->At(simstdhep->GetFirstDaughter()));
00702 if ( child->GetStatusCode() < 200 ) isprimary = true;
00703 }
00704 if ( isprimary ) {
00705
00706
00707 std::vector<TParticle*>& stdheplist = fEvtStdHepMap[mcindex];
00708 TParticle* stdhepcopy = new TParticle(*simstdhep);
00709
00710 stdhepcopy -> SetProductionVertex(stdhepcopy->Vx()*100.,
00711 stdhepcopy->Vy()*100.,
00712 stdhepcopy->Vz()*100.,
00713 stdhepcopy->T());
00714
00715 if ( UtilPDG::isIon(stdhepcopy -> GetPdgCode()) ) {
00716 int pdg2006 = UtilPDG::stdIonNumber(stdhepcopy->GetPdgCode(),
00717 UtilPDG::kPDG2006);
00718 stdhepcopy -> SetPdgCode(pdg2006);
00719 }
00720
00721 indexmap.insert(std::make_pair(istd,stdheplist.size()));
00722 stdheplist.push_back(stdhepcopy);
00723 }
00724
00725 }
00726
00727
00728 if ( mcindex != nevent - 1 ) {
00729 MSG("PTSim",Msg::kError)
00730 << "PTSimModule::InitSnarl:"
00731 << "\nBreakdown in procedure to match stdhep to "
00732 << "associated mc entry.\nFound " << mcindex + 1 << " primaries "
00733 << "in stdhep array, but nevent = " << nevent << ".\n"
00734 << "Unable to process snarl. Abort." << endl;
00735 abort();
00736 }
00737
00738
00739
00740 std::vector<TParticle*>& particlelist = fEvtStdHepMap[mcindex];
00741 Int_t nsize = particlelist.size();
00742 for ( int ip = 0; ip < nsize; ip++ ) {
00743 TParticle* particle = particlelist[ip];
00744 if ( particle->GetFirstMother() != -1 ) {
00745
00746 std::map<int,int>::iterator inditr
00747 = indexmap.find(particle->GetFirstMother());
00748 if (inditr == indexmap.end() ) {
00749 MSG("PTSim",Msg::kError) << "No mother index in map. Abort" << endl;
00750 abort();
00751 }
00752 particle->SetFirstMother(inditr->second);
00753 }
00754 if ( particle->GetSecondMother() != -1 ) {
00755
00756 std::map<int,int>::iterator inditr
00757 = indexmap.find(particle->GetSecondMother());
00758 if (inditr == indexmap.end() ) {
00759 MSG("PTSim",Msg::kError) << "No mother index in map. Abort" << endl;
00760 abort();
00761 }
00762 particle->SetLastMother(inditr->second);
00763 }
00764 if ( particle->GetFirstDaughter() != -1 ) {
00765
00766 std::map<int,int>::iterator inditr
00767 = indexmap.find(particle->GetFirstDaughter());
00768 if (inditr != indexmap.end() )
00769 particle->SetFirstDaughter(inditr->second);
00770 else
00771 particle->SetFirstDaughter(-1);
00772 }
00773 if ( particle->GetLastDaughter() != -1 ) {
00774
00775 std::map<int,int>::iterator inditr
00776 = indexmap.find(particle->GetLastDaughter());
00777 if (inditr != indexmap.end() )
00778 particle->SetLastDaughter(inditr->second);
00779 else
00780 particle->SetLastDaughter(-1);
00781 }
00782 }
00783
00784 indexmap.clear();
00785
00786
00787
00788 fStdHepArray -> Clear("C");
00789
00790 return;
00791
00792 }
00793
00794
00795 void PTSimApplication::ResetEvtStdHepMap() {
00796
00797 EvtStdHepMap::reverse_iterator ritr;
00798 for ( ritr = fEvtStdHepMap.rbegin(); ritr != fEvtStdHepMap.rend(); ritr++ ) {
00799 std::vector<TParticle*>& particlelist = ritr->second;
00800 for ( unsigned int ip = 0; ip < particlelist.size(); ip++ ) {
00801 TParticle* particle = particlelist[ip];
00802 if ( particle ) delete particle; particle = 0;
00803 }
00804 particlelist.clear();
00805 }
00806 fEvtStdHepMap.clear();
00807
00808 }
00809
00810
00811 bool PTSimApplication::IsRockVetoed() {
00812
00813
00814
00815
00816 bool isRockVetoed = false;
00817
00818
00819 if ( !(gMC->TrackCharge()) ) return isRockVetoed;
00820
00821 Int_t copyNo = 0;
00822 if ( gMC -> CurrentVolID(copyNo)
00823 == gGeoManager->GetMasterVolume()->GetNumber() ) {
00824
00825 TGeoNode* node = gGeoManager->GetMasterVolume()->GetNode("LINR_1");
00826 TLorentzVector pos;
00827 gMC -> TrackPosition(pos);
00828 Double_t gxyz[3] = {pos.X(),pos.Y(),pos.Z()};
00829 Double_t safety = node -> Safety(gxyz,false);
00830 if ( safety > fRkVMinDistInCM ) {
00831 TLorentzVector mom;
00832 gMC->TrackMomentum(mom);
00833 if ( safety > fRkVFactor*mom.E()/fRockdEdXMin ) isRockVetoed = true;
00834 }
00835 }
00836
00837 return isRockVetoed;
00838
00839 }
00840
00841
00842 void PTSimApplication::InitRockdEdXMin() {
00843
00844
00845
00846
00847
00848
00849
00850 Double_t nominaldEdXMin = 1.2e-3;
00851
00852 TGeant3* geant3 = dynamic_cast<TGeant3*>(gMC);
00853 if ( !geant3 ) {
00854 MSG("PTSim",Msg::kWarning)
00855 << "No support for non-TGeant3 concrete VMC in InitRockdEdXMin\n"
00856 << "to determine minimum dE/dX from LOSS tables. Will use nominal "
00857 << "value of " << nominaldEdXMin << " GeV/(g/cm^2) * the density "
00858 << " of the rock." << endl;
00859 fRockdEdXMin = nominaldEdXMin
00860 * (gGeoManager->GetVolume("MARS")->GetMaterial()->GetDensity());
00861 }
00862 else {
00863
00864
00865
00866
00867
00868 Float_t log10KEmin = log10(geant3 -> Gcmulo() -> ekmin);
00869 log10KEmin = TMath::Max(log10KEmin,(Float_t)-5.);
00870 Float_t log10KEmax = log10(geant3 -> Gcmulo() -> ekmax);
00871
00872
00873
00874
00875
00876 const Int_t nlog10KEbin = 1000;
00877 Float_t* tkin = new Float_t[nlog10KEbin];
00878 Float_t* value = new Float_t[nlog10KEbin];
00879
00880
00881
00882 Float_t pcut[5] = {0};
00883
00884
00885
00886 TString volName = "MARS";
00887 TString matName;
00888 Int_t imate = 0;
00889 Double_t a, z, dens, radl, inter;
00890 TArrayD par;
00891 if ( !(geant3
00892 -> GetMaterial(volName,matName,imate,a,z,dens,radl,inter,par)) ) {
00893 MSG("PTSim",Msg::kError) << "Failed to retrieve material for volume "
00894 << volName.Data() << ". Abort." << endl;
00895 abort();
00896 }
00897 MSG("PTSim",Msg::kDebug)
00898 << "InitRockdEdXMin: GetMaterial for volume MARS retrieved:\n"
00899 << " imate " << imate << " a " << a << " z " << z << " dens " << dens
00900 << " name " << matName.Data() << endl;
00901
00902 Int_t ipart = 6;
00903
00904 char mechname[] = "LOSS";
00905
00906 Float_t de = (log10KEmax - log10KEmin)/(nlog10KEbin);
00907 for ( Int_t ie = 0; ie < nlog10KEbin; ie++ ) {
00908 Float_t log10tkin = log10KEmin + Float_t(ie)*de;
00909 tkin[ie] = pow((Float_t)10., log10tkin);
00910 value[ie] = 0;
00911 }
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 Int_t ixst = 0;
00926 geant3 -> Gftmat(imate,ipart,mechname,nlog10KEbin,tkin,value,pcut,ixst);
00927
00928 if ( ixst != 1 ) {
00929 MSG("PTSim",Msg::kError) << "Gftmat call to retrieve dE/dX for matId "
00930 << imate << " over log10(KE) range "
00931 << log10KEmin << " to " << log10KEmax
00932 << "\nfailed when initializing energy "
00933 << "threshold cuts. Abort." << endl;
00934 abort();
00935 }
00936
00937
00938 Float_t minValue = 1.e10;
00939 for ( Int_t ie = 0; ie < nlog10KEbin; ie++ ) {
00940 minValue = TMath::Min(value[ie],minValue);
00941 }
00942
00943 fRockdEdXMin = minValue*1.e-3;
00944
00945 delete [] tkin;
00946 delete [] value;
00947
00948 }
00949
00950 MSG("PTSim",Msg::kInfo)
00951 << "Initialize rock minimum dE/dX for application of veto cuts to: "
00952 << fRockdEdXMin << " (GeV/cm)" << endl;
00953
00954 return;
00955
00956 }
00957
00958