Generates a muon beam that fills the beam box with muons distributed like cosmic rays. After the simulation is complete, an estimate of the exposure time is printed (for apparatus at sea level). The primary vertices are on the "celestial sphere", which should be outside the apparatus; all muons generated will intersect the beam box (unless scattered or absorbed or decayed beforehand), so CPU time is not wasted on tracks missing the apparatus. Define the beam box appropriately.
Note that the z axis is vertical, increasing DOWNWARD. The "nominal" beam muons propagate in the +z direction. All primary vertices will be in the z<0 half of the celestial sphere, and all muons will have a direction with positive z component; no beam muon is more than 70 degrees from heading vertically downward.
For now, this is just mu+.
Method: First, an initial vertex is selected uniformly in the beam box (beamWidth,beamHeight,beamLength), and a muon is generated with appropriate momentum and angular distribution. This track is extended to the center of the beam box, and hits counts the number of hits inside the beam box at its midplane. Then if radius>0 the track is extended backwards to where it intersects the "celestial sphere" -- the sphere with R=radius centered at the center of the beam box. If radius<=0 then the primary vertices will be on the midplane of the beam box.
Public Member Functions | |
BLCMDcosmicraybeam () | |
Constructor. | |
G4String | commandName () |
commandName() returns "cosmicraybeam". | |
int | command (BLArgumentVector &argv, BLArgumentMap &namedArgs) |
command() implements the cosmicraybeam command. | |
void | printBeam () |
printBeam() will print a description. | |
void | defineNamedArgs () |
defineNamedArgs() defines the named arguments for this command. | |
int | getNEvents () const |
getNEvents() returns the # events to process. | |
void | init () |
init() will initialize internal variables. | |
bool | generateReferenceParticle (G4Event *event) |
generateReferenceParticle() generates the reference particle. | |
bool | nextBeamEvent (G4Event *event) |
nextBeamEvent() generates the next beam event. | |
void | summary () |
summary() will print a summary. | |
double | cosmicRayMuonMomentum () |
cosmicRayMuonMomentum() returns a random momentum value distributed like the muons from cosmic rays. Average momentum is 3.0*GeV/c, cutoff is 120*GeV/c. Return value is in geant4 units (MeV). Data from Kremer et al, Phys. Rev. Lett., Vol 83 no 21, p4241 (1999) | |
double | cosmicRayMuonAngle () |
cosmicRayMuonAngle() returns a random angle distributed like the polar angle of cosmic ray muons. The return value is the polar angle from vertical (radians). It is cut off at 70 degrees. Note this is the distribution for muons of ~3 GeV/c, which is the average momentum. In fact, lower energy muons have a steeper distribution and higher ones have a flatter distribution. But this is a reasonable approximation. Particle Data Group, Review of Particle Properties, 2002. Section 23.3.1. | |
Private Attributes | |
G4double | meanMomentum |
G4double | beamZ |
G4double | beamWidth |
G4double | beamHeight |
G4double | beamLength |
G4ParticleGun * | muonGun |
G4ParticleDefinition * | muon |
G4double | radius |
G4long | hits |
G4double | sterradians |
G4double | hitsPerM2PerSecPerSterrad |
G4String | particle |
G4int | evNumber |
BLCMDcosmicraybeam::BLCMDcosmicraybeam | ( | ) |
Constructor.
References beamHeight, beamLength, beamWidth, beamZ, BLCMDTYPE_BEAM, evNumber, hits, hitsPerM2PerSecPerSterrad, meanMomentum, muon, muonGun, particle, radius, BLCommand::registerCommand(), BLCommand::setDescription(), BLCommand::setSynopsis(), and sterradians.
00124 : BLBeam() 00125 { 00126 registerCommand(BLCMDTYPE_BEAM); 00127 setSynopsis("Define a Cosmic-Ray muon 'beam'."); 00128 setDescription("The muon beam is nominally headed in the +Z direction,\n" 00129 "implying that +Z is physically DOWN.\n" 00130 "The beam intersects a box defined by beamWidth, beamHeight,\n" 00131 "and beamLength, centered at X=Y=0 and beamZ. For each\n" 00132 "event a point is selected randomly within this box, angles\n" 00133 "theta and phi and the muon momentum are generated according\n" 00134 "to a fit to their sea-level distributions, the track is\n" 00135 "extended backwards to the 'celestial sphere', and that is\n" 00136 "the initial beam position for the event. The muon flux\n" 00137 "through the rectangle at Z=beamZ is used to display an\n" 00138 "estimate of the sea-level exposure time for the run."); 00139 00140 meanMomentum = 3.0*GeV; 00141 beamZ = 0.0; 00142 beamWidth = 0.0; 00143 beamHeight = 0.0; 00144 beamLength = 0.0; 00145 muonGun = 0; 00146 muon = 0; 00147 radius = 0.0; 00148 hits = 0; 00149 sterradians = 0.0; 00150 hitsPerM2PerSecPerSterrad = 0.0; 00151 particle = "mu+"; 00152 evNumber = 0; 00153 }
G4String BLCMDcosmicraybeam::commandName | ( | ) | [inline, virtual] |
int BLCMDcosmicraybeam::command | ( | BLArgumentVector & | argv, | |
BLArgumentMap & | namedArgs | |||
) | [virtual] |
command() implements the cosmicraybeam command.
Implements BLCommand.
References BLManager::getObject(), BLGroup::getWorld(), BLCommand::handleNamedArgs(), printBeam(), BLCommand::printError(), radius, BLManager::registerBeam(), BLGroup::setMinHeight(), BLGroup::setMinLength(), and BLGroup::setMinWidth().
00156 { 00157 if(argv.size() != 0) { 00158 printError("Invalid cosmicraybeam command"); 00159 return -1; 00160 } 00161 00162 handleNamedArgs(namedArgs); 00163 00164 // ensure our muons are within the world. 00165 BLGroup::getWorld()->setMinWidth(radius*2.0); 00166 BLGroup::getWorld()->setMinHeight(radius*2.0); 00167 BLGroup::getWorld()->setMinLength(radius*2.0); 00168 00169 BLManager::getObject()->registerBeam(this); 00170 00171 printBeam(); 00172 00173 return 0; 00174 }
void BLCMDcosmicraybeam::printBeam | ( | ) |
printBeam() will print a description.
References beamHeight, beamLength, beamWidth, beamZ, BLBeam::nEvents, particle, and radius.
Referenced by command().
00187 { 00188 printf("cosmicraybeam mu+ particle=%s ",particle.c_str()); 00189 printf("nEvents=%d ",nEvents); 00190 printf("beamZ=%.1f ",beamZ); 00191 printf("radius=%.3f ",radius); 00192 printf("\n\t\t"); 00193 printf("beamHeight=%.1f ",beamHeight); 00194 printf("beamWidth=%.1f ",beamWidth); 00195 printf("beamLength=%.3f ",beamLength); 00196 printf("\n"); 00197 }
void BLCMDcosmicraybeam::defineNamedArgs | ( | ) | [virtual] |
defineNamedArgs() defines the named arguments for this command.
Reimplemented from BLCommand.
References BLCommand::argDouble(), BLCommand::argInt(), beamHeight, beamLength, beamWidth, beamZ, BLBeam::nEvents, and radius.
00177 { 00178 argInt(nEvents,"nEvents","Number of events to process"); 00179 argDouble(beamZ,"beamZ","Beam location in Z (mm)",mm); 00180 argDouble(radius,"radius","Radius of celestial sphere (mm)",mm); 00181 argDouble(beamHeight,"beamHeight","Rectangular Beam height (mm)",mm); 00182 argDouble(beamWidth,"beamWidth","Rectangular Beam width (mm)",mm); 00183 argDouble(beamLength,"beamLength","Rectangular Beam length (mm)",mm); 00184 }
int BLCMDcosmicraybeam::getNEvents | ( | ) | const [inline, virtual] |
getNEvents() returns the # events to process.
Reimplemented from BLBeam.
References BLBeam::nEvents.
00089 { return nEvents; }
void BLCMDcosmicraybeam::init | ( | ) | [virtual] |
init() will initialize internal variables.
Implements BLBeam.
References evNumber, muon, muonGun, and particle.
Referenced by cosmicRayMuonAngle(), and cosmicRayMuonMomentum().
00200 { 00201 if(muon != 0) return; 00202 00203 muon = G4ParticleTable::GetParticleTable()->FindParticle(particle); 00204 muonGun = new G4ParticleGun(1); 00205 muonGun->SetParticleDefinition(muon); 00206 evNumber = 0; 00207 }
bool BLCMDcosmicraybeam::generateReferenceParticle | ( | G4Event * | event | ) | [virtual] |
bool BLCMDcosmicraybeam::nextBeamEvent | ( | G4Event * | event | ) | [virtual] |
nextBeamEvent() generates the next beam event.
Implements BLBeam.
References beamHeight, beamLength, beamWidth, beamZ, cosmicRayMuonAngle(), cosmicRayMuonMomentum(), evNumber, hits, muon, muonGun, BLBeam::nEvents, radius, BLBeam::setRandomSeedToGenerate(), and BLBeam::setRandomSeedToTrack().
00215 { 00216 if(++evNumber > nEvents) return false; 00217 00218 setRandomSeedToGenerate(evNumber); 00219 00220 G4double mass = muon->GetPDGMass(); 00221 G4ThreeVector position; 00222 G4ThreeVector direction; 00223 G4double time = 0.0; 00224 G4double momentum = 0.0; 00225 00226 // work in local coordinates (relative to the beam box) 00227 G4double x = beamWidth*G4UniformRand() - beamWidth/2.0; 00228 G4double y = beamHeight*G4UniformRand() - beamHeight/2.0; 00229 G4double z = beamLength*G4UniformRand() - beamLength/2.0; 00230 momentum = cosmicRayMuonMomentum(); 00231 double theta = cosmicRayMuonAngle(); 00232 double phi = 2.0*pi*G4UniformRand(); 00233 direction[0] = momentum*sin(theta)*cos(phi); 00234 direction[1] = momentum*sin(theta)*sin(phi); 00235 direction[2] = momentum*cos(theta); 00236 00237 // propagate to z=0 (center of the beam box) 00238 x -= direction[0]/direction[2]*z; 00239 y -= direction[1]/direction[2]*z; 00240 z = 0.0; 00241 00242 // count midplane hits in the beam box (for normalization in summary()) 00243 if(fabs(x) < beamWidth/2.0 && fabs(y) < beamHeight/2.0) 00244 ++hits; 00245 00246 // project backwards (negative z) onto the celestial sphere 00247 if(radius > 0.0) { 00248 G4double xp = direction[0]/direction[2]; 00249 G4double yp = direction[1]/direction[2]; 00250 G4double a = 1.0 + xp*xp + yp*yp; 00251 G4double b = 2.0 * (x*xp + y*yp); 00252 G4double c = x*x + y*y - radius*radius; 00253 z = (-b - sqrt(b*b-4.0*a*c)) / (2.0 * a); 00254 position[0] = x + xp*z; 00255 position[1] = y + yp*z; 00256 position[2] = z + beamZ; 00257 } else { 00258 position[0] = x; 00259 position[1] = y; 00260 position[2] = beamZ; 00261 } 00262 00263 G4double ke = sqrt(momentum*momentum + mass*mass) - mass; 00264 muonGun->SetParticleTime(time); 00265 muonGun->SetParticlePosition(position); 00266 muonGun->SetParticleEnergy(ke); 00267 muonGun->SetParticleMomentumDirection(direction); 00268 muonGun->GeneratePrimaryVertex(event); 00269 00270 setRandomSeedToTrack(evNumber); 00271 return true; 00272 }
void BLCMDcosmicraybeam::summary | ( | ) | [virtual] |
summary() will print a summary.
Reimplemented from BLBeam.
References beamHeight, beamWidth, hits, hitsPerM2PerSecPerSterrad, and sterradians.
00275 { 00276 G4double area = beamWidth*beamHeight/meter2; 00277 G4double hitsPerSec = hitsPerM2PerSecPerSterrad * area * sterradians; 00278 printf("CosmicRayBeam: %ld hits in midplane, area %.3f meter^2 " 00279 " %.3f sterradians\n", 00280 hits,area,sterradians); 00281 if(hitsPerSec > 0.0) 00282 printf(" %.1f hits/sec, estimated exposure" 00283 " %.1f sec\n",hitsPerSec,hits/hitsPerSec); 00284 }
double BLCMDcosmicraybeam::cosmicRayMuonMomentum | ( | ) |
cosmicRayMuonMomentum() returns a random momentum value distributed like the muons from cosmic rays. Average momentum is 3.0*GeV/c, cutoff is 120*GeV/c. Return value is in geant4 units (MeV). Data from Kremer et al, Phys. Rev. Lett., Vol 83 no 21, p4241 (1999)
References BLAssert, hitsPerM2PerSecPerSterrad, and init().
Referenced by nextBeamEvent().
00287 { 00288 // Data from Kremer et al, Phys. Rev. Lett., Vol 83 no 21, p4241 (1999). 00289 // values are lower bin edge, bin average, mu+ rate, mu- rate 00290 // (laid out this silly way so verification with the paper is easy) 00291 // NOTE: units are GeV/c, and counts/(GeV/c m^2 sr s) 00292 static double vals[] = { 00293 0.0, 0.0, 0.0, 0.0, 00294 0.2, 0.25, 14.0, 11.0, 00295 0.3, 0.35, 16.8, 13.6, 00296 0.4, 0.47, 17.2, 14.4, 00297 0.55, 0.62, 16.6, 13.5, 00298 0.70, 0.78, 15.6, 13.3, 00299 0.85, 0.92, 14.8, 12.1, 00300 1.0, 1.1, 13.0, 11.0, 00301 1.2, 1.3, 12.0, 10.1, 00302 1.4, 1.5, 10.2, 8.7, 00303 1.6, 1.84, 9.1, 7.3, 00304 2.1, 2.49, 6.6, 5.2, 00305 2.94, 3.49, 4.12, 3.38, 00306 4.12, 4.78, 2.53, 1.98, 00307 5.5, 6.21, 1.61, 1.25, 00308 7.0, 8.37, 0.90, 0.69, 00309 10.0, 12.42, 0.389, 0.309, 00310 15.5, 18.85, 0.138, 0.108, 00311 23.0, 26.68, 0.063, 0.046, 00312 31.1, 36.69, 0.028, 0.019, 00313 43.6, 51.47, 0.0099, 0.0071, 00314 61.1, 72.08, 0.0036, 0.0030, 00315 85.6, 100.96, 0.0014, 0.0012, 00316 120.0, 120.0, 0.0, 0.0}; // cutoff at 120 GeV/c 00317 const int nvals = sizeof(vals)/sizeof(vals[0]); 00318 const int nbins = nvals/4 - 1; 00319 const int npdf=256; 00320 static double pdf[npdf]; 00321 static double pmax = vals[4*nbins]; 00322 static bool init=true; 00323 00324 if(init) { 00325 // RandGeneral needs equal-sized bins for pdf[] 00326 // it returns a value in the range [0,1) 00327 hitsPerM2PerSecPerSterrad = 0.0; 00328 for(int i=0,ibin=0; i<npdf; ++i) { 00329 double p = (i+0.5)*pmax/npdf; 00330 while(p >= vals[4*ibin+5]) ++ibin; 00331 BLAssert(ibin <= nbins); 00332 double f = (p - vals[4*ibin+1]) / 00333 (vals[4*ibin+5]-vals[4*ibin+1]); 00334 BLAssert(0.0 <= f && f <= 1.0); 00335 pdf[i] = (1.0-f)*(vals[4*ibin+2]+vals[4*ibin+3]) + 00336 f*(vals[4*ibin+6]+vals[4*ibin+7]); 00337 hitsPerM2PerSecPerSterrad += pdf[i] * pmax/npdf; 00338 } 00339 init = false; 00340 } 00341 00342 CLHEP::RandGeneral generator(pdf,npdf); // BUG in RandGeneral - cannot use new 00343 return generator.shoot() * pmax * GeV; 00344 }
double BLCMDcosmicraybeam::cosmicRayMuonAngle | ( | ) |
cosmicRayMuonAngle() returns a random angle distributed like the polar angle of cosmic ray muons. The return value is the polar angle from vertical (radians). It is cut off at 70 degrees. Note this is the distribution for muons of ~3 GeV/c, which is the average momentum. In fact, lower energy muons have a steeper distribution and higher ones have a flatter distribution. But this is a reasonable approximation. Particle Data Group, Review of Particle Properties, 2002. Section 23.3.1.
References init(), and sterradians.
Referenced by nextBeamEvent().
00347 { 00348 const int npdf=128; 00349 static double pdf[npdf]; 00350 const double thetamax = 70.0*deg; 00351 static bool init = true; 00352 00353 if(init) { 00354 // RandGeneral needs equal-sized bins for pdf[] 00355 // it returns a value in the range [0,1) 00356 sterradians = 0.0; 00357 G4double dtheta = thetamax / npdf; 00358 for(int i=0; i<npdf; ++i) { 00359 // Particle Data Group, Review of Particle Properties, 00360 // 2002. Section 23.3.1. 00361 double c = cos(dtheta*i); 00362 pdf[i] = c*c; 00363 sterradians += 2.0*pi*c*c*sin(dtheta*i)*dtheta; 00364 } 00365 init = false; 00366 } 00367 00368 CLHEP::RandGeneral generator(pdf,npdf); // BUG in RandGeneral - cannot use new 00369 return generator.shoot() * thetamax; 00370 }
G4double BLCMDcosmicraybeam::meanMomentum [private] |
Referenced by BLCMDcosmicraybeam().
G4double BLCMDcosmicraybeam::beamZ [private] |
Referenced by BLCMDcosmicraybeam(), defineNamedArgs(), nextBeamEvent(), and printBeam().
G4double BLCMDcosmicraybeam::beamWidth [private] |
Referenced by BLCMDcosmicraybeam(), defineNamedArgs(), nextBeamEvent(), printBeam(), and summary().
G4double BLCMDcosmicraybeam::beamHeight [private] |
Referenced by BLCMDcosmicraybeam(), defineNamedArgs(), nextBeamEvent(), printBeam(), and summary().
G4double BLCMDcosmicraybeam::beamLength [private] |
Referenced by BLCMDcosmicraybeam(), defineNamedArgs(), nextBeamEvent(), and printBeam().
G4ParticleGun* BLCMDcosmicraybeam::muonGun [private] |
Referenced by BLCMDcosmicraybeam(), init(), and nextBeamEvent().
G4ParticleDefinition* BLCMDcosmicraybeam::muon [private] |
Referenced by BLCMDcosmicraybeam(), init(), and nextBeamEvent().
G4double BLCMDcosmicraybeam::radius [private] |
Referenced by BLCMDcosmicraybeam(), command(), defineNamedArgs(), nextBeamEvent(), and printBeam().
G4long BLCMDcosmicraybeam::hits [private] |
Referenced by BLCMDcosmicraybeam(), nextBeamEvent(), and summary().
G4double BLCMDcosmicraybeam::sterradians [private] |
Referenced by BLCMDcosmicraybeam(), cosmicRayMuonAngle(), and summary().
G4double BLCMDcosmicraybeam::hitsPerM2PerSecPerSterrad [private] |
Referenced by BLCMDcosmicraybeam(), cosmicRayMuonMomentum(), and summary().
G4String BLCMDcosmicraybeam::particle [private] |
Referenced by BLCMDcosmicraybeam(), init(), and printBeam().
G4int BLCMDcosmicraybeam::evNumber [private] |
Referenced by BLCMDcosmicraybeam(), init(), and nextBeamEvent().