Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-14 08:27:29

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /// \file GB04BOptnBremSplitting.cc
0027 /// \brief Implementation of the GB04BOptnBremSplitting class
0028 
0029 #include "GB04BOptnBremSplitting.hh"
0030 
0031 #include "G4BiasingProcessInterface.hh"
0032 #include "G4ParticleChangeForLoss.hh"
0033 
0034 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0035 
0036 GB04BOptnBremSplitting::GB04BOptnBremSplitting(G4String name)
0037   : G4VBiasingOperation(name), fSplittingFactor(1), fParticleChange()
0038 {}
0039 
0040 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0041 
0042 GB04BOptnBremSplitting::~GB04BOptnBremSplitting() = default;
0043 
0044 G4VParticleChange*
0045 GB04BOptnBremSplitting::ApplyFinalStateBiasing(const G4BiasingProcessInterface* callingProcess,
0046                                                const G4Track* track, const G4Step* step, G4bool&)
0047 {
0048   // -- Collect brem. process (wrapped process) final state:
0049   G4VParticleChange* processFinalState =
0050     callingProcess->GetWrappedProcess()->PostStepDoIt(*track, *step);
0051 
0052   // -- if no splitting requested, let the brem. process to return directly its
0053   // -- generated final state:
0054   if (fSplittingFactor == 1) return processFinalState;
0055 
0056   // -- a special case here: the brem. process corrects for cross-section change
0057   // -- over the step due to energy loss by sometimes "abandoning" the interaction,
0058   // -- returning an unchanged incoming electron/positron.
0059   // -- We respect this correction, and if no secondary is produced, its means this
0060   // -- case is happening:
0061   if (processFinalState->GetNumberOfSecondaries() == 0) return processFinalState;
0062 
0063   // -- Now start the biasing:
0064   // --   - the electron state will be taken as the first one produced by the brem.
0065   // --     process, hence the one stored in above processFinalState particle change.
0066   // --     This state will be stored in our fParticleChange object.
0067   // --   - the photon accompagnying the electron will be stored also this way.
0068   // --   - we will then do fSplittingFactor - 1 call to the brem. process to collect
0069   // --     fSplittingFactor - 1 additionnal gammas. All these will be stored in our
0070   // --     fParticleChange object.
0071 
0072   // -- We called the brem. process above. Its concrete particle change is indeed
0073   // -- a "G4ParticleChangeForLoss" object. We cast this particle change to access
0074   // -- methods of the concrete G4ParticleChangeForLoss type:
0075   auto actualParticleChange = (G4ParticleChangeForLoss*)processFinalState;
0076 
0077   fParticleChange.Initialize(*track);
0078 
0079   // -- Store electron final state:
0080   fParticleChange.ProposeTrackStatus(actualParticleChange->GetTrackStatus());
0081   fParticleChange.ProposeEnergy(actualParticleChange->GetProposedKineticEnergy());
0082   fParticleChange.ProposeMomentumDirection(actualParticleChange->GetProposedMomentumDirection());
0083 
0084   // -- Now deal with the gamma's:
0085   // -- their common weight:
0086   G4double gammaWeight = track->GetWeight() / fSplittingFactor;
0087 
0088   // -- inform we will have fSplittingFactor gamma's:
0089   fParticleChange.SetNumberOfSecondaries(fSplittingFactor);
0090 
0091   // -- inform we take care of secondaries weight (otherwise these
0092   // -- secondaries are by default given the primary weight).
0093   fParticleChange.SetSecondaryWeightByProcess(true);
0094 
0095   // -- Store first gamma:
0096   G4Track* gammaTrack = actualParticleChange->GetSecondary(0);
0097   gammaTrack->SetWeight(gammaWeight);
0098   fParticleChange.AddSecondary(gammaTrack);
0099   // -- and clean-up the brem. process particle change:
0100   actualParticleChange->Clear();
0101 
0102   // -- now start the fSplittingFactor-1 calls to the brem. process to store each
0103   // -- related gamma:
0104   G4int nCalls = 1;
0105   while (nCalls < fSplittingFactor) {
0106     // ( note: we don't need to cast to actual type here, as methods for accessing
0107     //   secondary particles are from base class G4VParticleChange )
0108     processFinalState = callingProcess->GetWrappedProcess()->PostStepDoIt(*track, *step);
0109     if (processFinalState->GetNumberOfSecondaries() == 1) {
0110       gammaTrack = processFinalState->GetSecondary(0);
0111       gammaTrack->SetWeight(gammaWeight);
0112       fParticleChange.AddSecondary(gammaTrack);
0113       nCalls++;
0114     }
0115     // -- very rare special case: we ignore for now.
0116     else if (processFinalState->GetNumberOfSecondaries() > 1) {
0117       for (G4int i = 0; i < processFinalState->GetNumberOfSecondaries(); i++)
0118         delete processFinalState->GetSecondary(i);
0119     }
0120     processFinalState->Clear();
0121   }
0122 
0123   // -- we are done:
0124   return &fParticleChange;
0125 }
0126 
0127 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......