Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/advanced/ChargeExchangeMC/src/CexmcChargeExchangeReconstructor.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 /*
 27  * ============================================================================
 28  *
 29  *       Filename:  CexmcChargeExchangeReconstructor.cc
 30  *
 31  *    Description:  charge exchange reconstructor
 32  *
 33  *        Version:  1.0
 34  *        Created:  02.12.2009 15:17:13
 35  *       Revision:  none
 36  *       Compiler:  gcc
 37  *
 38  *         Author:  Alexey Radkov (), 
 39  *        Company:  PNPI
 40  *
 41  * ============================================================================
 42  */
 43 
 44 #include <cmath>
 45 #include <G4ThreeVector.hh>
 46 #include <G4LorentzVector.hh>
 47 #include "CexmcChargeExchangeReconstructor.hh"
 48 #include "CexmcChargeExchangeReconstructorMessenger.hh"
 49 #include "CexmcEnergyDepositStore.hh"
 50 #include "CexmcPrimaryGeneratorAction.hh"
 51 #include "CexmcParticleGun.hh"
 52 #include "CexmcProductionModel.hh"
 53 #include "CexmcRunManager.hh"
 54 #include "CexmcException.hh"
 55 
 56 
 57 CexmcChargeExchangeReconstructor::CexmcChargeExchangeReconstructor(
 58                             const CexmcProductionModel *  productionModel ) :
 59     outputParticleMass( 0 ), nucleusOutputParticleMass( 0 ),
 60     useTableMass( false ), useMassCut( false ), massCutOPCenter( 0 ),
 61     massCutNOPCenter( 0 ), massCutOPWidth( 0 ), massCutNOPWidth( 0 ),
 62     massCutEllipseAngle( 0 ), useAbsorbedEnergyCut( false ),
 63     absorbedEnergyCutCLCenter( 0 ), absorbedEnergyCutCRCenter( 0 ),
 64     absorbedEnergyCutCLWidth( 0 ), absorbedEnergyCutCRWidth( 0 ),
 65     absorbedEnergyCutEllipseAngle( 0 ), expectedMomentumAmp( -1 ),
 66     edCollectionAlgorithm( CexmcCollectEDInAllCrystals ),
 67     hasMassCutTriggered( false ), hasAbsorbedEnergyCutTriggered( false ),
 68     beamParticleIsInitialized( false ), particleGun( NULL ), messenger( NULL )
 69 {
 70     if ( ! productionModel )
 71         throw CexmcException( CexmcWeirdException );
 72 
 73     productionModelData.incidentParticle =
 74                                     productionModel->GetIncidentParticle();
 75 
 76     CexmcRunManager *  runManager( static_cast< CexmcRunManager * >(
 77                                             G4RunManager::GetRunManager() ) );
 78     const CexmcPrimaryGeneratorAction *  primaryGeneratorAction(
 79                         static_cast< const CexmcPrimaryGeneratorAction * >(
 80                                 runManager->GetUserPrimaryGeneratorAction() ) );
 81     CexmcPrimaryGeneratorAction *  thePrimaryGeneratorAction(
 82                         const_cast< CexmcPrimaryGeneratorAction * >(
 83                                 primaryGeneratorAction ) );
 84     particleGun = thePrimaryGeneratorAction->GetParticleGun();
 85 
 86     productionModelData.nucleusParticle =
 87                                     productionModel->GetNucleusParticle();
 88     productionModelData.outputParticle =
 89                                     productionModel->GetOutputParticle();
 90     productionModelData.nucleusOutputParticle =
 91                                     productionModel->GetNucleusOutputParticle();
 92 
 93     messenger = new CexmcChargeExchangeReconstructorMessenger( this );
 94 }
 95 
 96 
 97 CexmcChargeExchangeReconstructor::~CexmcChargeExchangeReconstructor()
 98 {
 99     delete messenger;
100 }
101 
102 
103 void  CexmcChargeExchangeReconstructor::SetupBeamParticle( void )
104 {
105     if ( *productionModelData.incidentParticle !=
106                                         *particleGun->GetParticleDefinition() )
107         throw CexmcException( CexmcBeamAndIncidentParticlesMismatch );
108 
109     beamParticleIsInitialized = true;
110 }
111 
112 
113 void  CexmcChargeExchangeReconstructor::Reconstruct(
114                                     const CexmcEnergyDepositStore *  edStore )
115 {
116     if ( ! beamParticleIsInitialized )
117     {
118         if ( *productionModelData.incidentParticle !=
119                                         *particleGun->GetParticleDefinition() )
120             throw CexmcException( CexmcBeamAndIncidentParticlesMismatch );
121 
122         beamParticleIsInitialized = true;
123     }
124 
125     if ( edCollectionAlgorithm == CexmcCollectEDInAdjacentCrystals )
126         collectEDInAdjacentCrystals = true;
127 
128     ReconstructEntryPoints( edStore );
129     if ( hasBasicTrigger )
130         ReconstructTargetPoint();
131     if ( hasBasicTrigger )
132         ReconstructAngle();
133 
134     G4ThreeVector  epLeft( calorimeterEPLeftWorldPosition -
135                            targetEPWorldPosition );
136     G4ThreeVector  epRight( calorimeterEPRightWorldPosition -
137                             targetEPWorldPosition );
138 
139     G4double  cosTheAngle( std::cos( theAngle ) );
140     G4double  calorimeterEDLeft( edStore->calorimeterEDLeft );
141     G4double  calorimeterEDRight( edStore->calorimeterEDRight );
142 
143     if ( edCollectionAlgorithm == CexmcCollectEDInAdjacentCrystals )
144     {
145         calorimeterEDLeft = calorimeterEDLeftAdjacent;
146         calorimeterEDRight = calorimeterEDRightAdjacent;
147     }
148 
149     //G4double  cosOutputParticleLAB(
150         //( calorimeterEDLeft * cosAngleLeft +
151           //calorimeterEDRight * cosAngleRight ) /
152           //std::sqrt( calorimeterEDLeft * calorimeterEDLeft +
153                      //calorimeterEDRight * calorimeterEDRight +
154                      //calorimeterEDLeft * calorimeterEDRight * cosTheAngle ) );
155 
156     outputParticleMass = std::sqrt( 2 * calorimeterEDLeft *
157                                     calorimeterEDRight * ( 1 - cosTheAngle ) );
158 
159     G4ThreeVector    opdpLeftMomentum( epLeft );
160     opdpLeftMomentum.setMag( calorimeterEDLeft );
161     G4ThreeVector    opdpRightMomentum( epRight );
162     opdpRightMomentum.setMag( calorimeterEDRight );
163     G4ThreeVector    opMomentum( opdpLeftMomentum + opdpRightMomentum );
164 
165     /* opMass will be used only in calculation of output particle's total
166      * energy, in other places outputParticleMass should be used instead */
167     G4double         opMass( useTableMass ?
168                              productionModelData.outputParticle->GetPDGMass() :
169                              outputParticleMass );
170     /* the formula below is equivalent to
171      * calorimeterEDLeft + calorimeterEDRight if opMass = outputParticleMass */
172     G4double         opEnergy( std::sqrt( opMomentum.mag2() +
173                                           opMass * opMass ) );
174     productionModelData.outputParticleLAB = G4LorentzVector( opMomentum,
175                                                              opEnergy );
176 
177     G4ThreeVector  incidentParticleMomentum( particleGun->GetOrigDirection() );
178     G4double       incidentParticleMomentumAmp( expectedMomentumAmp > 0 ?
179                     expectedMomentumAmp : particleGun->GetOrigMomentumAmp() );
180     incidentParticleMomentum *= incidentParticleMomentumAmp;
181 
182     G4double       incidentParticlePDGMass(
183                         productionModelData.incidentParticle->GetPDGMass() );
184     G4double       incidentParticlePDGMass2( incidentParticlePDGMass *
185                                              incidentParticlePDGMass );
186     G4double       incidentParticleEnergy(
187         std::sqrt( incidentParticleMomentumAmp * incidentParticleMomentumAmp +
188                    incidentParticlePDGMass2 ) );
189 
190     productionModelData.incidentParticleLAB = G4LorentzVector(
191                         incidentParticleMomentum, incidentParticleEnergy );
192     G4double       nucleusParticlePDGMass(
193                         productionModelData.nucleusParticle->GetPDGMass() );
194     productionModelData.nucleusParticleLAB = G4LorentzVector(
195                         G4ThreeVector( 0, 0, 0 ), nucleusParticlePDGMass );
196 
197     G4LorentzVector  lVecSum( productionModelData.incidentParticleLAB +
198                         productionModelData.nucleusParticleLAB );
199     G4ThreeVector    boostVec( lVecSum.boostVector() );
200 
201     productionModelData.nucleusOutputParticleLAB =
202             lVecSum - productionModelData.outputParticleLAB;
203 
204     productionModelData.incidentParticleSCM =
205             productionModelData.incidentParticleLAB;
206     productionModelData.nucleusParticleSCM =
207             productionModelData.nucleusParticleLAB;
208     productionModelData.outputParticleSCM =
209             productionModelData.outputParticleLAB;
210     productionModelData.nucleusOutputParticleSCM =
211             productionModelData.nucleusOutputParticleLAB;
212 
213     productionModelData.incidentParticleSCM.boost( -boostVec );
214     productionModelData.nucleusParticleSCM.boost( -boostVec );
215     productionModelData.outputParticleSCM.boost( -boostVec );
216     productionModelData.nucleusOutputParticleSCM.boost( -boostVec );
217 
218     G4ThreeVector  nopMomentum( incidentParticleMomentum - opMomentum );
219     G4double       nopEnergy( incidentParticleEnergy + nucleusParticlePDGMass -
220                               opEnergy );
221     nucleusOutputParticleMass = std::sqrt( nopEnergy * nopEnergy -
222                                            nopMomentum.mag2() );
223 
224     if ( useMassCut )
225     {
226         G4double  cosMassCutEllipseAngle( std::cos( massCutEllipseAngle ) );
227         G4double  sinMassCutEllipseAngle( std::sin( massCutEllipseAngle ) );
228 
229         if ( massCutOPWidth <= 0. || massCutNOPWidth <= 0. )
230         {
231             hasMassCutTriggered = false;
232         }
233         else
234         {
235             G4double  massCutOPWidth2( massCutOPWidth * massCutOPWidth );
236             G4double  massCutNOPWidth2( massCutNOPWidth * massCutNOPWidth );
237 
238             hasMassCutTriggered =
239                 std::pow( ( outputParticleMass - massCutOPCenter ) *
240                               cosMassCutEllipseAngle +
241                           ( nucleusOutputParticleMass - massCutNOPCenter ) *
242                               sinMassCutEllipseAngle, 2 ) / massCutOPWidth2 +
243                 std::pow( - ( outputParticleMass - massCutOPCenter ) *
244                               sinMassCutEllipseAngle +
245                           ( nucleusOutputParticleMass - massCutNOPCenter ) *
246                               cosMassCutEllipseAngle, 2 ) / massCutNOPWidth2 <
247                 1;
248         }
249     }
250 
251     if ( useAbsorbedEnergyCut )
252     {
253         G4double  cosAbsorbedEnergyCutEllipseAngle(
254                                 std::cos( absorbedEnergyCutEllipseAngle ) );
255         G4double  sinAbsorbedEnergyCutEllipseAngle(
256                                 std::sin( absorbedEnergyCutEllipseAngle ) );
257 
258         if ( absorbedEnergyCutCLWidth <= 0. || absorbedEnergyCutCRWidth <= 0. )
259         {
260             hasAbsorbedEnergyCutTriggered = false;
261         }
262         else
263         {
264             G4double  absorbedEnergyCutCLWidth2(
265                         absorbedEnergyCutCLWidth * absorbedEnergyCutCLWidth );
266             G4double  absorbedEnergyCutCRWidth2(
267                         absorbedEnergyCutCRWidth * absorbedEnergyCutCRWidth );
268 
269             hasAbsorbedEnergyCutTriggered =
270                 std::pow( ( calorimeterEDLeft - absorbedEnergyCutCLCenter ) *
271                               cosAbsorbedEnergyCutEllipseAngle +
272                           ( calorimeterEDRight - absorbedEnergyCutCRCenter ) *
273                               sinAbsorbedEnergyCutEllipseAngle, 2 ) /
274                 absorbedEnergyCutCLWidth2 +
275                 std::pow( - ( calorimeterEDLeft - absorbedEnergyCutCLCenter ) *
276                               sinAbsorbedEnergyCutEllipseAngle +
277                           ( calorimeterEDRight - absorbedEnergyCutCRCenter ) *
278                               cosAbsorbedEnergyCutEllipseAngle, 2 ) /
279                 absorbedEnergyCutCRWidth2 <
280                 1;
281         }
282     }
283 
284     hasBasicTrigger = true;
285 }
286 
287 
288 G4bool  CexmcChargeExchangeReconstructor::HasFullTrigger( void ) const
289 {
290     if ( ! hasBasicTrigger )
291         return false;
292     if ( useMassCut && ! hasMassCutTriggered )
293         return false;
294     if ( useAbsorbedEnergyCut && ! hasAbsorbedEnergyCutTriggered )
295         return false;
296 
297     return true;
298 }
299 
300 
301 void  CexmcChargeExchangeReconstructor::SetExpectedMomentumAmpDiff(
302                                                             G4double  value )
303 {
304     expectedMomentumAmp = particleGun->GetOrigMomentumAmp() + value;
305 }
306 
307