00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #include <cassert>
00012
00013
00014 #include <TClonesArray.h>
00015 #include <TVirtualMC.h>
00016 #include <TMCProcess.h>
00017 #include <TPDGCode.h>
00018 #include <TDatabasePDG.h>
00019
00020 #include "MessageService/MsgService.h"
00021 #include "JobControl/JobCommand.h"
00022 #include "JobControl/JobCModuleRegistry.h"
00023 #include "ParticleTransportSim/PTSim.h"
00024 #include "ParticleTransportSim/PTSimModule.h"
00025 #include "ParticleTransportSim/PTSimApplication.h"
00026 #include "ParticleTransportSim/PTSimStack.h"
00027 #include "MCApplication/MCApplication.h"
00028 #include "Util/LoadMinosPDG.h"
00029 #include "Util/UtilString.h"
00030 #include "Record/SimSnarlRecord.h"
00031 #include "MinosObjectMap/MomNavigator.h"
00032
00033 ClassImp(PTSimModule)
00034
00035
00036
00037
00038 CVSID("$Id: PTSimModule.cxx,v 1.56 2009/06/22 03:51:01 kasahara Exp $");
00039
00040 JOBMODULE(PTSimModule, "PTSimModule",
00041 "A module for running the particle transport simulation.");
00042
00043
00044 PTSimModule::PTSimModule(): fMCConfig("<null>"),fDecayConfig("<null>"),
00045 fMCAppUser(0),fRandomSeed(0) {
00046
00047
00048 LoadMinosPDG();
00049
00050 fStopwatch.Reset();
00051 fStopwatch.Stop();
00052
00053
00054
00055 fMCAppUser = new PTSimApplication("PTSimApplication","Minos MC Application");
00056 if ( !fMCAppUser ) {
00057 MSG("PTSim",Msg::kFatal) << "No MC application instance." << endl;
00058 abort();
00059 }
00060
00061
00062 }
00063
00064
00065 PTSimModule::~PTSimModule() {
00066
00067
00068 MSG("PTSim",Msg::kDebug) << "PTSimModule dtor @ " << this << endl;
00069
00070 if ( fMCAppUser ) delete fMCAppUser; fMCAppUser = 0;
00071
00072
00073
00074 MCApplication& mcapp = const_cast<MCApplication&>(MCApplication::Instance());
00075 mcapp.Clear();
00076
00077 }
00078
00079
00080 const Registry& PTSimModule::DefaultConfig() const {
00081
00082
00083
00084
00085
00086
00087
00088
00089 MSG("PTSim",Msg::kDebug) << "Loading default config" << endl;
00090
00091 static Registry r;
00092 std::string name = this->JobCModule::GetName();
00093 name += ".config.default";
00094 r.SetName(name.c_str());
00095
00096 r.UnLockValues();
00097 r.Set("MCConfig","<null>");
00098 r.Set("DecayConfig","<null>");
00099 r.Set("StdHepSelectMask",PTSim::kMomentum);
00100
00101
00102 r.Set("StdHepThr",0.15);
00103
00104
00105
00106 r.Set("StdHepHitThr",0.001);
00107
00108
00109
00110 r.Set("StdHepSaveSibling",2);
00111
00112 r.Set("StdHepSaveAncestor",1);
00113 r.Set("RandomSeed",fRandomSeed);
00114 r.Set("RkVLevel",0);
00115 r.Set("RkVMinDist",2.);
00116
00117
00118 r.Set("RkVFactor",1.25);
00119 r.Set("UseLinearStep",false);
00120
00121 r.LockValues();
00122
00123
00124
00125
00126 PTSimStack* stack = fMCAppUser -> GetStack();
00127 if ( !stack ) {
00128 MSG("PTSim",Msg::kFatal) << "No stack!" << endl;
00129 abort();
00130 }
00131
00132
00133 stack -> SetStdHepThrByType(0.,kPNoProcess,-13);
00134 stack -> SetStdHepThrByType(0.,kPNoProcess,+13);
00135
00136 stack -> SetStdHepThrByType(0.,kPDecay,kRootino,-13);
00137 stack -> SetStdHepThrByType(0.,kPDecay,kRootino,+13);
00138
00139
00140 return r;
00141 }
00142
00143
00144
00145 void PTSimModule::Config(const Registry& r) {
00146
00147
00148
00149
00150
00151
00152
00153
00154 MSG("PTSim",Msg::kDebug) << "Config PTSimModule with r=" << r << endl;
00155
00156 Int_t tmpi;
00157 Double_t tmpd;
00158 const Char_t* tmpc;
00159 if ( r.Get("MCConfig",tmpc) ) fMCConfig = tmpc;
00160 if ( r.Get("DecayConfig",tmpc) ) fDecayConfig = tmpc;
00161
00162 PTSimStack* stack = fMCAppUser -> GetStack();
00163 if ( r.Get("StdHepThr",tmpd) ) stack -> SetStdHepThr(tmpd);
00164 if ( r.Get("StdHepHitThr",tmpd) ) stack -> SetStdHepHitThr(tmpd);
00165 if ( r.Get("StdHepSelectMask",tmpi) ) stack -> SetStdHepSelectMask(tmpi);
00166 if ( r.Get("StdHepSaveSibling",tmpi) ) stack -> SetStdHepSaveSibling(tmpi);
00167 if ( r.Get("StdHepSaveAncestor",tmpi) ) stack -> SetStdHepSaveAncestor(tmpi);
00168 if ( r.Get("RandomSeed",tmpi) ) fRandomSeed = tmpi;
00169 if ( r.Get("RkVLevel",tmpi) ) fMCAppUser -> SetRkVLevel(tmpi);
00170 if ( r.Get("RkVMinDist",tmpd) ) fMCAppUser -> SetRkVMinDistInCM(tmpd*100.);
00171 if ( r.Get("RkVFactor",tmpd) ) fMCAppUser -> SetRkVFactor(tmpd);
00172 if ( r.Get("UseLinearStep",tmpi) ) fMCAppUser -> UseLinearStep(tmpi);
00173
00174 }
00175
00176
00177 void PTSimModule::BeginJob() {
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 MSG("PTSim",Msg::kDebug) << "PTSimModule::BeginJob" << endl;
00188
00189
00190
00191
00192 }
00193
00194
00195 void PTSimModule::EndJob() {
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 MSG("PTSim",Msg::kDebug) << "PTSimModule::EndJob" << endl;
00206
00207
00208
00209 fStopwatch.Stop();
00210 Int_t nSnarl = 0;
00211 Int_t nEvent = 0;
00212 if ( fMCAppUser ) {
00213 nSnarl = fMCAppUser -> GetNSnarls();
00214 nEvent = fMCAppUser -> GetNEvents();
00215 }
00216
00217 MSG("PTSim",Msg::kInfo) << "PTSimModule::EndJob, Time(sec), Real "
00218 << fStopwatch.RealTime() << ", CPU "
00219 << fStopwatch.CpuTime() << " # snarls/events "
00220 << nSnarl << "/" << nEvent << endl;
00221
00222 }
00223
00224
00225 void PTSimModule::HandleCommand(JobCommand* cmd) {
00226
00227
00228
00229 if ( !cmd->HaveCmd() ) return;
00230 string s = cmd->PopCmd();
00231 if ( s == "StdHepThrByType" ) {
00232 UtilIstHEP::EProdMethod prodmethod = UtilIstHEP::kMNoProcess;
00233 Int_t pdgId = kRootino;
00234 Int_t parentId = kRootino;
00235 double thresh = 0.;
00236 if ( cmd->HaveOpt() ) {
00237 thresh = cmd->PopFloatOpt();
00238
00239 if ( cmd->HaveOpt() ) {
00240 int prodmethodint = cmd -> PopIntOpt();
00241 if ( prodmethodint < 0 || prodmethodint >= UtilIstHEP::kNProdMethod ){
00242 MSG("PTSim",Msg::kWarning)
00243 << "StdHepThrByType called w/invalid UtilIstHEP::EProdMethod "
00244 << prodmethodint << ". Ignored." << endl;
00245 return;
00246 }
00247 else prodmethod = (UtilIstHEP::EProdMethod)(prodmethodint);
00248
00249 if ( cmd->HaveOpt() ) {
00250 pdgId = cmd -> PopIntOpt();
00251 if ( cmd->HaveOpt() ) parentId = cmd -> PopIntOpt();
00252 }
00253 }
00254 else {
00255 MSG("PTSim",Msg::kWarning)
00256 << "StdHepThrByType called w/no production method. Ignored."
00257 << endl;
00258 return;
00259 }
00260 }
00261 else {
00262 MSG("PTSim",Msg::kWarning)
00263 << "StdHepThrByType called w/no momentum threshold. Ignored."
00264 << endl;
00265 return;
00266 }
00267
00268
00269 std::string particlename = " for particles of type ";
00270 if ( pdgId != kRootino ) {
00271 particlename += UtilString::ToString<int>(pdgId) + "/";
00272 const TDatabasePDG& dbpdg = *(TDatabasePDG::Instance());
00273 particlename += "???";
00274 if ( dbpdg.GetParticle(pdgId) ) particlename
00275 += dbpdg.GetParticle(pdgId)->GetName();
00276 }
00277 else particlename = "";
00278
00279 std::string parentname = " for particles w/parent type ";
00280 if ( !particlename.empty() ) parentname = " and parent type ";
00281 if ( parentId != kRootino ) {
00282 parentname += UtilString::ToString<int>(parentId) + "/";
00283 const TDatabasePDG& dbpdg = *(TDatabasePDG::Instance());
00284 parentname += "???";
00285 if ( dbpdg.GetParticle(parentId) ) parentname
00286 += dbpdg.GetParticle(parentId)->GetName();
00287 }
00288 else parentname = "";
00289
00290 if ( prodmethod == UtilIstHEP::kMNoProcess ) {
00291 MSG("PTSim",Msg::kInfo) << "PTSimModule StdHepThrByType "
00292 << "configured to " << thresh << "(GeV/c)"
00293 << particlename.c_str()
00294 << parentname.c_str()
00295 << endl;
00296 }
00297 else {
00298 std::string prodmethodname = " for particles produced by ";
00299 if ( !parentname.empty() || !particlename.empty() )
00300 prodmethodname = " and produced by ";
00301 MSG("PTSim",Msg::kInfo) << "PTSimModule StdHepThrByType "
00302 << "configured to " << thresh << "(GeV/c)"
00303 << particlename.c_str()
00304 << parentname.c_str()
00305 << prodmethodname.c_str() << prodmethod
00306 << "/" << UtilIstHEP::AsString(prodmethod)
00307 << endl;
00308 }
00309
00310 PTSimStack* stack = fMCAppUser -> GetStack();
00311 TMCProcess tmcprocess = UtilIstHEP::GetTMCProcess(prodmethod);
00312 stack -> SetStdHepThrByType(thresh,tmcprocess,pdgId,parentId);
00313 return;
00314 }
00315 else if ( s == "StdHepSave" ) {
00316
00317 std::vector<int> snarllist;
00318 MsgStream& msgDebug = MSGSTREAM("PTSim",Msg::kDebug);
00319 msgDebug << "StdHepSave ";
00320
00321 bool isrange = false;
00322 Int_t nsnarl = 0;
00323 while ( cmd->HaveOpt() ) {
00324 Int_t snarlno = cmd->PopIntOpt();
00325 msgDebug << snarlno << " ";
00326 snarllist.push_back(TMath::Abs(snarlno));
00327 nsnarl++;
00328 if ( snarlno < 0 ) isrange = true;
00329 }
00330 msgDebug << endl;
00331 if ( isrange && nsnarl != 2 ) {
00332 MSG("PTSim",Msg::kWarning)
00333 << "StdHepSave by range requires two arguments. Ignored." << endl;
00334 snarllist.clear();
00335 isrange = false;
00336 }
00337
00338 PTSimStack* stack = fMCAppUser -> GetStack();
00339 stack -> SetStdHepSave(snarllist,isrange);
00340
00341 return;
00342 }
00343
00344
00345 MSG("PTSim",Msg::kError) << "Illegal command: " << s.c_str() << endl;
00346
00347 }
00348
00349
00350 JobCResult PTSimModule::Reco(MomNavigator *mom) {
00351
00352
00353
00354
00355
00356
00357
00358
00359 JobCResult result(JobCResult::kPassed);
00360 MSG("PTSim",Msg::kDebug) << "PTSimModule::Reco" << endl;
00361
00362
00363 assert(mom);
00364
00365 SimSnarlRecord* record
00366 = dynamic_cast<SimSnarlRecord*>(mom->GetFragment("SimSnarlRecord"));
00367 if ( !record ) {
00368 MSG("PTSim",Msg::kError) << "No SimSnarlRecord in Mom." << endl;
00369 result.SetWarning().SetFailed();
00370 return result;
00371 }
00372
00373 RecJobHistory& jobhist
00374 = const_cast<RecJobHistory&>(record->GetJobHistory());
00375 jobhist.CreateJobRecord(RecJobHistory::kPTSim);
00376
00377 const SimSnarlHeader* header= record->GetSimSnarlHeader();
00378
00379 MCApplication& mcapp = const_cast<MCApplication&>(MCApplication::Instance());
00380 const VldContext& vldc = *(record -> GetVldContext());
00381 if ( !(mcapp.GetMC() ) ) {
00382
00383 mcapp.InitMC(fMCConfig.c_str(),vldc,fDecayConfig.c_str());
00384
00385 }
00386 mcapp.InitSnarl(vldc);
00387
00388
00389 mcapp.SetUserApplication(fMCAppUser);
00390
00391
00392
00393
00394
00395
00396 TClonesArray* stdheparray = dynamic_cast<TClonesArray*>(const_cast<TObject*>
00397 (record -> FindComponent("TClonesArray","StdHep")));
00398
00399 if ( !stdheparray || stdheparray->GetEntriesFast() == 0 ) {
00400 MSG("PTSim",Msg::kWarning)
00401 << "No StdHep TClonesArray in SimSnarlRecord or is empty." << endl;
00402 return JobCResult::kError;
00403 }
00404
00405
00406
00407
00408 const TClonesArray* neukinarray = dynamic_cast<const TClonesArray*>
00409 (record -> FindComponent("TClonesArray","NeuKinList"));
00410 Int_t nevent = 1;
00411 if ( neukinarray && neukinarray->GetEntriesFast() != 0 )
00412 nevent = neukinarray->GetEntriesFast();
00413
00414
00415
00416 TClonesArray* hitarray = dynamic_cast<TClonesArray*>(const_cast<TObject*>
00417 (record -> FindComponent("TClonesArray","DigiScintHits")));
00418 if ( hitarray ) hitarray -> Clear("C");
00419 else {
00420 hitarray = new TClonesArray("DigiScintHit");
00421 hitarray -> SetName("DigiScintHits");
00422 record -> AdoptComponent(hitarray);
00423 }
00424
00425
00426
00427
00428 Int_t run = header -> GetRun();
00429 Int_t snarl = header -> GetSnarl();
00430 Int_t seed = run+snarl+fRandomSeed;
00431 MSG("PTSim",Msg::kDebug) << "Random number seed for run,snarl("
00432 << run << "," << snarl << ") = " << seed << endl;
00433 mcapp.GetRandom() -> SetSeed(seed);
00434
00435 fMCAppUser -> SetHitArray(hitarray);
00436
00437 fMCAppUser -> InitSnarl(snarl,stdheparray,nevent);
00438
00439 fStopwatch.Start(false);
00440
00441 gMC -> ProcessRun(nevent);
00442 fStopwatch.Stop();
00443
00444 return result;
00445
00446 }
00447
00448
00449
00450
00451
00452
00453