00001 #include "SimG4Core/PhysicsLists/interface/CMSMonopolePhysics.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003
00004 #include "G4ParticleDefinition.hh"
00005 #include "G4ProcessManager.hh"
00006
00007 #include "G4StepLimiter.hh"
00008 #include "G4Transportation.hh"
00009 #include "G4MonopoleTransportation.hh"
00010 #include "G4mplIonisation.hh"
00011 #include "G4mplIonisationWithDeltaModel.hh"
00012 #include "G4hMultipleScattering.hh"
00013 #include "G4hIonisation.hh"
00014 #include "G4hhIonisation.hh"
00015
00016 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00017
00018 CMSMonopolePhysics::CMSMonopolePhysics(const HepPDT::ParticleDataTable * pdt,
00019 sim::FieldBuilder * fB_,
00020 const edm::ParameterSet & p) :
00021 G4VPhysicsConstructor("Monopole Physics"), fieldBuilder(fB_) {
00022
00023 verbose = p.getUntrackedParameter<int>("Verbosity",0);
00024 magCharge = p.getUntrackedParameter<int>("MonopoleCharge",1);
00025 deltaRay = p.getUntrackedParameter<bool>("MonopoleDeltaRay",true);
00026 multiSc = p.getUntrackedParameter<bool>("MonopoleMultiScatter",false);
00027 transport = p.getUntrackedParameter<bool>("MonopoleTransport",true);
00028 double mass = p.getUntrackedParameter<double>("MonopoleMass",200);
00029 if (pdt && mass > 0.0) {
00030 int ii=0;
00031 for (HepPDT::ParticleDataTable::const_iterator p=pdt->begin();
00032 p != pdt->end(); ++p,++ii) {
00033 HepPDT::ParticleData particle = (p->second);
00034 std::string particleName = (particle.name()).substr(0,8);
00035 if (strcmp(particleName.c_str(),"Monopole") == 0) {
00036 names.push_back(particle.name());
00037 masses.push_back(mass*CLHEP::GeV);
00038 elCharges.push_back((int)(particle.charge()));
00039 pdgEncodings.push_back(particle.pid());
00040 monopoles.push_back(0);
00041
00042 if (verbose > 0) G4cout << "CMSMonopolePhysics: Monopole[" << ii
00043 << "] " << particleName << " Mass "
00044 << particle.mass() << " GeV, Magnetic Charge "
00045 << magCharge << ", Electric Charge "
00046 << particle.charge() << G4endl;
00047 } else if(strcmp(particleName.c_str(),"AntiMono") == 0) {
00048 names.push_back(particle.name());
00049 masses.push_back(mass*CLHEP::GeV);
00050 elCharges.push_back((int)(particle.charge()));
00051 pdgEncodings.push_back(particle.pid());
00052 monopoles.push_back(0);
00053
00054 if (verbose > 0) G4cout << "CMSMonopolePhysics: Monopole[" << ii
00055 << "] " << particleName << " Mass "
00056 << particle.mass() << " GeV, Magnetic Charge "
00057 << magCharge << ", Electric Charge "
00058 << particle.charge() << G4endl;
00059 }
00060 }
00061 }
00062
00063 if (verbose > 0) G4cout << "CMSMonopolePhysics has " << names.size()
00064 << " monopole candidates and delta Ray option "
00065 << deltaRay << G4endl;
00066 }
00067
00068 CMSMonopolePhysics::~CMSMonopolePhysics() {}
00069
00070 void CMSMonopolePhysics::ConstructParticle() {
00071
00072 for (unsigned int ii=0; ii<names.size(); ++ii) {
00073 if (!monopoles[ii]) {
00074 G4Monopole* mpl = new G4Monopole(names[ii], pdgEncodings[ii],
00075 masses[ii], ((pdgEncodings[ii] > 0 ) ? magCharge : -magCharge), elCharges[ii]);;
00076 monopoles[ii] = mpl;
00077
00078 if (verbose > 0) G4cout << "Create G4Monopole " << names[ii]
00079 << " of mass " << masses[ii]/CLHEP::GeV
00080 << " GeV, magnetic charge " << ((pdgEncodings[ii] > 0) ? magCharge : -magCharge)
00081 << ", electric charge " << elCharges[ii]
00082 << " and PDG encoding " << pdgEncodings[ii]
00083 << " at " << monopoles[ii] << G4endl;
00084 }
00085 }
00086 }
00087
00088 void CMSMonopolePhysics::ConstructProcess() {
00089
00090
00091 if (verbose > 0)
00092 G4cout << "### CMSMonopolePhysics ConstructProcess()" << G4endl;
00093 for (unsigned int ii=0; ii<monopoles.size(); ++ii) {
00094 if (monopoles[ii]) {
00095 G4Monopole* mpl = monopoles[ii];
00096 G4ProcessManager* pmanager = new G4ProcessManager(mpl);
00097 mpl->SetProcessManager(pmanager);
00098
00099 G4String particleName = mpl->GetParticleName();
00100 G4double magn = mpl->MagneticCharge();
00101 G4double mass = mpl->GetPDGMass();
00102 if (verbose > 1)
00103 G4cout << "### CMSMonopolePhysics instantiates for " << particleName
00104 << " at " << mpl << " Mass " << mass/CLHEP::GeV
00105 << " GeV Mag " << magn << " Process manager " << pmanager
00106 << G4endl;
00107
00108
00109
00110 G4double emin = mass/20000.;
00111 if(emin < CLHEP::keV) emin = CLHEP::keV;
00112 G4double emax = std::max(10.*CLHEP::TeV, mass*100);
00113 G4int nbin = G4int(std::log10(emax/emin));
00114 if (nbin < 1) nbin = 1;
00115 nbin *= 10;
00116
00117 G4int idx = 1;
00118 if (verbose > 1)
00119 G4cout << "### Magnetic charge " << magn << " and electric charge "
00120 << mpl->GetPDGCharge() <<"\n # of bins in dE/dx table = "
00121 << nbin << " in the range " << emin << ":" << emax << G4endl;
00122
00123 if (magn == 0.0 || (!transport)) {
00124 pmanager->AddProcess( new G4Transportation(verbose), -1, 0, 0);
00125 } else {
00126 pmanager->AddProcess( new G4MonopoleTransportation(mpl,fieldBuilder,verbose), -1, 0, 0);
00127 }
00128
00129 if (mpl->GetPDGCharge() != 0.0) {
00130 if (multiSc) {
00131 G4hMultipleScattering* hmsc = new G4hMultipleScattering();
00132 pmanager->AddProcess(hmsc, -1, idx, idx);
00133 ++idx;
00134 }
00135 if (deltaRay) {
00136 G4hIonisation* hhioni = new G4hIonisation();
00137 hhioni->SetDEDXBinning(nbin);
00138 hhioni->SetMinKinEnergy(emin);
00139 hhioni->SetMaxKinEnergy(emax);
00140 pmanager->AddProcess(hhioni, -1, idx, idx);
00141 } else {
00142 G4hhIonisation* hhioni = new G4hhIonisation();
00143 hhioni->SetDEDXBinning(nbin);
00144 hhioni->SetMinKinEnergy(emin);
00145 hhioni->SetMaxKinEnergy(emax);
00146 pmanager->AddProcess(hhioni, -1, idx, idx);
00147 }
00148 ++idx;
00149 }
00150 if(magn != 0.0) {
00151 G4mplIonisation* mplioni = new G4mplIonisation(magn);
00152 mplioni->SetDEDXBinning(nbin);
00153 mplioni->SetMinKinEnergy(emin);
00154 mplioni->SetMaxKinEnergy(emax);
00155 if (!deltaRay) {
00156 G4mplIonisationWithDeltaModel* mod =
00157 new G4mplIonisationWithDeltaModel(magn,"PAI");
00158 mplioni->AddEmModel(0,mod,mod);
00159 }
00160 pmanager->AddProcess(mplioni, -1, idx, idx);
00161 ++idx;
00162 }
00163 pmanager->AddProcess( new G4StepLimiter(), -1, -1, idx);
00164 if (verbose > 1) pmanager->DumpInfo();
00165 }
00166 }
00167 }