ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CexmcEventAction.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CexmcEventAction.cc
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: CexmcEventAction.cc
30  *
31  * Description: event action
32  *
33  * Version: 1.0
34  * Created: 27.10.2009 22:48:08
35  * Revision: none
36  * Compiler: gcc
37  *
38  * Author: Alexey Radkov (),
39  * Company: PNPI
40  *
41  * ============================================================================
42  */
43 
44 #include <cmath>
45 #ifdef CEXMC_USE_PERSISTENCY
46 #include <boost/archive/binary_oarchive.hpp>
47 #endif
48 #include <G4DigiManager.hh>
49 #include <G4Event.hh>
50 #include <G4Circle.hh>
51 #include <G4VisAttributes.hh>
52 #include <G4VisManager.hh>
53 #include <G4VTrajectory.hh>
54 #include <G4TrajectoryContainer.hh>
55 #include <G4Colour.hh>
56 #include <G4SystemOfUnits.hh>
57 #include "CexmcEventAction.hh"
59 #include "CexmcEventInfo.hh"
60 #include "CexmcEventSObject.hh"
61 #include "CexmcEventFastSObject.hh"
62 #include "CexmcTrackingAction.hh"
64 #include "CexmcRunManager.hh"
65 #include "CexmcHistoManager.hh"
66 #include "CexmcRun.hh"
67 #include "CexmcPhysicsManager.hh"
68 #include "CexmcProductionModel.hh"
73 #include "CexmcTrackPointsStore.hh"
74 #include "CexmcTrackPointInfo.hh"
75 #include "CexmcException.hh"
76 #include "CexmcCommon.hh"
77 
78 
79 namespace
80 {
81  G4double CexmcSmallCircleScreenSize( 5.0 );
82  G4double CexmcBigCircleScreenSize( 10.0 );
83  G4Colour CexmcTrackPointsMarkerColour( 0.0, 1.0, 0.4 );
84  G4Colour CexmcRecTrackPointsMarkerColour( 1.0, 0.4, 0.0 );
85 
86 #ifdef CEXMC_USE_ROOT
87  inline G4double CexmcGetKinEnergy( G4double momentumAmp, G4double mass )
88  {
89  return std::sqrt( momentumAmp * momentumAmp + mass * mass ) - mass;
90  }
91 #endif
92 }
93 
94 
96  G4int verbose_ ) :
97  physicsManager( physicsManager_ ), reconstructor( NULL ),
98 #ifdef CEXMC_USE_ROOT
99  opKinEnergy( 0. ),
100 #endif
101  verbose( verbose_ ), verboseDraw( 4 ), messenger( NULL )
102 {
103  G4DigiManager * digiManager( G4DigiManager::GetDMpointer() );
104  digiManager->AddNewModule( new CexmcEnergyDepositDigitizer(
106  digiManager->AddNewModule( new CexmcTrackPointsDigitizer(
110  messenger = new CexmcEventActionMessenger( this );
111 }
112 
113 
115 {
116  delete reconstructor;
117  delete messenger;
118 }
119 
120 
122 {
124 }
125 
126 
128 {
129  G4RunManager * runManager( G4RunManager::GetRunManager() );
130  CexmcTrackingAction * trackingAction
131  ( static_cast< CexmcTrackingAction * >(
132  const_cast< G4UserTrackingAction * >(
133  runManager->GetUserTrackingAction() ) ) );
134  trackingAction->BeginOfEventAction();
135 
137 }
138 
139 
141  const CexmcEnergyDepositDigitizer * digitizer )
142 {
143  G4double monitorED( digitizer->GetMonitorED() );
144  G4double vetoCounterEDLeft( digitizer->GetVetoCounterEDLeft() );
145  G4double vetoCounterEDRight( digitizer->GetVetoCounterEDRight() );
146  G4double calorimeterEDLeft( digitizer->GetCalorimeterEDLeft() );
147  G4double calorimeterEDRight( digitizer->GetCalorimeterEDRight() );
148  G4int calorimeterEDLeftMaxX( digitizer->GetCalorimeterEDLeftMaxX() );
149  G4int calorimeterEDLeftMaxY( digitizer->GetCalorimeterEDLeftMaxY() );
150  G4int calorimeterEDRightMaxX( digitizer->GetCalorimeterEDRightMaxX() );
151  G4int calorimeterEDRightMaxY( digitizer->GetCalorimeterEDRightMaxY() );
152 
154  calorimeterEDLeftCollection(
155  digitizer->GetCalorimeterEDLeftCollection() );
157  calorimeterEDRightCollection(
158  digitizer->GetCalorimeterEDRightCollection() );
159 
160  /* ATTENTION: return object in heap - must be freed by caller! */
161  return new CexmcEnergyDepositStore( monitorED, vetoCounterEDLeft,
162  vetoCounterEDRight, calorimeterEDLeft, calorimeterEDRight,
163  calorimeterEDLeftMaxX, calorimeterEDLeftMaxY,
164  calorimeterEDRightMaxX, calorimeterEDRightMaxY,
165  calorimeterEDLeftCollection, calorimeterEDRightCollection );
166 }
167 
168 
170  const CexmcTrackPointsDigitizer * digitizer )
171 {
172  const CexmcTrackPointInfo &
173  monitorTP( digitizer->GetMonitorTP() );
174  const CexmcTrackPointInfo &
175  targetTPBeamParticle(
176  digitizer->GetTargetTPBeamParticle() );
177  const CexmcTrackPointInfo &
178  targetTPOutputParticle(
179  digitizer->GetTargetTPOutputParticle() );
180  const CexmcTrackPointInfo &
181  targetTPNucleusParticle(
182  digitizer->GetTargetTPNucleusParticle() );
183  const CexmcTrackPointInfo &
184  targetTPOutputParticleDecayProductParticle1(
185  digitizer->
186  GetTargetTPOutputParticleDecayProductParticle( 0 ) );
187  const CexmcTrackPointInfo &
188  targetTPOutputParticleDecayProductParticle2(
189  digitizer->
190  GetTargetTPOutputParticleDecayProductParticle( 1 ) );
191  const CexmcTrackPointInfo &
192  vetoCounterTPLeft(
193  digitizer->GetVetoCounterTPLeft() );
194  const CexmcTrackPointInfo &
195  vetoCounterTPRight(
196  digitizer->GetVetoCounterTPRight() );
197  const CexmcTrackPointInfo &
198  calorimeterTPLeft(
199  digitizer->GetCalorimeterTPLeft() );
200  const CexmcTrackPointInfo &
201  calorimeterTPRight(
202  digitizer->GetCalorimeterTPRight() );
203 
204  /* ATTENTION: return object in heap - must be freed by caller! */
205  return new CexmcTrackPointsStore( monitorTP, targetTPBeamParticle,
206  targetTPOutputParticle, targetTPNucleusParticle,
207  targetTPOutputParticleDecayProductParticle1,
208  targetTPOutputParticleDecayProductParticle2,
209  vetoCounterTPLeft, vetoCounterTPRight,
210  calorimeterTPLeft, calorimeterTPRight );
211 }
212 
213 
215  const CexmcEnergyDepositStore * edStore )
216 {
217  G4cout << " --- Energy Deposit" << G4endl;
218  G4cout << " monitor : " <<
219  G4BestUnit( edStore->monitorED, "Energy" ) << G4endl;
220  G4cout << " vc (l) : " <<
221  G4BestUnit( edStore->vetoCounterEDLeft, "Energy" ) << G4endl;
222  G4cout << " vc (r) : " <<
223  G4BestUnit( edStore->vetoCounterEDRight, "Energy" ) << G4endl;
224  G4cout << " cal (l) : " <<
225  G4BestUnit( edStore->calorimeterEDLeft, "Energy" );
227  G4cout << " cal (r) : " <<
228  G4BestUnit( edStore->calorimeterEDRight, "Energy" );
230 }
231 
232 
234  const CexmcTrackPointsStore * tpStore )
235 {
236  if ( ! tpStore )
237  return;
238 
239  G4cout << " --- Track Points" << G4endl;
240  G4cout << " monitor : " << tpStore->monitorTP << G4endl;
241  G4cout << " target : " << tpStore->targetTPBeamParticle << G4endl;
242  G4cout << " : " << tpStore->targetTPOutputParticle << G4endl;
243  G4cout << " : " << tpStore->targetTPNucleusParticle << G4endl;
244  G4cout << " : " <<
246  G4cout << " : " <<
248  G4cout << " vc (l) : " << tpStore->vetoCounterTPLeft << G4endl;
249  G4cout << " vc (r) : " << tpStore->vetoCounterTPRight << G4endl;
250  G4cout << " cal (l) : " << tpStore->calorimeterTPLeft << G4endl;
251  G4cout << " cal (r) : " << tpStore->calorimeterTPRight << G4endl;
252  G4cout << " ---" << G4endl;
253  G4cout << " angle between the " <<
255  " decay products : " <<
257  angle(
259  deg << " deg" << G4endl;
260 }
261 
262 
264  const CexmcAngularRangeList & angularRanges,
265  const CexmcProductionModelData & pmData )
266 {
267  G4cout << " --- Triggered angular ranges: " << angularRanges;
268  G4cout << " --- Production model data: " << pmData;
269 }
270 
271 
273  const CexmcAngularRangeList & triggeredRecAngularRanges,
274  const CexmcAngularRange & angularGap ) const
275 {
276  G4cout << " --- Reconstructed data: " << G4endl;
277  G4cout << " -- entry points:" << G4endl;
278  G4cout << " left: " << G4BestUnit(
279  reconstructor->GetCalorimeterEPLeftPosition(), "Length" ) << G4endl;
280  G4cout << " right: " << G4BestUnit(
281  reconstructor->GetCalorimeterEPRightPosition(), "Length" ) << G4endl;
282  G4cout << " target: " << G4BestUnit(
283  reconstructor->GetTargetEPPosition(), "Length" ) << G4endl;
284  G4cout << " -- the angle: " << reconstructor->GetTheAngle() / deg <<
285  " deg" << G4endl;
286  G4cout << " -- mass of the output particle: " << G4BestUnit(
287  reconstructor->GetOutputParticleMass(), "Energy" ) << G4endl;
288  G4cout << " -- mass of the nucleus output particle: " << G4BestUnit(
289  reconstructor->GetNucleusOutputParticleMass(), "Energy" ) << G4endl;
290  if ( reconstructor->IsMassCutUsed() )
291  {
293  G4cout << " < mass cut passed >" << G4endl;
294  else
295  G4cout << " < mass cut failed >" << G4endl;
296  }
298  {
300  G4cout << " < absorbed energy cut passed >" << G4endl;
301  else
302  G4cout << " < absorbed energy cut failed >" << G4endl;
303  }
304  const CexmcProductionModelData & pmData(
306  G4cout << " -- production model data: " << pmData;
307  G4cout << " -- triggered angular ranges: ";
308  if ( triggeredRecAngularRanges.empty() )
309  G4cout << "< orphan detected, gap " << angularGap << " >" << G4endl;
310  else
311  G4cout << triggeredRecAngularRanges;
312 }
313 
314 
315 #ifdef CEXMC_USE_ROOT
316 
317 void CexmcEventAction::FillEDTHistos( const CexmcEnergyDepositStore * edStore,
318  const CexmcAngularRangeList & triggeredAngularRanges ) const
319 {
320  CexmcHistoManager * histoManager( CexmcHistoManager::Instance() );
321 
322  histoManager->Add( CexmcAbsorbedEnergy_EDT_Histo, 0,
323  edStore->calorimeterEDLeft,
324  edStore->calorimeterEDRight );
325 
326  for ( CexmcAngularRangeList::const_iterator
327  k( triggeredAngularRanges.begin() );
328  k != triggeredAngularRanges.end(); ++k )
329  {
330  histoManager->Add( CexmcAbsEnInLeftCalorimeter_ARReal_EDT_Histo,
331  k->index, edStore->calorimeterEDLeft );
332  histoManager->Add( CexmcAbsEnInRightCalorimeter_ARReal_EDT_Histo,
333  k->index, edStore->calorimeterEDRight );
334  }
335 }
336 
337 
338 void CexmcEventAction::FillTPTHistos( const CexmcTrackPointsStore * tpStore,
339  const CexmcProductionModelData & pmData,
340  const CexmcAngularRangeList & triggeredAngularRanges ) const
341 {
342  CexmcHistoManager * histoManager( CexmcHistoManager::Instance() );
343 
344  if ( tpStore->monitorTP.IsValid() )
345  {
346  histoManager->Add( CexmcMomentumBP_TPT_Histo, 0,
347  tpStore->monitorTP.momentumAmp );
348  histoManager->Add( CexmcTPInMonitor_TPT_Histo, 0,
349  tpStore->monitorTP.positionLocal.x(),
350  tpStore->monitorTP.positionLocal.y() );
351  }
352 
353  if ( tpStore->targetTPOutputParticle.IsValid() )
354  {
355  histoManager->Add( CexmcTPInTarget_TPT_Histo, 0,
359  if ( histoManager->GetVerboseLevel() > 0 )
360  {
361  histoManager->Add( CexmcMomentumIP_TPT_Histo, 0,
362  pmData.incidentParticleLAB.rho() );
363  }
364  }
365 
366  for ( CexmcAngularRangeList::const_iterator
367  k( triggeredAngularRanges.begin() );
368  k != triggeredAngularRanges.end(); ++k )
369  {
370  if ( tpStore->calorimeterTPLeft.IsValid() )
371  {
372  /* kinetic energy and momentum of gamma are equal */
373  G4double kinEnergy( tpStore->calorimeterTPLeft.momentumAmp );
374  histoManager->Add( CexmcKinEnAtLeftCalorimeter_ARReal_TPT_Histo,
375  k->index, kinEnergy );
376  }
377  if ( tpStore->calorimeterTPRight.IsValid() )
378  {
379  G4double kinEnergy( tpStore->calorimeterTPRight.momentumAmp );
380  histoManager->Add( CexmcKinEnAtRightCalorimeter_ARReal_TPT_Histo,
381  k->index, kinEnergy );
382  }
383  if ( tpStore->targetTPOutputParticle.IsValid() )
384  {
385  histoManager->Add( CexmcTPInTarget_ARReal_TPT_Histo, k->index,
389  histoManager->Add( CexmcKinEnOP_LAB_ARReal_TPT_Histo, k->index,
390  opKinEnergy );
391  histoManager->Add( CexmcAngleOP_SCM_ARReal_TPT_Histo, k->index,
392  pmData.outputParticleSCM.cosTheta() );
393  }
396  {
397  G4double openAngle(
399  directionWorld.angle( tpStore->
400  targetTPOutputParticleDecayProductParticle2.
401  directionWorld ) / deg );
402  histoManager->Add( CexmcOpenAngle_ARReal_TPT_Histo, k->index,
403  openAngle );
404  }
405  }
406 }
407 
408 
409 void CexmcEventAction::FillRTHistos( G4bool reconstructorHasFullTrigger,
410  const CexmcEnergyDepositStore * edStore,
411  const CexmcTrackPointsStore * tpStore,
412  const CexmcProductionModelData & pmData,
413  const CexmcAngularRangeList & triggeredAngularRanges ) const
414 {
415  CexmcHistoManager * histoManager( CexmcHistoManager::Instance() );
416 
419 
420  histoManager->Add( CexmcRecMasses_EDT_Histo, 0, opMass, nopMass );
421 
422  for ( CexmcAngularRangeList::const_iterator
423  k( triggeredAngularRanges.begin() );
424  k != triggeredAngularRanges.end(); ++k )
425  {
426  if ( tpStore->calorimeterTPLeft.IsValid() )
427  {
428  histoManager->Add( CexmcOPDPAtLeftCalorimeter_ARReal_EDT_Histo,
429  k->index,
430  tpStore->calorimeterTPLeft.positionLocal.x(),
431  tpStore->calorimeterTPLeft.positionLocal.y() );
432  }
433  if ( tpStore->calorimeterTPRight.IsValid() )
434  {
435  histoManager->Add( CexmcOPDPAtRightCalorimeter_ARReal_EDT_Histo,
436  k->index,
438  tpStore->calorimeterTPRight.positionLocal.y() );
439  }
440  histoManager->Add( CexmcRecOPDPAtLeftCalorimeter_ARReal_EDT_Histo,
441  k->index,
444  histoManager->Add( CexmcRecOPDPAtRightCalorimeter_ARReal_EDT_Histo,
445  k->index,
448  }
449 
450  if ( ! reconstructorHasFullTrigger )
451  return;
452 
453  if ( tpStore->monitorTP.IsValid() )
454  {
455  histoManager->Add( CexmcMomentumBP_RT_Histo, 0,
456  tpStore->monitorTP.momentumAmp );
457  }
458 
459  if ( tpStore->targetTPOutputParticle.IsValid() )
460  {
461  histoManager->Add( CexmcTPInTarget_RT_Histo, 0,
465  }
466 
467  histoManager->Add( CexmcRecMasses_RT_Histo, 0,
470 
471  histoManager->Add( CexmcAbsorbedEnergy_RT_Histo, 0,
472  edStore->calorimeterEDLeft,
473  edStore->calorimeterEDRight );
474 
476  outputParticleSCM.cosTheta());
477 
478  for ( CexmcAngularRangeList::const_iterator
479  k( triggeredAngularRanges.begin() );
480  k != triggeredAngularRanges.end(); ++k )
481  {
482  histoManager->Add( CexmcRecMassOP_ARReal_RT_Histo, k->index, opMass );
483  histoManager->Add( CexmcRecMassNOP_ARReal_RT_Histo, k->index, nopMass );
484  if ( tpStore->calorimeterTPLeft.IsValid() )
485  {
486  G4double kinEnergy( tpStore->calorimeterTPLeft.momentumAmp );
487  histoManager->Add( CexmcKinEnAtLeftCalorimeter_ARReal_RT_Histo,
488  k->index, kinEnergy );
489  histoManager->Add( CexmcMissEnFromLeftCalorimeter_ARReal_RT_Histo,
490  k->index,
491  kinEnergy - edStore->calorimeterEDLeft );
492  }
493  if ( tpStore->calorimeterTPRight.IsValid() )
494  {
495  G4double kinEnergy( tpStore->calorimeterTPRight.momentumAmp );
496  histoManager->Add( CexmcKinEnAtRightCalorimeter_ARReal_RT_Histo,
497  k->index, kinEnergy );
498  histoManager->Add( CexmcMissEnFromRightCalorimeter_ARReal_RT_Histo,
499  k->index,
500  kinEnergy - edStore->calorimeterEDRight );
501  }
502  if ( tpStore->targetTPOutputParticle.IsValid() )
503  {
504  histoManager->Add( CexmcTPInTarget_ARReal_RT_Histo, k->index,
508  histoManager->Add( CexmcKinEnOP_LAB_ARReal_RT_Histo, k->index,
509  opKinEnergy );
510  histoManager->Add( CexmcAngleOP_SCM_ARReal_RT_Histo, k->index,
511  pmData.outputParticleSCM.cosTheta() );
512  G4double diffCosTheta( pmData.outputParticleSCM.cosTheta() -
513  recCosTheta );
514  histoManager->Add( CexmcDiffAngleOP_SCM_ARReal_RT_Histo, k->index,
515  diffCosTheta );
516  }
519  {
520  G4double openAngle(
522  directionWorld.angle( tpStore->
523  targetTPOutputParticleDecayProductParticle2.
524  directionWorld ) / deg );
525  histoManager->Add( CexmcOpenAngle_ARReal_RT_Histo, k->index,
526  openAngle );
527  G4double diffOpenAngle( openAngle - reconstructor->GetTheAngle() /
528  deg );
529  histoManager->Add( CexmcDiffOpenAngle_ARReal_RT_Histo, k->index,
530  diffOpenAngle );
531  }
532  if ( tpStore->calorimeterTPLeft.IsValid() )
533  {
534  histoManager->Add( CexmcOPDPAtLeftCalorimeter_ARReal_RT_Histo,
535  k->index,
536  tpStore->calorimeterTPLeft.positionLocal.x(),
537  tpStore->calorimeterTPLeft.positionLocal.y() );
538  }
539  if ( tpStore->calorimeterTPRight.IsValid() )
540  {
541  histoManager->Add( CexmcOPDPAtRightCalorimeter_ARReal_RT_Histo,
542  k->index,
544  tpStore->calorimeterTPRight.positionLocal.y() );
545  }
546  histoManager->Add( CexmcAbsEnInLeftCalorimeter_ARReal_RT_Histo,
547  k->index, edStore->calorimeterEDLeft );
548  histoManager->Add( CexmcAbsEnInRightCalorimeter_ARReal_RT_Histo,
549  k->index, edStore->calorimeterEDRight );
550  histoManager->Add( CexmcRecAngleOP_SCM_ARReal_RT_Histo,
551  k->index, recCosTheta );
552  histoManager->Add( CexmcRecOpenAngle_ARReal_RT_Histo,
553  k->index, reconstructor->GetTheAngle() / deg );
554  histoManager->Add( CexmcRecOPDPAtLeftCalorimeter_ARReal_RT_Histo,
555  k->index,
558  histoManager->Add( CexmcRecOPDPAtRightCalorimeter_ARReal_RT_Histo,
559  k->index,
562  }
563 }
564 
565 #endif
566 
567 
569 {
570  G4VisManager * visManager( static_cast< G4VisManager * >(
572  if ( ! visManager || ! visManager->GetCurrentGraphicsSystem() )
573  return;
574 
575  G4int nTraj( 0 );
576  G4TrajectoryContainer * trajContainer( event->GetTrajectoryContainer() );
577 
578  if ( ! trajContainer )
579  return;
580 
581  nTraj = trajContainer->entries();
582 
583  for ( int i( 0 ); i < nTraj; ++i )
584  {
585  G4VTrajectory * traj( ( *trajContainer )[ i ] );
586  traj->DrawTrajectory();
587  }
588 }
589 
590 
592  const CexmcTrackPointsStore * tpStore ) const
593 {
594  G4VisManager * visManager( static_cast< G4VisManager * >(
596  if ( ! visManager || ! visManager->GetCurrentGraphicsSystem() )
597  return;
598 
599  G4Circle circle;
600  G4VisAttributes visAttributes( CexmcTrackPointsMarkerColour );
601  circle.SetScreenSize( CexmcSmallCircleScreenSize );
602  circle.SetFillStyle( G4Circle::filled );
603  circle.SetVisAttributes( visAttributes );
604 
605  if ( tpStore->monitorTP.IsValid() )
606  {
607  circle.SetPosition( tpStore->monitorTP.positionWorld );
608  visManager->Draw( circle );
609  }
610 
611  if ( tpStore->targetTPBeamParticle.IsValid() )
612  {
614  visManager->Draw( circle );
615  }
616 
617  if ( tpStore->targetTPOutputParticle.IsValid() )
618  {
620  visManager->Draw( circle );
621  }
622 
623  if ( tpStore->vetoCounterTPLeft.IsValid() )
624  {
625  circle.SetPosition( tpStore->vetoCounterTPLeft.positionWorld );
626  visManager->Draw( circle );
627  }
628 
629  if ( tpStore->vetoCounterTPRight.IsValid() )
630  {
631  circle.SetPosition( tpStore->vetoCounterTPRight.positionWorld );
632  visManager->Draw( circle );
633  }
634 
635  if ( tpStore->calorimeterTPLeft.IsValid() )
636  {
637  circle.SetPosition( tpStore->calorimeterTPLeft.positionWorld );
638  visManager->Draw( circle );
639  }
640 
641  if ( tpStore->calorimeterTPRight.IsValid() )
642  {
643  circle.SetPosition( tpStore->calorimeterTPRight.positionWorld );
644  visManager->Draw( circle );
645  }
646 }
647 
648 
650 {
651  G4VisManager * visManager( static_cast< G4VisManager * >(
653  if ( ! visManager || ! visManager->GetCurrentGraphicsSystem() )
654  return;
655 
657  circle.SetScreenSize( CexmcSmallCircleScreenSize );
658  circle.SetFillStyle( G4Circle::filled );
659  G4VisAttributes visAttributes( CexmcRecTrackPointsMarkerColour );
660  circle.SetVisAttributes( visAttributes );
661  visManager->Draw( circle );
662 
663  circle.SetScreenSize( CexmcBigCircleScreenSize );
664  circle.SetPosition( reconstructor->GetCalorimeterEPLeftWorldPosition() );
665  visManager->Draw( circle );
666 
667  circle.SetPosition( reconstructor->GetCalorimeterEPRightWorldPosition() );
668  visManager->Draw( circle );
669 }
670 
671 
673  const CexmcAngularRangeList & aRangesReal,
674  const CexmcAngularRangeList & aRangesRec,
675  G4bool tpDigitizerHasTriggered,
676  G4bool edDigitizerHasTriggered,
677  G4bool edDigitizerMonitorHasTriggered,
678  G4bool reconstructorHasFullTrigger,
679  const CexmcAngularRange & aGap )
680 {
681  G4RunManager * runManager( G4RunManager::GetRunManager() );
682  const CexmcRun * run( static_cast< const CexmcRun * >(
683  runManager->GetCurrentRun() ) );
684  CexmcRun * theRun( const_cast< CexmcRun * >( run ) );
685 
686  if ( tpDigitizerHasTriggered )
687  {
688  for ( CexmcAngularRangeList::const_iterator k( aRangesReal.begin() );
689  k != aRangesReal.end(); ++k )
690  {
691  theRun->IncrementNmbOfHitsSampledFull( k->index );
692  if ( edDigitizerMonitorHasTriggered )
693  theRun->IncrementNmbOfHitsSampled( k->index );
694  if ( reconstructorHasFullTrigger )
695  theRun->IncrementNmbOfHitsTriggeredRealRange( k->index );
696  }
697  if ( reconstructorHasFullTrigger )
698  {
699  if ( aRangesRec.empty() )
700  {
701  theRun->IncrementNmbOfOrphanHits( aGap.index );
702  }
703  else
704  {
705  for ( CexmcAngularRangeList::const_iterator
706  k( aRangesRec.begin() ); k != aRangesRec.end(); ++k )
707  {
708  theRun->IncrementNmbOfHitsTriggeredRecRange( k->index );
709  }
710  }
711  }
712  }
713  else
714  {
715  if ( edDigitizerHasTriggered )
717  if ( reconstructorHasFullTrigger )
719  }
720 }
721 
722 
723 #ifdef CEXMC_USE_PERSISTENCY
724 
725 void CexmcEventAction::SaveEvent( const G4Event * event,
726  G4bool edDigitizerHasTriggered,
727  const CexmcEnergyDepositStore * edStore,
728  const CexmcTrackPointsStore * tpStore,
729  const CexmcProductionModelData & pmData )
730 {
731  CexmcRunManager * runManager( static_cast< CexmcRunManager * >(
733  if ( ! runManager->ProjectIsSaved() )
734  return;
735 
736  if ( runManager->GetEventDataVerboseLevel() == CexmcWriteNoEventData )
737  return;
738 
739  if ( ! edDigitizerHasTriggered && runManager->GetEventDataVerboseLevel() !=
741  return;
742 
743  boost::archive::binary_oarchive * archive(
744  runManager->GetEventsArchive() );
745  if ( archive )
746  {
747  CexmcEventSObject sObject = { event->GetEventID(),
748  edDigitizerHasTriggered, edStore->monitorED,
749  edStore->vetoCounterEDLeft, edStore->vetoCounterEDRight,
750  edStore->calorimeterEDLeft, edStore->calorimeterEDRight,
753  tpStore->monitorTP, tpStore->targetTPBeamParticle,
757  tpStore->vetoCounterTPLeft, tpStore->vetoCounterTPRight,
758  tpStore->calorimeterTPLeft, tpStore->calorimeterTPRight, pmData };
759  archive->operator<<( sObject );
760  const CexmcRun * run( static_cast< const CexmcRun * >(
761  runManager->GetCurrentRun() ) );
762  CexmcRun * theRun( const_cast< CexmcRun * >( run ) );
763  theRun->IncrementNmbOfSavedEvents();
764  }
765 }
766 
767 
768 void CexmcEventAction::SaveEventFast( const G4Event * event,
769  G4bool tpDigitizerHasTriggered,
770  G4bool edDigitizerHasTriggered,
771  G4bool edDigitizerMonitorHasTriggered,
772  G4double opCosThetaSCM )
773 {
774  CexmcRunManager * runManager( static_cast< CexmcRunManager * >(
776  if ( ! runManager->ProjectIsSaved() )
777  return;
778 
779  if ( runManager->GetEventDataVerboseLevel() == CexmcWriteNoEventData )
780  return;
781 
782  boost::archive::binary_oarchive * archive(
783  runManager->GetFastEventsArchive() );
784  if ( archive )
785  {
786  if ( ! tpDigitizerHasTriggered )
787  opCosThetaSCM = CexmcInvalidCosTheta;
788 
789  CexmcEventFastSObject sObject = { event->GetEventID(), opCosThetaSCM,
790  edDigitizerHasTriggered,
791  edDigitizerMonitorHasTriggered };
792  archive->operator<<( sObject );
793  const CexmcRun * run( static_cast< const CexmcRun * >(
794  runManager->GetCurrentRun() ) );
795  CexmcRun * theRun( const_cast< CexmcRun * >( run ) );
796  theRun->IncrementNmbOfSavedFastEvents();
797  }
798 }
799 
800 #endif
801 
802 
804 {
805  G4DigiManager * digiManager( G4DigiManager::GetDMpointer() );
806  CexmcEnergyDepositDigitizer * energyDepositDigitizer(
807  static_cast< CexmcEnergyDepositDigitizer * >( digiManager->
808  FindDigitizerModule( CexmcEDDigitizerName ) ) );
809  CexmcTrackPointsDigitizer * trackPointsDigitizer(
810  static_cast< CexmcTrackPointsDigitizer * >( digiManager->
811  FindDigitizerModule( CexmcTPDigitizerName ) ) );
812 
813  energyDepositDigitizer->Digitize();
814  trackPointsDigitizer->Digitize();
815 
816  G4bool edDigitizerMonitorHasTriggered(
817  energyDepositDigitizer->MonitorHasTriggered() );
818  G4bool edDigitizerHasTriggered( false );
819 
820  CexmcEventInfo * eventInfo( static_cast< CexmcEventInfo * >(
821  event->GetUserInformation() ) );
822  if ( ! eventInfo || eventInfo->EdTriggerIsOk() )
823  edDigitizerHasTriggered = energyDepositDigitizer->HasTriggered();
824 
825  G4bool tpDigitizerHasTriggered( trackPointsDigitizer->HasTriggered() );
826  G4bool reconstructorHasBasicTrigger( false );
827  G4bool reconstructorHasFullTrigger( false );
828 
830  energyDepositDigitizer ) );
832  trackPointsDigitizer ) );
833 
834  try
835  {
836  CexmcProductionModel * productionModel(
838 
839  if ( ! productionModel )
841 
842  const CexmcAngularRangeList & angularRanges(
843  productionModel->GetAngularRanges() );
844  const CexmcAngularRangeList & triggeredAngularRanges(
845  productionModel->GetTriggeredAngularRanges() );
846  const CexmcProductionModelData & pmData(
847  productionModel->GetProductionModelData() );
848 
849  if ( edDigitizerHasTriggered )
850  {
851  reconstructor->Reconstruct( edStore );
852  reconstructorHasBasicTrigger = reconstructor->HasBasicTrigger();
853  reconstructorHasFullTrigger = reconstructor->HasFullTrigger();
854  }
855 
856  CexmcAngularRangeList triggeredRecAngularRanges;
857 
858  if ( reconstructorHasBasicTrigger )
859  {
860  for ( CexmcAngularRangeList::const_iterator
861  k( angularRanges.begin() ); k != angularRanges.end(); ++k )
862  {
864  outputParticleSCM.cosTheta() );
865  if ( cosTheta <= k->top && cosTheta > k->bottom )
866  triggeredRecAngularRanges.push_back( CexmcAngularRange(
867  k->top, k->bottom, k->index ) );
868  }
869  }
870 
871  CexmcAngularRange angularGap( 0.0, 0.0, 0 );
872  if ( triggeredRecAngularRanges.empty() )
873  {
874  CexmcAngularRangeList angularGaps;
875  GetAngularGaps( angularRanges, angularGaps );
876  for ( CexmcAngularRangeList::const_iterator
877  k( angularGaps.begin() ); k != angularGaps.end(); ++k )
878  {
880  outputParticleSCM.cosTheta() );
881  if ( cosTheta <= k->top && cosTheta > k->bottom )
882  {
883  angularGap = *k;
884  break;
885  }
886  }
887  }
888 
889  UpdateRunHits( triggeredAngularRanges, triggeredRecAngularRanges,
890  tpDigitizerHasTriggered, edDigitizerHasTriggered,
891  edDigitizerMonitorHasTriggered,
892  reconstructorHasFullTrigger, angularGap );
893 
894  if ( verbose > 0 )
895  {
896  G4bool printMessages( verbose > 3 ||
897  ( ( verbose == 1 ) && tpDigitizerHasTriggered ) ||
898  ( ( verbose == 2 ) && edDigitizerHasTriggered ) ||
899  ( ( verbose == 3 ) && ( tpDigitizerHasTriggered ||
900  edDigitizerHasTriggered ) ) );
901  if ( printMessages )
902  {
903  G4cout << "Event " << event->GetEventID() << G4endl;
904  if ( tpDigitizerHasTriggered )
905  {
906  PrintTrackPoints( tpStore );
907  PrintProductionModelData( triggeredAngularRanges, pmData );
908  }
909  if ( reconstructorHasBasicTrigger )
910  PrintReconstructedData( triggeredRecAngularRanges,
911  angularGap );
912  if ( edDigitizerHasTriggered )
913  PrintEnergyDeposit( edStore );
914  }
915  }
916 
917  if ( verboseDraw > 0 )
918  {
919  G4bool drawTrajectories( verboseDraw > 3 ||
920  ( ( verboseDraw == 1 ) && tpDigitizerHasTriggered ) ||
921  ( ( verboseDraw == 2 ) && edDigitizerHasTriggered ) ||
922  ( ( verboseDraw == 3 ) && ( tpDigitizerHasTriggered ||
923  edDigitizerHasTriggered ) ) );
924  if ( drawTrajectories )
925  {
926  DrawTrajectories( event );
927  if ( tpDigitizerHasTriggered )
928  DrawTrackPoints( tpStore );
929  if ( reconstructorHasBasicTrigger )
931  }
932  }
933 
934 #ifdef CEXMC_USE_PERSISTENCY
935  if ( edDigitizerHasTriggered || tpDigitizerHasTriggered )
936  {
937  SaveEventFast( event, tpDigitizerHasTriggered,
938  edDigitizerHasTriggered,
939  edDigitizerMonitorHasTriggered,
940  pmData.outputParticleSCM.cosTheta() );
941  SaveEvent( event, edDigitizerHasTriggered, edStore, tpStore,
942  pmData );
943  }
944 #endif
945 
946 #ifdef CEXMC_USE_ROOT
947  /* opKinEnergy will be used in several histos */
948  if ( tpStore->targetTPOutputParticle.IsValid() )
949  {
950  opKinEnergy = CexmcGetKinEnergy(
953  }
954 
955  if ( edDigitizerHasTriggered )
956  FillEDTHistos( edStore, triggeredAngularRanges );
957 
958  /* fill TPT histos only when the monitor has triggered because events
959  * when it was missed have less value for us */
960  if ( tpDigitizerHasTriggered && edDigitizerMonitorHasTriggered )
961  FillTPTHistos( tpStore, pmData, triggeredAngularRanges );
962 
963  if ( reconstructorHasBasicTrigger )
964  FillRTHistos( reconstructorHasFullTrigger, edStore, tpStore,
965  pmData, triggeredAngularRanges );
966 #endif
967 
968  G4Event * theEvent( const_cast< G4Event * >( event ) );
969  if ( eventInfo )
970  {
971  delete eventInfo;
972  theEvent->SetUserInformation( NULL );
973  }
974  theEvent->SetUserInformation( new CexmcEventInfo(
975  edDigitizerHasTriggered,
976  tpDigitizerHasTriggered,
977  reconstructorHasFullTrigger ) );
978  }
979  catch ( CexmcException & e )
980  {
981  G4cout << e.what() << G4endl;
982  }
983  catch ( ... )
984  {
985  G4cout << "Unknown exception caught" << G4endl;
986  }
987 
988  delete edStore;
989  delete tpStore;
990 }
991