00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00013
00014 #include <TClonesArray.h>
00015 #include <TVirtualMC.h>
00016 #include <TPDGCode.h>
00017 #include <TDatabasePDG.h>
00018
00019 #include "Util/UtilIstHEP.h"
00020 #include "Conventions/Munits.h"
00021 #include "Digitization/DigiScintHit.h"
00022 #include "MessageService/MsgService.h"
00023 #include "ParticleTransportSim/PTSim.h"
00024 #include "ParticleTransportSim/PTSimStack.h"
00025
00026 ClassImp(PTSimStack)
00027
00028 CVSID("$Id: PTSimStack.cxx,v 1.33 2009/06/22 03:51:01 kasahara Exp $");
00029
00030 std::ostream& operator << (std::ostream& os, const PTSimStack& ps)
00031 { return ps.Print(os); }
00032
00033
00034 PTSimStack::PTSimStack() : fStdHepSaveByRange(false),
00035 fStdHepSaveSibling(1),
00036 fStdHepSaveAncestor(1),
00037 fStdHepSelectMask(PTSim::kMomentum),
00038 fStdHepHitThr(0.001),
00039 fStdHepThr(0.15) {
00040
00041
00042 MSG("PTSim",Msg::kVerbose) << "PTSimStack def ctor @ " << this << endl;
00043
00044 }
00045
00046
00047 PTSimStack::~PTSimStack() {
00048
00049
00050 MSG("PTSim",Msg::kVerbose) << "PTSimStack dtor @ " << this << endl;
00051 Reset();
00052
00053 }
00054
00055
00056 void PTSimStack::SetStdHepThrByType(double pthresh, TMCProcess process,
00057 Int_t pdgId, Int_t parentId) {
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 std::string particlename = "all particle types";
00072 if ( pdgId != kRootino ) {
00073 const TDatabasePDG& dbpdg = *(TDatabasePDG::Instance());
00074 particlename = "???";
00075 if ( dbpdg.GetParticle(pdgId) ) particlename
00076 = dbpdg.GetParticle(pdgId)->GetName();
00077 }
00078
00079
00080 std::string processname = "all production processes";
00081 if ( process != kPNoProcess ) {
00082 processname = TMCProcessName[process];
00083 }
00084
00085 if ( process == kPNoProcess ) {
00086 MSG("PTSim",Msg::kDebug) << "StdHepThrByType "
00087 << pthresh << "(GeV/c)"
00088 << " for particle type " << pdgId << "("
00089 << particlename.c_str() << ")" << endl;
00090 }
00091 else if ( pdgId == kRootino ) {
00092 MSG("PTSim",Msg::kDebug) << "StdHepThrByType "
00093 << pthresh << "(GeV/c)"
00094 << " for production process "
00095 << process << "(" << processname.c_str() << ")"
00096 << endl;
00097 }
00098 else {
00099 MSG("PTSim",Msg::kDebug) << "StdHepThrByType "
00100 << pthresh << "(GeV/c)"
00101 << " for particle type " << pdgId << "("
00102 << particlename.c_str() << ")"
00103 << " and production process "
00104 << process << "(" << processname.c_str() << ")"
00105 << endl;
00106 }
00107
00108 fStdHepThrByTypeMap[PTSimStdHepType(process,pdgId,parentId)] = pthresh;
00109
00110 }
00111
00112
00113 void PTSimStack::PushTrack(Int_t toBeDone, Int_t parentId, Int_t pdg,
00114 Double_t px, Double_t py, Double_t pz, Double_t e,
00115 Double_t vx, Double_t vy, Double_t vz, Double_t tof,
00116 Double_t polx, Double_t poly, Double_t polz,
00117 TMCProcess mech, Int_t& ntr, Double_t weight,
00118 Int_t status) {
00119
00120
00121
00122
00123
00124
00125
00126
00127 Int_t mechstatus = status;
00128 if ( mech != kPPrimary) mechstatus = (Int_t)UtilIstHEP::GetProdMethod(mech)
00129 + UtilIstHEP::kProdMethodOffset;
00130
00131 if ( mech == kPDecay ) {
00132
00133 const PTSimParticle* parent = GetParticle(parentId);
00134 const PTSimParticle* lastchild = dynamic_cast<const PTSimParticle*>
00135 (parent->GetChild(parent->GetNChildren()-1));
00136 Int_t decayparentId = -1;
00137 Int_t decayparentcode = UtilIstHEP::kMDecay
00138 + UtilIstHEP::kProdMethodOffset + 1000;
00139 if ( lastchild != 0 ) {
00140
00141 if ( lastchild -> GetStatusCode() == decayparentcode )
00142 decayparentId = lastchild->GetID();
00143 }
00144 if ( decayparentId < 0 ) {
00145
00146 TLorentzVector pos;
00147 gMC->TrackPosition(pos);
00148 TLorentzVector mom;
00149 gMC->TrackMomentum(mom);
00150 Int_t parentpdg = gMC->TrackPid();
00151
00152 MCAppStack<PTSimParticle>::PushTrack(0,parentId,parentpdg,
00153 mom.X(),mom.Y(),mom.Z(),mom.E(),pos.X(),pos.Y(),pos.Z(),pos.T(),
00154 0.,0.,0.,kPTransportation,decayparentId,1.,decayparentcode);
00155 }
00156
00157 MCAppStack<PTSimParticle>::PushTrack(toBeDone,decayparentId,pdg,
00158 px,py,pz,e,vx,vy,vz,tof,
00159 polx,poly,polz,mech,ntr,weight,
00160 mechstatus);
00161 }
00162 else {
00163
00164 MCAppStack<PTSimParticle>::PushTrack(toBeDone,parentId,pdg,
00165 px,py,pz,e,vx,vy,vz,tof,
00166 polx,poly,polz,mech,ntr,weight,
00167 mechstatus);
00168 }
00169
00170 }
00171
00172
00173 Double_t PTSimStack::GetStdHepThrByType(TMCProcess process, Int_t pdgId,
00174 Int_t parentId) const {
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 Double_t pthreshbytype = -1.;
00190
00191 PTSimStdHepType thrtype(process,pdgId,parentId);
00192 std::map<PTSimStdHepType,double>::const_iterator threshMapItr;
00193 threshMapItr = fStdHepThrByTypeMap.find(thrtype);
00194 if ( threshMapItr != fStdHepThrByTypeMap.end() ) {
00195
00196 pthreshbytype = threshMapItr -> second;
00197 }
00198
00199
00200 thrtype = PTSimStdHepType(process,kRootino,parentId);
00201 threshMapItr = fStdHepThrByTypeMap.find(thrtype);
00202 if ( threshMapItr != fStdHepThrByTypeMap.end() ) {
00203 if ( pthreshbytype < 0. ) pthreshbytype = threshMapItr -> second;
00204 else pthreshbytype = TMath::Min(pthreshbytype,threshMapItr->second);
00205 }
00206
00207
00208 thrtype = PTSimStdHepType(kPNoProcess,pdgId,parentId);
00209 threshMapItr = fStdHepThrByTypeMap.find(thrtype);
00210 if ( threshMapItr != fStdHepThrByTypeMap.end() ) {
00211 if ( pthreshbytype < 0. ) pthreshbytype = threshMapItr -> second;
00212
00213
00214
00215 else pthreshbytype = TMath::Min(pthreshbytype,threshMapItr->second);
00216 }
00217
00218 return pthreshbytype;
00219
00220 }
00221
00222
00223 void PTSimStack::FillStdHepArray(TClonesArray* stdheparray, Int_t snarl,
00224 TClonesArray* hitarray, Int_t firsthit) {
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 MSG("PTSim",Msg::kDebug) << "PTSimStack::FillStdHepArray for snarl "
00235 << snarl << endl;
00236
00237 if ( !stdheparray ) {
00238 MSG("PTSim",Msg::kFatal) << "PTSimStack::FillStdHepArray: Null "
00239 << "stdheparray TClonesArray ptr. Abort." << endl;
00240 abort();
00241 }
00242 if ( !hitarray ) {
00243 MSG("PTSim",Msg::kFatal) << "PTSimStack::FillStdHepArray: Null "
00244 << "hitarray TClonesArray ptr. Abort." << endl;
00245 abort();
00246 }
00247
00248 Int_t firsttrk = stdheparray -> GetEntriesFast();
00249 Int_t nstdhep = firsttrk;
00250 Int_t npart = GetNtrack();
00251
00252 MSG("PTSim",Msg::kDebug) << "PTSimStack::FillStdHepArray. Start with "
00253 << nstdhep << " particles in input stdhep array and "
00254 << npart << " particles in stack." << endl;
00255
00256
00257 bool savesecond = SaveSecondariesForSnarl(snarl);
00258
00259 Int_t decayparentcode = UtilIstHEP::kMDecay
00260 + UtilIstHEP::kProdMethodOffset + 1000;
00261
00262 std::stack<const PTSimParticle*> ministack;
00263
00264
00265 for ( Int_t ip = 0; ip < npart; ip++ ) {
00266
00267 PTSimParticle* particle = const_cast<PTSimParticle*>(GetParticle(ip));
00268
00269 if ( particle -> GetProcess() == kPPrimary ) {
00270
00271
00272 fPartToStdHep.insert(make_pair(particle->GetID(),nstdhep));
00273 TParticle* stdhep =
00274 new((*stdheparray)[nstdhep++])TParticle(*(particle->GetTParticle()));
00275
00276 stdhep -> SetProductionVertex(stdhep->Vx()*Munits::cm,
00277 stdhep->Vy()*Munits::cm,
00278 stdhep->Vz()*Munits::cm,stdhep->T());
00279
00280
00281 if ( particle->GetParentID(0) != -1 )
00282 stdhep->SetFirstMother(particle->GetParentID(0)+firsttrk);
00283 if ( particle->GetParentID(1) != -1 )
00284 stdhep->SetLastMother(particle->GetParentID(1)+firsttrk);
00285
00286 if ( particle -> GetNChildren() > 0 ) {
00287 if ( particle->GetStatusCode() == 1 ) {
00288 ministack.push(particle);
00289 }
00290 else {
00291 Int_t nchild = particle->GetNChildren();
00292 if ( particle->GetChild(nchild-1)->GetStatusCode() == 999 ) {
00293
00294 nchild += -1;
00295 }
00296 if ( nchild > 0 ) {
00297 stdhep->SetFirstDaughter(particle->GetChildID(0)+firsttrk);
00298 stdhep->SetLastDaughter(particle->GetChildID(nchild-1)+firsttrk);
00299 }
00300 }
00301 }
00302 }
00303 else if ( savesecond ) {
00304
00305 if ( decayparentcode != particle->GetStatusCode() ) {
00306 if ( ParticleIsSelected(particle) ) {
00307
00308
00309 particle -> SetToSave(true,fStdHepSaveAncestor,fStdHepSaveSibling);
00310 }
00311 }
00312 }
00313 }
00314
00315 while ( !ministack.empty() ) {
00316 const PTSimParticle* particle = ministack.top();
00317 ministack.pop();
00318
00319
00320
00321
00322
00323
00324 Int_t motherId = particle->GetID();
00325 std::map<int,int>::iterator idItr = fPartToStdHep.find(motherId);
00326 if (idItr == fPartToStdHep.end() ) {
00327 if (idItr == fPartToStdHep.end() ) {
00328 MSG("PTSim",Msg::kError) << "PTSimStack::FillStdHepArray motherId "
00329 << motherId << " not in map. abort." << endl;
00330 abort();
00331 }
00332 }
00333 Int_t motherstdindex = idItr->second;
00334
00335 Int_t nchildren = particle->GetNChildren();
00336 for ( Int_t ic = 0; ic < nchildren; ic++ ) {
00337 const PTSimParticle* child = dynamic_cast<const PTSimParticle*>
00338 (particle->GetChild(ic));
00339
00340 if ( child -> IsSetToSave() ) {
00341
00342 TParticle* stdhep
00343 = new((*stdheparray)[nstdhep])TParticle(*(child->GetTParticle()));
00344
00345 fPartToStdHep.insert(make_pair(child->GetID(),nstdhep));
00346 stdhep -> SetFirstMother(TMath::Abs(motherstdindex));
00347 stdhep -> SetLastMother(TMath::Abs(motherstdindex));
00348
00349 stdhep -> SetProductionVertex(stdhep->Vx()*Munits::cm,
00350 stdhep->Vy()*Munits::cm,
00351 stdhep->Vz()*Munits::cm,stdhep->T());
00352 TParticle* ancestor = dynamic_cast<TParticle*>
00353 (stdheparray->At(TMath::Abs(motherstdindex)));
00354 if(ancestor->GetFirstDaughter()< 0)
00355 ancestor->SetFirstDaughter(nstdhep);
00356 ancestor -> SetLastDaughter(nstdhep);
00357 nstdhep++;
00358 }
00359 else {
00360
00361
00362 fPartToStdHep.insert(make_pair(child->GetID(),
00363 -TMath::Abs(motherstdindex)));
00364 }
00365
00366
00367 if ( child->GetNChildren() > 0 ) {
00368 ministack.push(child);
00369 }
00370
00371 }
00372 }
00373
00374
00375 AdjustHitTrackId(hitarray,firsthit);
00376
00377 Int_t nfinal = stdheparray->GetEntriesFast();
00378 MSG("PTSim",Msg::kDebug) << "FillStdHepArray. Finish with "
00379 << nfinal << " particles in stdheparray." << endl;
00380
00381
00382 }
00383
00384
00385 void PTSimStack::Reset() {
00386 MSG("PTSim",Msg::kVerbose) << "PTSimStack::Reset " << endl;
00387
00388 MCAppStack<PTSimParticle>::Reset();
00389 fPartToStdHep.clear();
00390
00391 }
00392
00393
00394
00395 bool PTSimStack::SaveSecondariesForSnarl(Int_t snarl) const {
00396
00397
00398
00399
00400 bool savesecond = false;
00401 if ( !fStdHepSaveByRange ) {
00402 for ( unsigned int is = 0; is < fStdHepSave.size(); is++ ) {
00403 if ( snarl == fStdHepSave[is] ) { savesecond = true; break; }
00404 }
00405 }
00406 else {
00407 if ( snarl <= fStdHepSave[1] && snarl >= fStdHepSave[0] ) {
00408 savesecond = true;
00409 }
00410 }
00411
00412 return savesecond;
00413
00414 }
00415
00416
00417
00418 bool PTSimStack::ParticleIsSelected(const PTSimParticle* particle) const {
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 if ( particle -> GetProcess() == kPPrimary ) return true;
00443
00444
00445 if ( fStdHepSelectMask & PTSim::kHit ) {
00446 if ( particle -> HasHitAboveThresh() ) return true;
00447 }
00448
00449 if ( fStdHepSelectMask & PTSim::kMomentum ) {
00450
00451
00452
00453
00454
00455 Int_t pdgId = particle -> GetPdgCode();
00456 TMCProcess process = particle -> GetProcess();
00457
00458 Double_t pthresh = GetStdHepThrByType(process,pdgId,kRootino);
00459
00460 for ( UInt_t ip = 0; ip < particle->GetNParents(); ip++ ) {
00461 Int_t parentId = particle->GetParent(ip)->GetPdgCode();
00462 Double_t pthreshbytype = GetStdHepThrByType(process,pdgId,parentId);
00463 if ( pthreshbytype >= 0 ) {
00464 if ( pthresh >= 0 ) pthresh = TMath::Min(pthresh,pthreshbytype);
00465 else pthresh = pthreshbytype;
00466 }
00467 }
00468 if ( pthresh < 0 ) pthresh = GetStdHepThr();
00469 if ( particle -> GetTParticle() -> P() >= pthresh ) return true;
00470 }
00471
00472
00473 return false;
00474
00475 }
00476
00477
00478
00479 void PTSimStack::AdjustHitTrackId(TClonesArray* hitarray,
00480 Int_t firsthit) const {
00481
00482
00483
00484 for ( Int_t ihit = firsthit; ihit < hitarray->GetEntriesFast(); ihit++ ) {
00485 DigiScintHit* hit = dynamic_cast<DigiScintHit*>(hitarray->At(ihit));
00486 Int_t trackid = hit->TrackId();
00487 Int_t stdhepid = GetStdHepIndex(trackid);
00488
00489 hit -> SetTrackId(stdhepid);
00490 }
00491
00492 }
00493
00494
00495 Int_t PTSimStack::GetStdHepIndex(UInt_t id) const {
00496
00497
00498
00499
00500 std::map<int,int>::const_iterator idItr = fPartToStdHep.find(id);
00501 if (idItr == fPartToStdHep.end() ) {
00502 MSG("PTSim",Msg::kError) << "PTSimStack::GetStdHepIndex for trk Id " << id
00503 << " not in map. abort." << endl;
00504 abort();
00505 }
00506 return idItr->second;
00507
00508 }
00509