// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // // $Id: G4PrimaryTransformer.cc,v 1.27 2006/06/29 18:09:58 gunter Exp $ // GEANT4 tag $Name: geant4-09-03 $ // #include "G4PrimaryTransformer.hh" #include "G4Event.hh" #include "G4PrimaryVertex.hh" #include "G4ParticleDefinition.hh" #include "G4DynamicParticle.hh" #include "G4Track.hh" #include "G4ThreeVector.hh" #include "G4DecayProducts.hh" #include "G4UnitsTable.hh" #include "G4ios.hh" #include "Randomize.hh" G4PrimaryTransformer::G4PrimaryTransformer() :verboseLevel(0),trackID(0),unknown(0),unknownParticleDefined(false) { particleTable = G4ParticleTable::GetParticleTable(); CheckUnknown(); } G4PrimaryTransformer::~G4PrimaryTransformer() {;} void G4PrimaryTransformer::CheckUnknown() { unknown = particleTable->FindParticle("unknown"); if(unknown) { unknownParticleDefined = true; } else { unknownParticleDefined = false; } } G4TrackVector* G4PrimaryTransformer::GimmePrimaries(G4Event* anEvent,G4int trackIDCounter) { trackID = trackIDCounter; //TV.clearAndDestroy(); for( size_t ii=0; iiGetNumberOfPrimaryVertex(); if(n_vertex==0) return 0; for( G4int i=0; iGetPrimaryVertex(i) ); } return &TV; } void G4PrimaryTransformer::GenerateTracks(G4PrimaryVertex* primaryVertex) { G4double X0 = primaryVertex->GetX0(); G4double Y0 = primaryVertex->GetY0(); G4double Z0 = primaryVertex->GetZ0(); G4double T0 = primaryVertex->GetT0(); G4double WV = primaryVertex->GetWeight(); #ifdef G4VERBOSE if(verboseLevel>1) { G4cout << "G4PrimaryTransformer::PrimaryVertex (" << X0 / mm << "(mm)," << Y0 / mm << "(mm)," << Z0 / mm << "(mm)," << T0 / nanosecond << "(nsec))" << G4endl; } #endif G4PrimaryParticle* primaryParticle = primaryVertex->GetPrimary(); while( primaryParticle != 0 ) { GenerateSingleTrack( primaryParticle, X0, Y0, Z0, T0, WV ); primaryParticle = primaryParticle->GetNext(); } } void G4PrimaryTransformer::GenerateSingleTrack (G4PrimaryParticle* primaryParticle, G4double x0,G4double y0,G4double z0,G4double t0,G4double wv) { static G4ParticleDefinition* optPhoton = 0; static G4int nWarn = 0; if(!optPhoton) optPhoton = particleTable->FindParticle("opticalphoton"); G4ParticleDefinition* partDef = GetDefinition(primaryParticle); if(!IsGoodForTrack(partDef)) // The particle cannot be converted to G4Track, check daughters { #ifdef G4VERBOSE if(verboseLevel>2) { G4cout << "Primary particle (PDGcode " << primaryParticle->GetPDGcode() << ") --- Ignored" << G4endl; } #endif G4PrimaryParticle* daughter = primaryParticle->GetDaughter(); while(daughter) { GenerateSingleTrack(daughter,x0,y0,z0,t0,wv); daughter = daughter->GetNext(); } } // The particle is defined in GEANT4 else { // Create G4DynamicParticle object #ifdef G4VERBOSE if(verboseLevel>1) { G4cout << "Primary particle (" << partDef->GetParticleName() << ") --- Transfered with momentum " << primaryParticle->GetMomentum() << G4endl; } #endif G4DynamicParticle* DP = new G4DynamicParticle(partDef,primaryParticle->GetMomentum()); if(partDef==optPhoton && primaryParticle->GetPolarization().mag2()==0.) { if(nWarn<10) { G4Exception("G4PrimaryTransformer::GenerateSingleTrack","ZeroPolarization",JustWarning, "Polarization of the optical photon is null. Random polarization is assumed."); G4cerr << "This warning message is issued up to 10 times." << G4endl; nWarn++; } G4double angle = G4UniformRand() * 360.0*deg; G4ThreeVector normal (1., 0., 0.); G4ThreeVector kphoton = DP->GetMomentumDirection(); G4ThreeVector product = normal.cross(kphoton); G4double modul2 = product*product; G4ThreeVector e_perpend (0., 0., 1.); if (modul2 > 0.) e_perpend = (1./std::sqrt(modul2))*product; G4ThreeVector e_paralle = e_perpend.cross(kphoton); G4ThreeVector polar = std::cos(angle)*e_paralle + std::sin(angle)*e_perpend; DP->SetPolarization(polar.x(),polar.y(),polar.z()); } else { DP->SetPolarization(primaryParticle->GetPolX(), primaryParticle->GetPolY(), primaryParticle->GetPolZ()); } if(primaryParticle->GetProperTime()>0.0) { DP->SetPreAssignedDecayProperTime(primaryParticle->GetProperTime()); } // Set Charge if it is specified if (primaryParticle->GetCharge()SetCharge(primaryParticle->GetCharge()); } // Set Mass if it is specified G4double pmas = primaryParticle->GetMass(); if(pmas>=0.) { DP->SetMass(pmas); } // Set decay products to the DynamicParticle SetDecayProducts( primaryParticle, DP ); // Set primary particle DP->SetPrimaryParticle(primaryParticle); // Set PDG code if it is different from G4ParticleDefinition if(partDef->GetPDGEncoding()==0 && primaryParticle->GetPDGcode()!=0) { DP->SetPDGcode(primaryParticle->GetPDGcode()); } // Check the particle is properly constructed if(!CheckDynamicParticle(DP)) { delete DP; return; } // Create G4Track object G4Track* track = new G4Track(DP,t0,G4ThreeVector(x0,y0,z0)); // Set trackID and let primary particle know it trackID++; track->SetTrackID(trackID); primaryParticle->SetTrackID(trackID); // Set parentID to 0 as a primary particle track->SetParentID(0); // Set weight ( vertex weight * particle weight ) track->SetWeight(wv*(primaryParticle->GetWeight())); // Store it to G4TrackVector TV.push_back( track ); } } void G4PrimaryTransformer::SetDecayProducts (G4PrimaryParticle* mother, G4DynamicParticle* motherDP) { G4PrimaryParticle* daughter = mother->GetDaughter(); if(!daughter) return; G4DecayProducts* decayProducts = (G4DecayProducts*)(motherDP->GetPreAssignedDecayProducts() ); if(!decayProducts) { decayProducts = new G4DecayProducts(*motherDP); motherDP->SetPreAssignedDecayProducts(decayProducts); } while(daughter) { G4ParticleDefinition* partDef = GetDefinition(daughter); if(!IsGoodForTrack(partDef)) { #ifdef G4VERBOSE if(verboseLevel>2) { G4cout << " >> Decay product (PDGcode " << daughter->GetPDGcode() << ") --- Ignored" << G4endl; } #endif SetDecayProducts(daughter,motherDP); } else { #ifdef G4VERBOSE if(verboseLevel>1) { G4cout << " >> Decay product (" << partDef->GetParticleName() << ") --- Attached with momentum " << daughter->GetMomentum() << G4endl; } #endif G4DynamicParticle*DP = new G4DynamicParticle(partDef,daughter->GetMomentum()); DP->SetPrimaryParticle(daughter); // Decay proper time for daughter if(daughter->GetProperTime()>0.0) { DP->SetPreAssignedDecayProperTime(daughter->GetProperTime()); } // Set Charge is specified if (daughter->GetCharge()SetCharge(daughter->GetCharge()); } G4double pmas = daughter->GetMass(); if(pmas>=0.) { DP->SetMass(pmas); } decayProducts->PushProducts(DP); SetDecayProducts(daughter,DP); // Check the particle is properly constructed if(!CheckDynamicParticle(DP)) { delete DP; return; } } daughter = daughter->GetNext(); } } void G4PrimaryTransformer::SetUnknnownParticleDefined(G4bool vl) { unknownParticleDefined = vl; if(unknownParticleDefined && !unknown) { G4cerr << "unknownParticleDefined cannot be set true because G4UnknownParticle is not defined in the physics list." << G4endl << "Command ignored." << G4endl; unknownParticleDefined = false; } } G4bool G4PrimaryTransformer::CheckDynamicParticle(G4DynamicParticle*DP) { if(IsGoodForTrack(DP->GetDefinition())) return true; G4DecayProducts* decayProducts = (G4DecayProducts*)(DP->GetPreAssignedDecayProducts()); if(decayProducts && decayProducts->entries()>0) return true; G4cerr << G4endl << "G4PrimaryTransformer: a shortlived primary particle is found" << G4endl << " without any valid decay table nor pre-assigned decay mode." << G4endl; G4Exception("G4PrimaryTransformer","InvalidPrimary",JustWarning, "This primary particle will be ignored."); return false; } G4ParticleDefinition* G4PrimaryTransformer::GetDefinition(G4PrimaryParticle*pp) { G4ParticleDefinition* partDef = pp->GetG4code(); if(!partDef) partDef = particleTable->FindParticle(pp->GetPDGcode()); if(unknownParticleDefined && ((!partDef)||partDef->IsShortLived())) partDef = unknown; return partDef; } G4bool G4PrimaryTransformer::IsGoodForTrack(G4ParticleDefinition* pd) { if(!pd) { return false; } else if(!(pd->IsShortLived())) { return true; } // Following two lines should be removed if the user does not want to make shortlived // primary particle with proper decay table to be converted into a track. else if(pd->GetDecayTable()) { return true; } return false; }