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