Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/advanced/ChargeExchangeMC/src/CexmcRunManager.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:  CexmcRunManager.cc
 30  *
 31  *    Description:  run manager
 32  *
 33  *        Version:  1.0
 34  *        Created:  03.11.2009 20:27:46
 35  *       Revision:  none
 36  *       Compiler:  gcc
 37  *
 38  *         Author:  Alexey Radkov (), 
 39  *        Company:  PNPI
 40  *
 41  * ============================================================================
 42  */
 43 
 44 #include <stdlib.h>
 45 #include <sys/stat.h>
 46 #include <vector>
 47 #include <fstream>
 48 #ifdef CEXMC_USE_PERSISTENCY
 49 #include <boost/archive/binary_iarchive.hpp>
 50 #include <boost/archive/binary_oarchive.hpp>
 51 #endif
 52 #include <G4Eta.hh>
 53 #include <G4DigiManager.hh>
 54 #include <G4SDManager.hh>
 55 #include <G4DecayTable.hh>
 56 #include <G4ParticleDefinition.hh>
 57 #include <G4ParticleTable.hh>
 58 #include <G4UImanager.hh>
 59 #include <G4Timer.hh>
 60 #include <G4Region.hh>
 61 #include <G4RegionStore.hh>
 62 #include <G4ProductionCuts.hh>
 63 #include <G4VisManager.hh>
 64 #include <G4Scene.hh>
 65 #include <G4VModel.hh>
 66 #include <G4Version.hh>
 67 #include "CexmcRunManager.hh"
 68 #include "CexmcRunManagerMessenger.hh"
 69 #include "CexmcRunAction.hh"
 70 #include "CexmcRun.hh"
 71 #include "CexmcPhysicsManager.hh"
 72 #include "CexmcProductionModel.hh"
 73 #include "CexmcSimpleDecayTableStore.hh"
 74 #include "CexmcPrimaryGeneratorAction.hh"
 75 #include "CexmcEnergyDepositDigitizer.hh"
 76 #include "CexmcSimpleEnergyDeposit.hh"
 77 #include "CexmcEnergyDepositInLeftRightSet.hh"
 78 #include "CexmcEnergyDepositInCalorimeter.hh"
 79 #include "CexmcTrackPoints.hh"
 80 #include "CexmcTrackPointsInLeftRightSet.hh"
 81 #include "CexmcTrackPointsInCalorimeter.hh"
 82 #include "CexmcChargeExchangeReconstructor.hh"
 83 #include "CexmcEventAction.hh"
 84 #include "CexmcParticleGun.hh"
 85 #include "CexmcEnergyDepositStore.hh"
 86 #include "CexmcTrackPointsStore.hh"
 87 #include "CexmcSetup.hh"
 88 #include "CexmcEventSObject.hh"
 89 #include "CexmcEventFastSObject.hh"
 90 #include "CexmcTrackPointInfo.hh"
 91 #include "CexmcEventInfo.hh"
 92 #include "CexmcBasicPhysicsSettings.hh"
 93 #include "CexmcSensitiveDetectorsAttributes.hh"
 94 #include "CexmcCustomFilterEval.hh"
 95 #include "CexmcScenePrimitives.hh"
 96 
 97 
 98 namespace
 99 {
100     G4String  gdmlFileExtension( ".gdml" );
101     G4String  gdmlbz2FileExtension( ".gdml.bz2" );
102 }
103 
104 
105 CexmcRunManager::CexmcRunManager( const G4String &  projectId_,
106                                   const G4String &  rProject_,
107                                   G4bool  overrideExistingProject ) :
108     basePhysicsUsed( CexmcPMFactoryInstance::GetBasePhysics() ),
109     productionModelType( CexmcUnknownProductionModel ),
110     gdmlFileName( "default.gdml" ), shouldGdmlFileBeValidated( false ),
111     zipGdmlFile( false ), projectsDir( "." ), projectId( projectId_ ),
112     rProject( rProject_ ), guiMacroName( "" ), cfFileName( "" ),
113     eventCountPolicy( CexmcCountAllEvents ),
114     skipInteractionsWithoutEDTonWrite( true ),
115     evDataVerboseLevel( CexmcWriteEventDataOnEveryEDT ),
116     rEvDataVerboseLevel( CexmcWriteNoEventData ), numberOfEventsProcessed( 0 ),
117     numberOfEventsProcessedEffective( 0 ), curEventRead( 0 ),
118 #ifdef CEXMC_USE_PERSISTENCY
119     eventsArchive( NULL ), fastEventsArchive( NULL ),
120 #ifdef CEXMC_USE_CUSTOM_FILTER
121     customFilter( NULL ),
122 #endif
123 #endif
124     physicsManager( NULL ), messenger( NULL )
125 {
126     /* this exception must be caught before creating the object! */
127     if ( rProject != "" && rProject == projectId )
128         throw CexmcException( CexmcWeirdException );
129 
130     const char *  projectsDirEnv( std::getenv( "CEXMC_PROJECTS_DIR" ) );
131 
132     if ( projectsDirEnv )
133         projectsDir = projectsDirEnv;
134 
135     struct stat  tmp;
136     if ( ProjectIsSaved() &&
137          stat( ( projectsDir + "/" + projectId + ".rdb" ).c_str(), &tmp ) == 0
138          && ! overrideExistingProject )
139         throw CexmcException( CexmcProjectExists );
140 
141     messenger = new CexmcRunManagerMessenger( this );
142 
143 #ifdef CEXMC_USE_PERSISTENCY
144     if ( ProjectIsRead() )
145         ReadPreinitProjectData();
146 #endif
147 }
148 
149 
150 CexmcRunManager::~CexmcRunManager()
151 {
152 #ifdef CEXMC_USE_CUSTOM_FILTER
153     delete customFilter;
154 #endif
155     delete messenger;
156 }
157 
158 
159 #ifdef CEXMC_USE_PERSISTENCY
160 
161 void  CexmcRunManager::ReadPreinitProjectData( void )
162 {
163     if ( ! ProjectIsRead() )
164         return;
165 
166     /* read run data */
167     std::ifstream  runDataFile( ( projectsDir + "/" + rProject + ".rdb" ).
168                                 c_str() );
169     if ( ! runDataFile )
170         throw CexmcException( CexmcReadProjectIncomplete );
171 
172     {
173         boost::archive::binary_iarchive  archive( runDataFile );
174         archive >> sObject;
175     }
176 
177     basePhysicsUsed = sObject.basePhysicsUsed;
178 
179     productionModelType = sObject.productionModelType;
180 
181     /* read gdml file */
182     G4String       cmd;
183     if ( ProjectIsSaved() )
184     {
185         G4String  fileExtension( zipGdmlFile ? gdmlbz2FileExtension :
186                                                gdmlFileExtension );
187         cmd = G4String( "cp " ) + projectsDir + "/" + rProject + fileExtension +
188                             " " + projectsDir + "/" + projectId + fileExtension;
189         if ( system( cmd ) != 0 )
190             throw CexmcException( CexmcReadProjectIncomplete );
191     }
192 
193     if ( zipGdmlFile )
194     {
195         cmd = G4String( "bunzip2 " ) + projectsDir + "/" + rProject +
196                                                         gdmlbz2FileExtension;
197         if ( system( cmd ) != 0 )
198             throw CexmcException( CexmcFileCompressException );
199     }
200 
201     gdmlFileName = projectsDir + "/" + rProject + gdmlFileExtension;
202 }
203 
204 
205 void  CexmcRunManager::ReadProject( void )
206 {
207     if ( ! ProjectIsRead() )
208         return;
209 
210     if ( ! physicsManager )
211         throw CexmcException( CexmcWeirdException );
212 
213     physicsManager->GetProductionModel()->SetAngularRanges(
214                                                     sObject.angularRanges );
215     G4DecayTable *  etaDecayTable( G4Eta::Definition()->GetDecayTable() );
216     for ( CexmcDecayBranchesStore::const_iterator
217             k( sObject.etaDecayTable.GetDecayBranches().begin() );
218             k != sObject.etaDecayTable.GetDecayBranches().end(); ++k )
219     {
220         etaDecayTable->GetDecayChannel( k->first )->SetBR( k->second );
221     }
222 
223     physicsManager->GetProductionModel()->ApplyFermiMotion(
224                                             sObject.fermiMotionIsOn, false );
225     eventCountPolicy = sObject.eventCountPolicy;
226 
227     G4Region *  region( G4RegionStore::GetInstance()->GetRegion(
228                                                 CexmcCalorimeterRegionName ) );
229     if ( ! region )
230         throw CexmcException( CexmcCalorimeterRegionNotInitialized );
231 
232     region->GetProductionCuts()->SetProductionCuts(
233                                                 sObject.calorimeterRegCuts );
234 
235     const CexmcPrimaryGeneratorAction *  primaryGeneratorAction(
236                             static_cast< const CexmcPrimaryGeneratorAction * >(
237                                                 userPrimaryGeneratorAction ) );
238     CexmcPrimaryGeneratorAction *        thePrimaryGeneratorAction(
239                             const_cast< CexmcPrimaryGeneratorAction * >(
240                                             primaryGeneratorAction ) );
241     CexmcParticleGun *      particleGun(
242                                 thePrimaryGeneratorAction->GetParticleGun() );
243     G4ParticleDefinition *  particleDefinition(
244                     G4ParticleTable::GetParticleTable()->FindParticle(
245                                                     sObject.beamParticle ) );
246     if ( ! particleDefinition )
247         throw CexmcException( CexmcWeirdException );
248 
249     particleGun->SetParticleDefinition( particleDefinition );
250     particleGun->SetOrigPosition( sObject.beamPos, false );
251     particleGun->SetOrigDirection( sObject.beamDir, false );
252     particleGun->SetOrigMomentumAmp( sObject.beamMomentumAmp, false );
253 
254     thePrimaryGeneratorAction->SetFwhmPosX( sObject.beamFwhmPosX, false );
255     thePrimaryGeneratorAction->SetFwhmPosY( sObject.beamFwhmPosY, false );
256     thePrimaryGeneratorAction->SetFwhmDirX( sObject.beamFwhmDirX, false );
257     thePrimaryGeneratorAction->SetFwhmDirY( sObject.beamFwhmDirY, false );
258     thePrimaryGeneratorAction->SetFwhmMomentumAmp(
259                                         sObject.beamFwhmMomentumAmp, false );
260 
261     G4DigiManager *                digiManager( G4DigiManager::GetDMpointer() );
262     CexmcEnergyDepositDigitizer *  edDigitizer(
263             static_cast< CexmcEnergyDepositDigitizer * >(
264                 digiManager->FindDigitizerModule( CexmcEDDigitizerName ) ) );
265     if ( ! edDigitizer )
266         throw CexmcException( CexmcWeirdException );
267 
268     edDigitizer->SetMonitorThreshold( sObject.monitorEDThreshold, false );
269     edDigitizer->SetVetoCounterLeftThreshold(
270                                 sObject.vetoCounterEDLeftThreshold, false );
271     edDigitizer->SetVetoCounterRightThreshold(
272                                 sObject.vetoCounterEDRightThreshold, false );
273     edDigitizer->SetCalorimeterLeftThreshold(
274                                 sObject.calorimeterEDLeftThreshold, false );
275     edDigitizer->SetCalorimeterRightThreshold(
276                                 sObject.calorimeterEDRightThreshold, false );
277     edDigitizer->SetCalorimeterTriggerAlgorithm(
278                                 sObject.calorimeterTriggerAlgorithm, false );
279     edDigitizer->SetOuterCrystalsVetoAlgorithm(
280                                 sObject.outerCrystalsVetoAlgorithm, false );
281     edDigitizer->SetOuterCrystalsVetoFraction(
282                                 sObject.outerCrystalsVetoFraction, false );
283     edDigitizer->ApplyFiniteCrystalResolution(
284                                 sObject.applyFiniteCrystalResolution, false );
285     edDigitizer->SetCrystalResolutionData( sObject.crystalResolutionData );
286 
287     const CexmcEventAction *  eventAction(
288                 static_cast< const CexmcEventAction * >( userEventAction ) );
289     if ( ! eventAction )
290         throw CexmcException( CexmcWeirdException );
291 
292     CexmcEventAction *        theEventAction( const_cast< CexmcEventAction * >(
293                                                                 eventAction ) );
294     CexmcChargeExchangeReconstructor *  reconstructor(
295                                         theEventAction->GetReconstructor() );
296     if ( ! reconstructor )
297         throw CexmcException( CexmcWeirdException );
298 
299     reconstructor->SetCalorimeterEntryPointDefinitionAlgorithm(
300                                         sObject.epDefinitionAlgorithm );
301     reconstructor->SetCalorimeterEntryPointDepthDefinitionAlgorithm(
302                                         sObject.epDepthDefinitionAlgorithm );
303     reconstructor->SetCrystalSelectionAlgorithm( sObject.csAlgorithm );
304     reconstructor->UseInnerRefCrystal( sObject.useInnerRefCrystal );
305     reconstructor->SetCalorimeterEntryPointDepth( sObject.epDepth );
306     reconstructor->UseTableMass( sObject.useTableMass );
307     reconstructor->UseMassCut( sObject.useMassCut );
308     reconstructor->SetMassCutOPCenter( sObject.mCutOPCenter );
309     reconstructor->SetMassCutNOPCenter( sObject.mCutNOPCenter );
310     reconstructor->SetMassCutOPWidth( sObject.mCutOPWidth );
311     reconstructor->SetMassCutNOPWidth( sObject.mCutNOPWidth );
312     reconstructor->SetMassCutEllipseAngle( sObject.mCutAngle );
313     reconstructor->UseAbsorbedEnergyCut( sObject.useAbsorbedEnergyCut );
314     reconstructor->SetAbsorbedEnergyCutCLCenter( sObject.aeCutCLCenter );
315     reconstructor->SetAbsorbedEnergyCutCRCenter( sObject.aeCutCRCenter );
316     reconstructor->SetAbsorbedEnergyCutCLWidth( sObject.aeCutCLWidth );
317     reconstructor->SetAbsorbedEnergyCutCRWidth( sObject.aeCutCRWidth );
318     reconstructor->SetAbsorbedEnergyCutEllipseAngle( sObject.aeCutAngle );
319     reconstructor->SetExpectedMomentumAmp( sObject.expectedMomentumAmp );
320     reconstructor->SetEDCollectionAlgorithm( sObject.edCollectionAlgorithm );
321 
322     physicsManager->SetProposedMaxIL( sObject.proposedMaxIL );
323 
324     rEvDataVerboseLevel = sObject.evDataVerboseLevel;
325     evDataVerboseLevel = rEvDataVerboseLevel;
326 }
327 
328 
329 void  CexmcRunManager::SaveProject( void )
330 {
331     if ( ! ProjectIsSaved() )
332         return;
333 
334     /* save run data */
335     if ( ! physicsManager )
336         throw CexmcException( CexmcWeirdException );
337 
338     CexmcSimpleDecayTableStore  etaDecayTable(
339                                     G4Eta::Definition()->GetDecayTable() );
340     const CexmcPrimaryGeneratorAction *  primaryGeneratorAction(
341                             static_cast< const CexmcPrimaryGeneratorAction * >(
342                                                 userPrimaryGeneratorAction ) );
343     CexmcPrimaryGeneratorAction *  thePrimaryGeneratorAction(
344                             const_cast< CexmcPrimaryGeneratorAction * >(
345                                             primaryGeneratorAction ) );
346     CexmcParticleGun *  particleGun(
347                             thePrimaryGeneratorAction->GetParticleGun() );
348 
349     G4DigiManager *                digiManager( G4DigiManager::GetDMpointer() );
350     CexmcEnergyDepositDigitizer *  edDigitizer(
351             static_cast< CexmcEnergyDepositDigitizer * >(
352                 digiManager->FindDigitizerModule( CexmcEDDigitizerName ) ) );
353     if ( ! edDigitizer )
354         throw CexmcException( CexmcWeirdException );
355 
356     const CexmcEventAction *  eventAction(
357                 static_cast< const CexmcEventAction * >( userEventAction ) );
358     CexmcEventAction *        theEventAction( const_cast< CexmcEventAction * >(
359                                                                 eventAction ) );
360     CexmcChargeExchangeReconstructor *  reconstructor(
361                                         theEventAction->GetReconstructor() );
362 
363     std::vector< G4double >  calorimeterRegCuts( 4 );
364     if ( ProjectIsRead() )
365     {
366         calorimeterRegCuts = sObject.calorimeterRegCuts;
367     }
368     else
369     {
370         G4Region *  region( G4RegionStore::GetInstance()->GetRegion(
371                                                 CexmcCalorimeterRegionName ) );
372         if ( ! region )
373             throw CexmcException( CexmcCalorimeterRegionNotInitialized );
374 
375         calorimeterRegCuts = region->GetProductionCuts()->GetProductionCuts();
376     }
377 
378     CexmcNmbOfHitsInRanges  nmbOfHitsSampled;
379     CexmcNmbOfHitsInRanges  nmbOfHitsSampledFull;
380     CexmcNmbOfHitsInRanges  nmbOfHitsTriggeredRealRange;
381     CexmcNmbOfHitsInRanges  nmbOfHitsTriggeredRecRange;
382     CexmcNmbOfHitsInRanges  nmbOfOrphanHits;
383     G4int                   nmbOfFalseHitsTriggeredEDT( 0 );
384     G4int                   nmbOfFalseHitsTriggeredRec( 0 );
385     G4int                   nmbOfSavedEvents( 0 );
386     G4int                   nmbOfSavedFastEvents( 0 );
387     CexmcRun *              run( static_cast< CexmcRun * >( currentRun ) );
388 
389     if ( run )
390     {
391         nmbOfHitsSampled = run->GetNmbOfHitsSampled();
392         nmbOfHitsSampledFull = run->GetNmbOfHitsSampledFull();
393         nmbOfHitsTriggeredRealRange = run->GetNmbOfHitsTriggeredRealRange();
394         nmbOfHitsTriggeredRecRange = run->GetNmbOfHitsTriggeredRecRange();
395         nmbOfOrphanHits = run->GetNmbOfOrphanHits();
396         nmbOfFalseHitsTriggeredEDT = run->GetNmbOfFalseHitsTriggeredEDT();
397         nmbOfFalseHitsTriggeredRec = run->GetNmbOfFalseHitsTriggeredRec();
398         nmbOfSavedEvents = run->GetNmbOfSavedEvents();
399         nmbOfSavedFastEvents = run->GetNmbOfSavedFastEvents();
400     }
401 
402     CexmcRunSObject  sObjectToWrite = {
403         basePhysicsUsed, productionModelType, gdmlFileName, etaDecayTable,
404         physicsManager->GetProductionModel()->GetAngularRanges(),
405         physicsManager->GetProductionModel()->IsFermiMotionOn(),
406         calorimeterRegCuts, eventCountPolicy,
407         particleGun->GetParticleDefinition()->GetParticleName(),
408         particleGun->GetOrigPosition(), particleGun->GetOrigDirection(),
409         particleGun->GetOrigMomentumAmp(),
410         primaryGeneratorAction->GetFwhmPosX(),
411         primaryGeneratorAction->GetFwhmPosY(),
412         primaryGeneratorAction->GetFwhmDirX(),
413         primaryGeneratorAction->GetFwhmDirY(),
414         primaryGeneratorAction->GetFwhmMomentumAmp(),
415         edDigitizer->GetMonitorThreshold(),
416         edDigitizer->GetVetoCounterLeftThreshold(),
417         edDigitizer->GetVetoCounterRightThreshold(),
418         edDigitizer->GetCalorimeterLeftThreshold(),
419         edDigitizer->GetCalorimeterRightThreshold(),
420         edDigitizer->GetCalorimeterTriggerAlgorithm(),
421         edDigitizer->GetOuterCrystalsVetoAlgorithm(),
422         edDigitizer->GetOuterCrystalsVetoFraction(),
423         edDigitizer->IsFiniteCrystalResolutionApplied(),
424         edDigitizer->GetCrystalResolutionData(),
425         reconstructor->GetCalorimeterEntryPointDefinitionAlgorithm(),
426         reconstructor->GetCalorimeterEntryPointDepthDefinitionAlgorithm(),
427         reconstructor->GetCrystalSelectionAlgorithm(),
428         reconstructor->IsInnerRefCrystalUsed(),
429         reconstructor->GetCalorimeterEntryPointDepth(),
430         reconstructor->IsTableMassUsed(), reconstructor->IsMassCutUsed(),
431         reconstructor->GetMassCutOPCenter(),
432         reconstructor->GetMassCutNOPCenter(),
433         reconstructor->GetMassCutOPWidth(), reconstructor->GetMassCutNOPWidth(),
434         reconstructor->GetMassCutEllipseAngle(),
435         reconstructor->IsAbsorbedEnergyCutUsed(),
436         reconstructor->GetAbsorbedEnergyCutCLCenter(),
437         reconstructor->GetAbsorbedEnergyCutCRCenter(),
438         reconstructor->GetAbsorbedEnergyCutCLWidth(),
439         reconstructor->GetAbsorbedEnergyCutCRWidth(),
440         reconstructor->GetAbsorbedEnergyCutEllipseAngle(),
441         nmbOfHitsSampled, nmbOfHitsSampledFull, nmbOfHitsTriggeredRealRange,
442         nmbOfHitsTriggeredRecRange, nmbOfOrphanHits, nmbOfFalseHitsTriggeredEDT,
443         nmbOfFalseHitsTriggeredRec, nmbOfSavedEvents, nmbOfSavedFastEvents,
444         numberOfEventsProcessed, numberOfEventsProcessedEffective,
445         numberOfEventToBeProcessed, rProject, skipInteractionsWithoutEDTonWrite,
446         cfFileName, evDataVerboseLevel, physicsManager->GetProposedMaxIL(),
447         reconstructor->GetExpectedMomentumAmp(),
448         reconstructor->GetEDCollectionAlgorithm(), 0 };
449 
450     std::ofstream   runDataFile( ( projectsDir + "/" + projectId + ".rdb" ).
451                                         c_str() );
452 
453     {
454         boost::archive::binary_oarchive  archive( runDataFile );
455         archive << sObjectToWrite;
456     }
457 }
458 
459 #endif
460 
461 
462 void  CexmcRunManager::DoCommonEventLoop( G4int  nEvent, const G4String &  cmd,
463                                           G4int  nSelect )
464 {
465     G4int  iEvent( 0 );
466     G4int  iEventEffective( 0 );
467 
468     for ( iEvent = 0; iEventEffective < nEvent; ++iEvent )
469     {
470         currentEvent = GenerateEvent( iEvent );
471         eventManager->ProcessOneEvent( currentEvent );
472         CexmcEventInfo *  eventInfo( static_cast< CexmcEventInfo * >(
473                                         currentEvent->GetUserInformation() ) );
474         switch ( eventCountPolicy )
475         {
476         case CexmcCountAllEvents :
477             ++iEventEffective;
478             break;
479         case CexmcCountEventsWithInteraction :
480             if ( eventInfo->TpTriggerIsOk() )
481                 ++iEventEffective;
482             break;
483         case CexmcCountEventsWithTrigger :
484             if ( eventInfo->EdTriggerIsOk() )
485                 ++iEventEffective;
486             break;
487         default :
488             ++iEventEffective;
489             break;
490         }
491         AnalyzeEvent( currentEvent );
492         UpdateScoring();
493         if ( iEvent < nSelect )
494             G4UImanager::GetUIpointer()->ApplyCommand( cmd );
495         StackPreviousEvent( currentEvent );
496         currentEvent = 0;
497         if ( runAborted )
498             break;
499     }
500 
501     numberOfEventsProcessed = iEvent;
502     numberOfEventsProcessedEffective = iEventEffective;
503 }
504 
505 
506 #ifdef CEXMC_USE_PERSISTENCY
507 
508 void  CexmcRunManager::DoReadEventLoop( G4int  nEvent )
509 {
510     G4int  iEvent( 0 );
511     G4int  iEventEffective( 0 );
512     G4int  nEventCount( 0 );
513 
514     if ( ! ProjectIsRead() )
515         return;
516 
517     if ( ! physicsManager )
518         throw CexmcException( CexmcWeirdException );
519 
520     CexmcProductionModel *  productionModel(
521                                         physicsManager->GetProductionModel() );
522     if ( ! productionModel )
523         throw CexmcException( CexmcWeirdException );
524 
525     CexmcSetup *  setup( static_cast< CexmcSetup * >( userDetector ) );
526     if ( ! setup )
527         throw CexmcException( CexmcWeirdException );
528 
529     CexmcEventSObject      evSObject;
530     CexmcEventFastSObject  evFastSObject;
531 
532     /* read events data */
533     std::ifstream   eventsDataFile(
534                         ( projectsDir + "/" + rProject + ".edb" ).c_str() );
535     if ( ! eventsDataFile )
536         throw CexmcException( CexmcReadProjectIncomplete );
537 
538     boost::archive::binary_iarchive  evArchive( eventsDataFile );
539 
540     std::ifstream   eventsFastDataFile(
541                         ( projectsDir + "/" + rProject + ".fdb" ).c_str() );
542     if ( ! eventsFastDataFile )
543         throw CexmcException( CexmcReadProjectIncomplete );
544 
545     boost::archive::binary_iarchive  evFastArchive( eventsFastDataFile );
546 
547     G4Event  event;
548     currentEvent = &event;
549     G4SDManager *      sdManager( G4SDManager::GetSDMpointer() );
550     event.SetHCofThisEvent( sdManager->PrepareNewEvent() );
551     G4HCofThisEvent *  hcOfThisEvent( event.GetHCofThisEvent() );
552 
553     G4DigiManager *  digiManager( G4DigiManager::GetDMpointer() );
554 
555     G4int  hcId( digiManager->GetHitsCollectionID(
556                         CexmcDetectorRoleName[ CexmcMonitorDetectorRole ] +
557                         "/" + CexmcDetectorTypeName[ CexmcEDDetector ] ) );
558     CexmcEnergyDepositCollection *  monitorED(
559                                             new CexmcEnergyDepositCollection );
560     hcOfThisEvent->AddHitsCollection( hcId, monitorED );
561     hcId = digiManager->GetHitsCollectionID(
562                         CexmcDetectorRoleName[ CexmcVetoCounterDetectorRole ] +
563                         "/" + CexmcDetectorTypeName[ CexmcEDDetector ] );
564     CexmcEnergyDepositCollection *  vetoCounterED(
565                                             new CexmcEnergyDepositCollection );
566     hcOfThisEvent->AddHitsCollection( hcId, vetoCounterED );
567     hcId = digiManager->GetHitsCollectionID(
568                         CexmcDetectorRoleName[ CexmcCalorimeterDetectorRole ] +
569                         "/" + CexmcDetectorTypeName[ CexmcEDDetector ] );
570     CexmcEnergyDepositCollection *  calorimeterED(
571                                             new CexmcEnergyDepositCollection );
572     hcOfThisEvent->AddHitsCollection( hcId, calorimeterED );
573     hcId = digiManager->GetHitsCollectionID(
574                         CexmcDetectorRoleName[ CexmcMonitorDetectorRole ] +
575                         "/" + CexmcDetectorTypeName[ CexmcTPDetector ] );
576     CexmcTrackPointsCollection *  monitorTP( new CexmcTrackPointsCollection );
577     hcOfThisEvent->AddHitsCollection( hcId, monitorTP );
578     hcId = digiManager->GetHitsCollectionID(
579                         CexmcDetectorRoleName[ CexmcVetoCounterDetectorRole ] +
580                         "/" + CexmcDetectorTypeName[ CexmcTPDetector ] );
581     CexmcTrackPointsCollection *  vetoCounterTP(
582                                             new CexmcTrackPointsCollection );
583     hcOfThisEvent->AddHitsCollection( hcId, vetoCounterTP );
584     hcId = digiManager->GetHitsCollectionID(
585                         CexmcDetectorRoleName[ CexmcCalorimeterDetectorRole ] +
586                         "/" + CexmcDetectorTypeName[ CexmcTPDetector ] );
587     CexmcTrackPointsCollection *  calorimeterTP(
588                                             new CexmcTrackPointsCollection );
589     hcOfThisEvent->AddHitsCollection( hcId, calorimeterTP );
590     hcId = digiManager->GetHitsCollectionID(
591                         CexmcDetectorRoleName[ CexmcTargetDetectorRole ] +
592                         "/" + CexmcDetectorTypeName[ CexmcTPDetector ] );
593     CexmcTrackPointsCollection *  targetTP( new CexmcTrackPointsCollection );
594     hcOfThisEvent->AddHitsCollection( hcId, targetTP );
595 
596 #ifdef CEXMC_USE_CUSTOM_FILTER
597     if ( customFilter )
598         customFilter->SetAddressedData( &evFastSObject, &evSObject );
599 #endif
600 
601     G4int   nmbOfSavedEvents( rEvDataVerboseLevel == CexmcWriteNoEventData ? 0 :
602                              sObject.nmbOfSavedFastEvents );
603     G4bool  eventDataWrittenOnEveryTPT( rEvDataVerboseLevel ==
604                                         CexmcWriteEventDataOnEveryTPT );
605 
606     for ( int  i( 0 ); i < nmbOfSavedEvents; ++i )
607     {
608         evFastArchive >> evFastSObject;
609 
610         if ( nEventCount < curEventRead )
611         {
612             if ( eventDataWrittenOnEveryTPT ||
613                  evFastSObject.edDigitizerHasTriggered )
614             {
615                 evArchive >> evSObject;
616                 if ( evFastSObject.edDigitizerHasTriggered )
617                     ++nEventCount;
618             }
619             continue;
620         }
621 
622         ++iEvent;
623 
624         productionModel->SetTriggeredAngularRanges(
625                                                 evFastSObject.opCosThetaSCM );
626         const CexmcAngularRangeList &  triggeredAngularRanges(
627                                 productionModel->GetTriggeredAngularRanges() );
628 
629         if ( ! eventDataWrittenOnEveryTPT &&
630              ! evFastSObject.edDigitizerHasTriggered )
631         {
632 #ifdef CEXMC_USE_CUSTOM_FILTER
633             /* user must be aware that using tpt commands in custom filter
634              * scripts for poor event data sets can easily lead to logical
635              * errors! This is because most of tpt data is only available for
636              * events with EDT trigger. There is no such problem if event data
637              * was written on every TPT event. */
638             if ( customFilter && ! customFilter->EvalTPT() )
639                 continue;
640 #endif
641             SaveCurrentTPTEvent( evFastSObject, triggeredAngularRanges,
642                      ProjectIsSaved() && ! skipInteractionsWithoutEDTonWrite );
643             continue;
644         }
645 
646         evArchive >> evSObject;
647 
648         G4bool  skipEDTOnThisEvent( false );
649 
650 #ifdef CEXMC_USE_CUSTOM_FILTER
651         if ( customFilter && ! customFilter->EvalTPT() )
652             continue;
653         if ( customFilter && ! customFilter->EvalEDT() )
654         {
655             if ( ! eventDataWrittenOnEveryTPT )
656             {
657                 SaveCurrentTPTEvent( evFastSObject, triggeredAngularRanges,
658                                      ProjectIsSaved() );
659                 continue;
660             }
661             skipEDTOnThisEvent = true;
662         }
663 #endif
664 
665         event.SetEventID( evSObject.eventId );
666 
667         /* AAA: beware! If something throws an exception between AAA and CCC
668          * then there would be segmentation violation in ~THitsMap() as it
669          * would try to delete local variable evSObject's fields.
670          * See also BBB */
671 
672         monitorED->GetMap()->operator[]( 0 ) = &evSObject.monitorED;
673         vetoCounterED->GetMap()->operator[]( 0 ) = &evSObject.vetoCounterEDLeft;
674         vetoCounterED->GetMap()->operator[]( 1 <<
675                 CexmcEnergyDepositInLeftRightSet::GetLeftRightBitsOffset() ) =
676                                                 &evSObject.vetoCounterEDRight;
677         G4int  row( 0 );
678         G4int  column( 0 );
679         for ( CexmcEnergyDepositCalorimeterCollection::iterator
680                 k( evSObject.calorimeterEDLeftCollection.begin() );
681                     k != evSObject.calorimeterEDLeftCollection.end(); ++k )
682         {
683             G4int  index( row <<
684                 CexmcEnergyDepositInCalorimeter::GetCopyDepth1BitsOffset() );
685             column = 0;
686             for ( CexmcEnergyDepositCrystalRowCollection::iterator
687                     l( k->begin() ); l != k->end(); ++l )
688             {
689                 calorimeterED->GetMap()->operator[]( index | column ) = &*l;
690                 ++column;
691             }
692             ++row;
693         }
694         row = 0;
695         for ( CexmcEnergyDepositCalorimeterCollection::iterator
696                 k( evSObject.calorimeterEDRightCollection.begin() );
697                     k != evSObject.calorimeterEDRightCollection.end(); ++k )
698         {
699             G4int  index(
700                 1 << CexmcEnergyDepositInLeftRightSet::GetLeftRightBitsOffset()
701                 | row <<
702                 CexmcEnergyDepositInCalorimeter::GetCopyDepth1BitsOffset() );
703             column = 0;
704             for ( CexmcEnergyDepositCrystalRowCollection::iterator
705                     l( k->begin() ); l != k->end(); ++l )
706             {
707                 calorimeterED->GetMap()->operator[]( index | column ) = &*l;
708                 ++column;
709             }
710             ++row;
711         }
712 
713         CexmcTrackPointInfo  monitorTPInfo( evSObject.monitorTP );
714         CexmcTrackPointInfo  targetTPBeamParticleInfo(
715                                         evSObject.targetTPBeamParticle );
716         CexmcTrackPointInfo  targetTPOutputParticleInfo(
717                                         evSObject.targetTPOutputParticle );
718         CexmcTrackPointInfo  targetTPNucleusParticleInfo(
719                                         evSObject.targetTPNucleusParticle );
720         CexmcTrackPointInfo  targetTPOutputParticleDecayProductParticle1Info(
721                         evSObject.targetTPOutputParticleDecayProductParticle1 );
722         CexmcTrackPointInfo  targetTPOutputParticleDecayProductParticle2Info(
723                         evSObject.targetTPOutputParticleDecayProductParticle2 );
724         CexmcTrackPointInfo  vetoCounterTPLeftInfo(
725                                                 evSObject.vetoCounterTPLeft );
726         CexmcTrackPointInfo  vetoCounterTPRightInfo(
727                                                 evSObject.vetoCounterTPRight );
728         CexmcTrackPointInfo  calorimeterTPLeftInfo(
729                                                 evSObject.calorimeterTPLeft );
730         CexmcTrackPointInfo  calorimeterTPRightInfo(
731                                                 evSObject.calorimeterTPRight );
732 
733         if ( monitorTPInfo.IsValid() )
734             monitorTP->GetMap()->operator[]( monitorTPInfo.trackId ) =
735                                                 &monitorTPInfo;
736         if ( targetTPBeamParticleInfo.IsValid() )
737             targetTP->GetMap()->operator[](
738                     targetTPBeamParticleInfo.trackId ) =
739                                                 &targetTPBeamParticleInfo;
740         if ( targetTPOutputParticleInfo.IsValid() )
741             targetTP->GetMap()->operator[](
742                     targetTPOutputParticleInfo.trackId ) =
743                                                 &targetTPOutputParticleInfo;
744         if ( targetTPNucleusParticleInfo.IsValid() )
745             targetTP->GetMap()->operator[](
746                     targetTPNucleusParticleInfo.trackId ) =
747                                                 &targetTPNucleusParticleInfo;
748         if ( targetTPOutputParticleDecayProductParticle1Info.IsValid() )
749             targetTP->GetMap()->operator[](
750                     targetTPOutputParticleDecayProductParticle1Info.trackId ) =
751                             &targetTPOutputParticleDecayProductParticle1Info;
752         if ( targetTPOutputParticleDecayProductParticle2Info.IsValid() )
753             targetTP->GetMap()->operator[](
754                     targetTPOutputParticleDecayProductParticle2Info.trackId ) =
755                             &targetTPOutputParticleDecayProductParticle2Info;
756         if ( vetoCounterTPLeftInfo.IsValid() )
757             vetoCounterTP->GetMap()->operator[](
758                     vetoCounterTPLeftInfo.trackId ) = &vetoCounterTPLeftInfo;
759         if ( vetoCounterTPRightInfo.IsValid() )
760             vetoCounterTP->GetMap()->operator[](
761                 1 << CexmcTrackPointsInLeftRightSet::GetLeftRightBitsOffset() |
762                     vetoCounterTPRightInfo.trackId ) = &vetoCounterTPRightInfo;
763 
764         G4ThreeVector  pos;
765         if ( calorimeterTPLeftInfo.IsValid() )
766         {
767             pos = calorimeterTPLeftInfo.positionLocal;
768             setup->ConvertToCrystalGeometry(
769                     calorimeterTPLeftInfo.positionLocal, row, column, pos );
770             calorimeterTPLeftInfo.positionLocal = pos;
771             calorimeterTP->GetMap()->operator[](
772                 row << CexmcTrackPointsInCalorimeter::
773                                                 GetCopyDepth1BitsOffset() |
774                 column << CexmcTrackPointsInCalorimeter::
775                                                 GetCopyDepth0BitsOffset() |
776                 calorimeterTPLeftInfo.trackId ) = &calorimeterTPLeftInfo;
777         }
778         if ( calorimeterTPRightInfo.IsValid() )
779         {
780             pos = calorimeterTPRightInfo.positionLocal;
781             setup->ConvertToCrystalGeometry(
782                     calorimeterTPRightInfo.positionLocal, row, column, pos );
783             calorimeterTPRightInfo.positionLocal = pos;
784             calorimeterTP->GetMap()->operator[](
785                 1 << CexmcTrackPointsInLeftRightSet::GetLeftRightBitsOffset() |
786                 row << CexmcTrackPointsInCalorimeter::
787                                                 GetCopyDepth1BitsOffset() |
788                 column << CexmcTrackPointsInCalorimeter::
789                                                 GetCopyDepth0BitsOffset() |
790                 calorimeterTPRightInfo.trackId ) = &calorimeterTPRightInfo;
791         }
792 
793         productionModel->SetProductionModelData(
794                                             evSObject.productionModelData );
795 
796         const CexmcEventAction *  eventAction(
797                 static_cast< const CexmcEventAction * >( userEventAction ) );
798         if ( ! eventAction )
799         {
800             /* BBB: all hits collections must be cleared before throwing
801              * anything from here, otherwise ~THitsMap() will try to delete
802              * local variable evSObject's fields like monitorED etc. */
803             monitorED->GetMap()->clear();
804             vetoCounterED->GetMap()->clear();
805             calorimeterED->GetMap()->clear();
806             monitorTP->GetMap()->clear();
807             targetTP->GetMap()->clear();
808             vetoCounterTP->GetMap()->clear();
809             calorimeterTP->GetMap()->clear();
810             throw CexmcException( CexmcEventActionIsNotInitialized );
811         }
812 
813         if ( skipEDTOnThisEvent )
814             event.SetUserInformation( new CexmcEventInfo( false, false,
815                                                           false ) );
816 
817         CexmcEventAction *  theEventAction( const_cast< CexmcEventAction * >(
818                                                                 eventAction ) );
819         theEventAction->EndOfEventAction( &event );
820 
821         CexmcEventInfo *  eventInfo( static_cast< CexmcEventInfo * >(
822                                                 event.GetUserInformation() ) );
823 
824         if ( eventInfo->EdTriggerIsOk() )
825             ++iEventEffective;
826 
827         delete eventInfo;
828         event.SetUserInformation( NULL );
829 
830         monitorED->GetMap()->clear();
831         vetoCounterED->GetMap()->clear();
832         calorimeterED->GetMap()->clear();
833         monitorTP->GetMap()->clear();
834         targetTP->GetMap()->clear();
835         vetoCounterTP->GetMap()->clear();
836         calorimeterTP->GetMap()->clear();
837 
838         /* CCC: see AAA */
839 
840         if ( nEvent > 0 && iEventEffective == nEvent )
841             break;
842     }
843 
844     curEventRead = nEventCount + iEventEffective;
845 
846     numberOfEventsProcessed = iEvent;
847     numberOfEventsProcessedEffective = iEventEffective;
848 
849 #ifdef CEXMC_USE_CUSTOM_FILTER
850     if ( customFilter )
851         customFilter->SetAddressedData( NULL, NULL );
852 #endif
853 }
854 
855 
856 void  CexmcRunManager::SaveCurrentTPTEvent(
857                                 const CexmcEventFastSObject &  evFastSObject,
858                                 const CexmcAngularRangeList &  angularRanges,
859                                 G4bool  writeToDatabase )
860 {
861     CexmcRun *  run( static_cast< CexmcRun * >( currentRun ) );
862 
863     if ( ! run )
864         return;
865 
866     for ( CexmcAngularRangeList::const_iterator  k( angularRanges.begin() );
867                                                 k != angularRanges.end(); ++k )
868     {
869         run->IncrementNmbOfHitsSampledFull( k->index );
870         if ( evFastSObject.edDigitizerMonitorHasTriggered )
871             run->IncrementNmbOfHitsSampled( k->index );
872     }
873 
874     if ( writeToDatabase )
875     {
876         fastEventsArchive->operator<<( evFastSObject );
877         run->IncrementNmbOfSavedFastEvents();
878     }
879 }
880 
881 #endif
882 
883 
884 /* mostly adopted from G4RunManager::DoEventLoop() */
885 void  CexmcRunManager::DoEventLoop( G4int  nEvent, const char *  macroFile,
886                                     G4int  nSelect )
887 {
888     if ( verboseLevel > 0 ) 
889         timer->Start();
890 
891     G4String  cmd;
892     if ( macroFile != 0 )
893     {
894         if ( nSelect < 0 )
895             nSelect = nEvent;
896         cmd = "/control/execute ";
897         cmd += macroFile;
898     }
899     else
900     {
901         nSelect = -1;
902     }
903 
904     numberOfEventsProcessed = 0;
905     numberOfEventsProcessedEffective = 0;
906 
907 #ifdef CEXMC_USE_PERSISTENCY
908     eventsArchive = NULL;
909     fastEventsArchive = NULL;
910     if ( ProjectIsRead() )
911     {
912         if ( ProjectIsSaved() )
913         {
914             std::ofstream   eventsDataFile(
915                         ( projectsDir + "/" + projectId + ".edb" ).c_str() );
916             boost::archive::binary_oarchive  eventsArchive_( eventsDataFile );
917             std::ofstream   fastEventsDataFile(
918                         ( projectsDir + "/" + projectId + ".fdb" ).c_str() );
919             boost::archive::binary_oarchive  fastEventsArchive_(
920                                                         fastEventsDataFile );
921             eventsArchive = &eventsArchive_;
922             fastEventsArchive = &fastEventsArchive_;
923             DoReadEventLoop( nEvent );
924         }
925         else
926         {
927             DoReadEventLoop( nEvent );
928         }
929     }
930     else
931     {
932         if ( ProjectIsSaved() )
933         {
934             std::ofstream   eventsDataFile(
935                         ( projectsDir + "/" + projectId + ".edb" ).c_str() );
936             boost::archive::binary_oarchive  eventsArchive_( eventsDataFile );
937             std::ofstream   fastEventsDataFile(
938                         ( projectsDir + "/" + projectId + ".fdb" ).c_str() );
939             boost::archive::binary_oarchive  fastEventsArchive_(
940                                                         fastEventsDataFile );
941             eventsArchive = &eventsArchive_;
942             fastEventsArchive = &fastEventsArchive_;
943             DoCommonEventLoop( nEvent, cmd, nSelect );
944         }
945         else
946         {
947             DoCommonEventLoop( nEvent, cmd, nSelect );
948         }
949     }
950     eventsArchive = NULL;
951     fastEventsArchive = NULL;
952 #else
953     DoCommonEventLoop( nEvent, cmd, nSelect );
954 #endif
955 
956     if ( verboseLevel > 0 )
957     {
958         timer->Stop();
959         G4cout << "Run terminated." << G4endl;
960         G4cout << "Run Summary" << G4endl;
961         if ( runAborted )
962         {
963             G4cout << "  Run Aborted after " << numberOfEventsProcessed <<
964                       " events processed." << G4endl;
965         }
966         else
967         {
968             G4cout << "  Number of events processed : " <<
969                       numberOfEventsProcessed << ", effectively: " <<
970                       numberOfEventsProcessedEffective << G4endl;
971         }
972         G4cout << "  "  << *timer << G4endl;
973     }
974 }
975 
976 
977 #ifdef CEXMC_USE_PERSISTENCY
978 
979 void  CexmcRunManager::PrintReadRunData( void ) const
980 {
981     if ( ! ProjectIsRead() )
982         return;
983 
984     G4bool  refCrystalInfoPrinted( false );
985 
986     G4cout << CEXMC_LINE_START << "Run data read from project '" << rProject <<
987               "'" << G4endl;
988     G4cout << "               (archive class version " <<
989               sObject.actualVersion << ")" << G4endl;
990     if ( ! sObject.rProject.empty() )
991     {
992         G4cout << "  -- Based on project '" << sObject.rProject << "'" <<
993                   G4endl;
994         if ( ! sObject.cfFileName.empty() )
995             G4cout << "  -- Custom filter script '" << sObject.cfFileName <<
996                       "' was used" << G4endl;
997     }
998     G4cout << "  -- Event data verbose level (0 - not saved, 1 - triggers, "
999               "2 - interactions): " << sObject.evDataVerboseLevel << G4endl;
1000     if ( ! sObject.rProject.empty() )
1001     {
1002         if ( sObject.evDataVerboseLevel == CexmcWriteEventDataOnEveryEDT )
1003         {
1004             G4cout << "  -- (fdb file contains " <<
1005                       ( sObject.interactionsWithoutEDTWereSkipped ?
1006                         "only interactions when an event was triggered" :
1007                         "all interactions" ) << ")" << std::endl;
1008         }
1009     }
1010     G4cout << "  -- Base physics used"
1011               "(1 - QGSP_BERT, 2 - QGSP_BIC_EMY, 3 - FTFP_BERT): " <<
1012               sObject.basePhysicsUsed << G4endl;
1013     G4cout << "  -- Production model (1 - pi0, 2 - eta): " <<
1014               sObject.productionModelType << G4endl;
1015     G4cout << "  -- Geometry definition file: " << sObject.gdmlFileName <<
1016               G4endl;
1017     G4cout << "  -- Angular ranges: " << sObject.angularRanges << G4endl;
1018     G4cout << "  -- Eta decay modes: " << G4endl;
1019     G4Eta::Definition()->GetDecayTable()->DumpInfo();
1020     G4cout << "  -- Fermi motion status (0 - disabled, 1 - enabled): " <<
1021               sObject.fermiMotionIsOn << G4endl;
1022     if ( sObject.calorimeterRegCuts.size() < 4 )
1023         throw CexmcException( CexmcWeirdException );
1024     G4cout << "  -- Production cuts in calorimeter (gamma, e-, e+, p): " <<
1025               G4BestUnit( sObject.calorimeterRegCuts[ 0 ], "Length" ) << ", " <<
1026               G4BestUnit( sObject.calorimeterRegCuts[ 1 ], "Length" ) << ", " <<
1027               G4BestUnit( sObject.calorimeterRegCuts[ 2 ], "Length" ) << ", " <<
1028               G4BestUnit( sObject.calorimeterRegCuts[ 3 ], "Length" ) << G4endl;
1029     G4cout << "  -- Proposed max interaction length in the target: " << 
1030               G4BestUnit( sObject.proposedMaxIL, "Length" ) << G4endl;
1031     G4cout << "  -- Event count policy (0 - all, 1 - interaction, 2 - trigger)"
1032               ": " << sObject.eventCountPolicy << G4endl;
1033     G4cout << "  -- Number of events (processed / effective / ordered): " <<
1034               sObject.numberOfEventsProcessed << " / " <<
1035               sObject.numberOfEventsProcessedEffective << " / " <<
1036               sObject.numberOfEventsToBeProcessed << G4endl;
1037     G4cout << "  -- Incident beam particle: " << sObject.beamParticle << G4endl;
1038     G4cout << "                   position: " <<
1039               G4BestUnit( sObject.beamPos, "Length" ) << G4endl;
1040     G4cout << "                  direction: " <<
1041               G4ThreeVector( sObject.beamDir ) << G4endl;
1042     G4cout << "                   momentum: " <<
1043               G4BestUnit( sObject.beamMomentumAmp, "Energy" ) << G4endl;
1044     G4cout << "              momentum fwhm: " << sObject.beamFwhmMomentumAmp <<
1045               G4endl;
1046     G4cout << "               pos fwhm (x): " <<
1047               G4BestUnit( sObject.beamFwhmPosX, "Length" ) << G4endl;
1048     G4cout << "               pos fwhm (y): " <<
1049               G4BestUnit( sObject.beamFwhmPosY, "Length" ) << G4endl;
1050     G4cout << "               dir fwhm (x): " << sObject.beamFwhmDirX / deg <<
1051               " deg" << G4endl;
1052     G4cout << "               dir fwhm (y): " << sObject.beamFwhmDirY / deg <<
1053               " deg" << G4endl;
1054     G4cout << "  -- Monitor ED threshold: " <<
1055               G4BestUnit( sObject.monitorEDThreshold, "Energy" ) << G4endl;
1056     G4cout << "  -- Veto counter (l/r) ED threshold: " <<
1057               G4BestUnit( sObject.vetoCounterEDLeftThreshold, "Energy" ) <<
1058               " / " <<
1059               G4BestUnit( sObject.vetoCounterEDRightThreshold, "Energy" ) <<
1060               G4endl;
1061     G4cout << "  -- Calorimeter (l/r) ED threshold: " <<
1062               G4BestUnit( sObject.calorimeterEDLeftThreshold, "Energy" ) <<
1063               " / " <<
1064               G4BestUnit( sObject.calorimeterEDRightThreshold, "Energy" ) <<
1065               G4endl;
1066     G4cout << "  -- Calorimeter trigger algorithm (0 - all, 1 - inner): " <<
1067               sObject.calorimeterTriggerAlgorithm << G4endl;
1068     G4cout << "  -- Outer crystals veto algorithm "
1069               "(0 - none, 1 - max, 2 - fraction): " <<
1070               sObject.outerCrystalsVetoAlgorithm << G4endl;
1071     if ( sObject.outerCrystalsVetoAlgorithm ==
1072          CexmcFractionOfEDInOuterCrystalsVeto )
1073     {
1074         G4cout << "  -- Outer crystals veto fraction: " <<
1075                   sObject.outerCrystalsVetoFraction << G4endl;
1076     }
1077     G4cout << "  -- Finite crystal resolution applied (0 - no, 1 - yes): " <<
1078               sObject.applyFiniteCrystalResolution << G4endl;
1079     if ( sObject.applyFiniteCrystalResolution )
1080     {
1081         G4cout << "  -- Crystal resolution data: " <<
1082                   sObject.crystalResolutionData;
1083     }
1084     G4cout << "  -- Reconstructor settings: " << G4endl;
1085     if ( sObject.expectedMomentumAmp > 0 )
1086     {
1087         G4cout << "     -- expected momentum in the target: " <<
1088                   G4BestUnit( sObject.expectedMomentumAmp, "Energy" ) << G4endl;
1089     }
1090     G4cout << "     -- ed collection algorithm (0 - all, 1 - adjacent): " <<
1091               sObject.edCollectionAlgorithm << G4endl;
1092     if ( sObject.edCollectionAlgorithm == CexmcCollectEDInAdjacentCrystals )
1093     {
1094         G4cout <<
1095             "     -- inner crystal used as reference (0 - no, 1 - yes): " <<
1096             sObject.useInnerRefCrystal << G4endl;
1097         refCrystalInfoPrinted = true;
1098     }
1099     G4cout << "     -- entry point definition algorithm " << G4endl;
1100     G4cout << "        (0 - center of calorimeter, 1 - center of crystal with "
1101                        "max ED," << G4endl;
1102     G4cout << "         2 - linear, 3 - square): " <<
1103               sObject.epDefinitionAlgorithm << G4endl;
1104     G4cout << "     -- entry point depth definition algorithm "
1105                       "(0 - plain, 1 - sphere): " <<
1106                           sObject.epDepthDefinitionAlgorithm << G4endl;
1107     G4cout << "     -- entry point depth: " <<
1108               G4BestUnit( sObject.epDepth, "Length" ) << G4endl;
1109     if ( sObject.epDefinitionAlgorithm == CexmcEntryPointByLinearEDWeights ||
1110          sObject.epDefinitionAlgorithm == CexmcEntryPointBySqrtEDWeights )
1111     {
1112         G4cout <<
1113             "     -- crystal selection algorithm (0 - all, 1 - adjacent): " <<
1114             sObject.csAlgorithm << G4endl;
1115     }
1116     if ( ! refCrystalInfoPrinted &&
1117          ( sObject.epDefinitionAlgorithm ==
1118                                 CexmcEntryPointInTheCenterOfCrystalWithMaxED ||
1119          ( ( sObject.epDefinitionAlgorithm == CexmcEntryPointBySqrtEDWeights ||
1120              sObject.epDefinitionAlgorithm ==
1121                                         CexmcEntryPointByLinearEDWeights ) &&
1122                sObject.csAlgorithm == CexmcSelectAdjacentCrystals ) ) )
1123     {
1124         G4cout <<
1125             "     -- inner crystal used as reference (0 - no, 1 - yes): " <<
1126             sObject.useInnerRefCrystal << G4endl;
1127     }
1128     G4cout << "     -- table mass of output particle used "
1129                       "(0 - no, 1 - yes): " << sObject.useTableMass << G4endl;
1130     G4cout << "     -- mass cut is enabled (0 - no, 1 - yes): " <<
1131               sObject.useMassCut << G4endl;
1132     if ( sObject.useMassCut )
1133     {
1134         G4cout << "     -- mass cut output particle center: " <<
1135                   G4BestUnit( sObject.mCutOPCenter, "Energy" ) << G4endl;
1136         G4cout << "     -- mass cut nucleus output particle center: " <<
1137                   G4BestUnit( sObject.mCutNOPCenter, "Energy" ) << G4endl;
1138         G4cout << "     -- mass cut output particle width of the ellipse: " <<
1139                   G4BestUnit( sObject.mCutOPWidth, "Energy" ) << G4endl;
1140         G4cout << "     -- mass cut nucleus output particle width of the "
1141                           "ellipse: "
1142                << G4BestUnit( sObject.mCutNOPWidth, "Energy" ) << G4endl;
1143         G4cout << "     -- mass cut angle of the ellipse: " <<
1144                   sObject.mCutAngle / deg << " deg" << G4endl;
1145     }
1146     G4cout << "     -- absorbed energy cut is enabled (0 - no, 1 - yes): " <<
1147               sObject.useAbsorbedEnergyCut << G4endl;
1148     if ( sObject.useAbsorbedEnergyCut )
1149     {
1150         G4cout << "     -- absorbed energy cut left calorimeter center: " <<
1151                   G4BestUnit( sObject.aeCutCLCenter, "Energy" ) << G4endl;
1152         G4cout << "     -- absorbed energy cut right calorimeter center: " <<
1153                   G4BestUnit( sObject.aeCutCRCenter, "Energy" ) << G4endl;
1154         G4cout << "     -- absorbed energy cut left calorimeter width of the "
1155                           "ellipse: " <<
1156                   G4BestUnit( sObject.aeCutCLWidth, "Energy" ) << G4endl;
1157         G4cout << "     -- absorbed energy cut right calorimeter width of the "
1158                           "ellipse: "
1159                << G4BestUnit( sObject.aeCutCRWidth, "Energy" ) << G4endl;
1160         G4cout << "     -- absorbed energy cut angle of the ellipse: " <<
1161                   sObject.aeCutAngle / deg << " deg" << G4endl;
1162     }
1163     G4cout << G4endl;
1164     CexmcRunAction::PrintResults( sObject.nmbOfHitsSampled,
1165                                   sObject.nmbOfHitsSampledFull,
1166                                   sObject.nmbOfHitsTriggeredRealRange,
1167                                   sObject.nmbOfHitsTriggeredRecRange,
1168                                   sObject.nmbOfOrphanHits,
1169                                   sObject.angularRanges,
1170                                   sObject.nmbOfFalseHitsTriggeredEDT,
1171                                   sObject.nmbOfFalseHitsTriggeredRec );
1172     G4cout << G4endl;
1173 }
1174 
1175 
1176 void  CexmcRunManager::ReadAndPrintEventsData( void ) const
1177 {
1178     if ( ! ProjectIsRead() )
1179         return;
1180 
1181     CexmcEventSObject  evSObject;
1182 
1183     /* read events data */
1184     std::ifstream   eventsDataFile(
1185                         ( projectsDir + "/" + rProject + ".edb" ).c_str() );
1186     if ( ! eventsDataFile )
1187         throw CexmcException( CexmcReadProjectIncomplete );
1188 
1189     boost::archive::binary_iarchive  evArchive( eventsDataFile );
1190 
1191     for ( int  i( 0 ); i < sObject.nmbOfSavedEvents; ++i )
1192     {
1193         evArchive >> evSObject;
1194 
1195         if ( ! evSObject.edDigitizerMonitorHasTriggered )
1196             continue;
1197 
1198         CexmcEnergyDepositStore  edStore( evSObject.monitorED,
1199             evSObject.vetoCounterEDLeft, evSObject.vetoCounterEDRight,
1200             evSObject.calorimeterEDLeft, evSObject.calorimeterEDRight,
1201             0, 0, 0, 0, evSObject.calorimeterEDLeftCollection,
1202             evSObject.calorimeterEDRightCollection );
1203 
1204         CexmcTrackPointsStore    tpStore( evSObject.monitorTP,
1205             evSObject.targetTPBeamParticle, evSObject.targetTPOutputParticle,
1206             evSObject.targetTPNucleusParticle,
1207             evSObject.targetTPOutputParticleDecayProductParticle1,
1208             evSObject.targetTPOutputParticleDecayProductParticle2,
1209             evSObject.vetoCounterTPLeft, evSObject.vetoCounterTPRight,
1210             evSObject.calorimeterTPLeft, evSObject.calorimeterTPRight );
1211 
1212         const CexmcProductionModelData &  pmData(
1213                                             evSObject.productionModelData );
1214 
1215         G4cout << "Event " << evSObject.eventId << G4endl;
1216         CexmcEventAction::PrintTrackPoints( &tpStore );
1217         G4cout << " --- Production model data: " << pmData;
1218         CexmcEventAction::PrintEnergyDeposit( &edStore );
1219     }
1220 }
1221 
1222 
1223 void  CexmcRunManager::PrintReadData(
1224                             const CexmcOutputDataTypeSet &  outputData ) const
1225 {
1226     if ( ! ProjectIsRead() )
1227         return;
1228 
1229     G4bool  addSpace( false );
1230 
1231     CexmcOutputDataTypeSet::const_iterator  found(
1232                                     outputData.find( CexmcOutputGeometry ) );
1233     if ( found != outputData.end() )
1234     {
1235         G4String  cmd( G4String( "cat " ) + projectsDir + "/" + rProject +
1236                        gdmlFileExtension );
1237         if ( system( cmd ) != 0 )
1238             throw CexmcException( CexmcReadProjectIncomplete );
1239 
1240         if ( zipGdmlFile )
1241         {
1242             cmd = G4String( "bzip2 " ) + projectsDir + "/" + rProject +
1243                                                             gdmlFileExtension;
1244             if ( system( cmd ) != 0 )
1245                 throw CexmcException( CexmcFileCompressException );
1246         }
1247 
1248         addSpace = true;
1249     }
1250 
1251     found = outputData.find( CexmcOutputEvents );
1252     if ( found != outputData.end() )
1253     {
1254         if ( addSpace )
1255             G4cout << G4endl << G4endl;
1256 
1257         ReadAndPrintEventsData();
1258 
1259         addSpace = true;
1260     }
1261 
1262     found = outputData.find( CexmcOutputRun );
1263     if ( found != outputData.end() )
1264     {
1265         if ( addSpace )
1266             G4cout << G4endl << G4endl;
1267 
1268         G4DecayTable *  etaDecayTable( G4Eta::Definition()->GetDecayTable() );
1269         for ( CexmcDecayBranchesStore::const_iterator
1270                 k( sObject.etaDecayTable.GetDecayBranches().begin() );
1271                 k != sObject.etaDecayTable.GetDecayBranches().end(); ++k )
1272         {
1273             etaDecayTable->GetDecayChannel( k->first )->SetBR( k->second );
1274         }
1275 
1276         PrintReadRunData();
1277     }
1278 }
1279 
1280 
1281 #ifdef CEXMC_USE_CUSTOM_FILTER
1282 
1283 void  CexmcRunManager::SetCustomFilter( const G4String &  cfFileName_ )
1284 {
1285     if ( customFilter )
1286     {
1287         delete customFilter;
1288         customFilter = NULL;
1289     }
1290 
1291     if ( cfFileName_.empty() )
1292         return;
1293 
1294     /* should not get here */
1295     if ( ! ProjectIsRead() )
1296         throw CexmcException( CexmcCmdIsNotAllowed );
1297 
1298     cfFileName = cfFileName_;
1299 
1300     customFilter = new CexmcCustomFilterEval( cfFileName );
1301 }
1302 
1303 #endif
1304 
1305 #endif
1306 
1307 
1308 void  CexmcRunManager::RegisterScenePrimitives( void )
1309 {
1310     G4VisManager *  visManager( static_cast< G4VisManager * >(
1311                                     G4VVisManager::GetConcreteInstance() ) );
1312     if ( ! visManager )
1313         return;
1314 
1315     G4Scene *       curScene( visManager->GetCurrentScene() );
1316     if ( ! curScene )
1317         return;
1318 
1319     /* G4Scene declarations lack this kind of typedef */
1320 #if G4VERSION_NUMBER < 960
1321     typedef std::vector< G4VModel * >      MList;
1322 #else
1323     typedef std::vector< G4Scene::Model >  MList;
1324 #endif
1325     const MList &  mList( curScene->GetRunDurationModelList() );
1326 
1327     for ( MList::const_iterator  k( mList.begin() ); k != mList.end(); ++k )
1328     {
1329 #if G4VERSION_NUMBER < 960
1330         const G4String &  modelDesc( ( *k )->GetGlobalDescription() );
1331 #else
1332         const G4String &  modelDesc( k->fpModel->GetGlobalDescription() );
1333 #endif
1334         if ( modelDesc == CexmcScenePrimitivesDescription )
1335             return;
1336     }
1337 
1338     CexmcSetup *  setup( static_cast< CexmcSetup * >( userDetector ) );
1339     if ( ! setup )
1340         throw CexmcException( CexmcWeirdException );
1341 
1342     /* BEWARE: looks like G4Scene won't delete models from its lists upon
1343      * termination! Hence destructor of the new model won't be called */
1344     curScene->AddRunDurationModel( new CexmcScenePrimitives( setup ) );
1345 }
1346 
1347 
1348 void  CexmcRunManager::BeamParticleChangeHook( void )
1349 {
1350     const CexmcEventAction *  eventAction(
1351                 static_cast< const CexmcEventAction * >( userEventAction ) );
1352     if ( ! eventAction )
1353         throw CexmcException( CexmcWeirdException );
1354 
1355     CexmcEventAction *        theEventAction( const_cast< CexmcEventAction * >(
1356                                                                 eventAction ) );
1357     theEventAction->BeamParticleChangeHook();
1358 }
1359 
1360 
1361 void  CexmcRunManager::SetupConstructionHook( void )
1362 {
1363 #ifdef CEXMC_USE_PERSISTENCY
1364     /* save gdml file */
1365     G4String            cmd( "" );
1366     CexmcExceptionType  exceptionType( CexmcSystemException );
1367 
1368     if ( zipGdmlFile )
1369     {
1370         if ( ProjectIsRead() )
1371         {
1372             cmd = G4String( "bzip2 " ) + projectsDir + "/" + rProject +
1373                                                             gdmlFileExtension;
1374         }
1375         else
1376         {
1377             if ( ProjectIsSaved() )
1378                 cmd = G4String( "bzip2 -c " ) + gdmlFileName + " > " +
1379                         projectsDir + "/" + projectId + gdmlbz2FileExtension;
1380         }
1381         exceptionType = CexmcFileCompressException;
1382     }
1383     else
1384     {
1385         if ( ! ProjectIsRead() && ProjectIsSaved() )
1386             cmd = G4String( "cp " ) + gdmlFileName + " " + projectsDir + "/" +
1387                                                 projectId + gdmlFileExtension;
1388         /* else already saved in ReadPreinitProjectData() */
1389     }
1390 
1391     if ( ! cmd.empty() && system( cmd ) != 0 )
1392         throw CexmcException( exceptionType );
1393 #endif
1394 }
1395 
1396