Geant4  10.03
CexmcSetup.cc
Go to the documentation of this file.
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: CexmcSetup.cc
30  *
31  * Description: physical setup
32  *
33  * Version: 1.0
34  * Created: 10.10.2009 23:00:50
35  * Revision: none
36  * Compiler: gcc
37  *
38  * Author: Alexey Radkov (),
39  * Company: PNPI
40  *
41  * =============================================================================
42  */
43 
44 #include <G4GDMLParser.hh>
46 #include <G4SDManager.hh>
47 #include <G4LogicalVolume.hh>
48 #include <G4VPhysicalVolume.hh>
49 #include <G4PhysicalVolumeStore.hh>
50 #include <G4Box.hh>
51 #include <G4LogicalVolumeStore.hh>
52 #include <G4Region.hh>
53 #include <G4RegionStore.hh>
54 #include <G4ProductionCuts.hh>
55 #include <G4VUserPhysicsList.hh>
56 #include <G4SystemOfUnits.hh>
57 #include "CexmcSetup.hh"
58 #include "CexmcPrimitiveScorer.hh"
59 #include "CexmcTrackPoints.hh"
66 #include "CexmcRunManager.hh"
67 #include "CexmcPhysicsManager.hh"
68 #include "CexmcException.hh"
69 
70 
71 CexmcSetup::CexmcSetup( const G4String & gdmlFile, G4bool validateGDMLFile ) :
72  world( 0 ), gdmlFile( gdmlFile ), validateGDMLFile( validateGDMLFile ),
73  calorimeterRegionInitialized( false ),
74  calorimeterGeometryDataInitialized( false ), monitorVolume( NULL ),
75  vetoCounterVolume( NULL ), calorimeterVolume( NULL ), targetVolume( NULL ),
76  rightVetoCounter( NULL ), rightCalorimeter( NULL )
77 {
78 }
79 
80 
82 {
83  if ( world )
84  return world;
85 
86  G4GDMLParser gdmlParser;
87 
88  gdmlParser.Read( gdmlFile, validateGDMLFile );
89  world = gdmlParser.GetWorldVolume();
90 
91  SetupSpecialVolumes( gdmlParser );
92 
93  ReadTransforms( gdmlParser );
94 
96 
97  CexmcRunManager * runManager( static_cast< CexmcRunManager * >(
99 
100  runManager->SetupConstructionHook();
101 
102  const CexmcPhysicsManager * physicsManager(
103  dynamic_cast< const CexmcPhysicsManager * >(
104  runManager->GetUserPhysicsList() ) );
105 
106  if ( ! physicsManager )
108 
109  CexmcPhysicsManager * thePhysicsManager(
110  const_cast< CexmcPhysicsManager * >( physicsManager ) );
111  thePhysicsManager->SetupConstructionHook( this );
112 
113  return world;
114 }
115 
116 
118 {
120  { NULL };
122 
123  for ( std::vector< G4LogicalVolume * >::const_iterator
124  lvIter( lvs->begin() ); lvIter != lvs->end(); ++lvIter )
125  {
126  G4String volumeName( G4String( ( *lvIter )->GetName() ) );
128  *lvIter ) );
130 
131  for ( G4GDMLAuxListType::const_iterator pair( auxInfo.begin() );
132  pair != auxInfo.end(); ++pair )
133  {
134  CexmcPrimitiveScorer * scorer( NULL );
135  G4String detectorName( "uninitialized" );
136  do
137  {
138  if ( pair->type == "EnergyDepositDetector" )
139  {
140  do
141  {
142  if ( pair->value == "MonitorRole" )
143  {
144  AssertAndAsignDetectorRole( curDetectorRole,
146  scorer = new CexmcSimpleEnergyDeposit(
148  break;
149  }
150  if ( pair->value == "VetoCounterRole" )
151  {
152  AssertAndAsignDetectorRole( curDetectorRole,
156  this );
157  break;
158  }
159  if ( pair->value == "CalorimeterRole" )
160  {
161  AssertAndAsignDetectorRole( curDetectorRole,
163  scorer = new CexmcEnergyDepositInCalorimeter(
165  this );
166  break;
167  }
168  } while ( false );
169  detectorName = CexmcDetectorRoleName[ curDetectorRole ];
170  G4cout << CEXMC_LINE_START "ED Scorer of detector role '" <<
171  detectorName << "' in volume '" << volumeName <<
172  "'" << G4endl;
173  break;
174  }
175  if ( pair->type == "TrackPointsDetector" )
176  {
177  do
178  {
179  if ( pair->value == "MonitorRole" )
180  {
181  AssertAndAsignDetectorRole( curDetectorRole,
183  scorer = new CexmcTrackPoints(
185  break;
186  }
187  if ( pair->value == "VetoCounterRole" )
188  {
189  AssertAndAsignDetectorRole( curDetectorRole,
191  scorer = new CexmcTrackPointsInLeftRightSet(
193  this );
194  break;
195  }
196  if ( pair->value == "CalorimeterRole" )
197  {
198  AssertAndAsignDetectorRole( curDetectorRole,
200  scorer = new CexmcTrackPointsInCalorimeter(
202  this );
203  break;
204  }
205  if ( pair->value == "TargetRole" )
206  {
207  AssertAndAsignDetectorRole( curDetectorRole,
209  scorer = new CexmcTrackPoints(
211  break;
212  }
213  } while ( false );
214  detectorName = CexmcDetectorRoleName[ curDetectorRole ];
215  G4cout << CEXMC_LINE_START "TP Scorer of detector role '" <<
216  detectorName << "' in volume '" << volumeName <<
217  "'" << G4endl;
218  if ( scorer )
219  {
220  CexmcTrackPointsFilter * filter(
221  new CexmcTrackPointsFilter( "trackPoints" ) );
222  scorer->SetFilter( filter );
223  }
224  break;
225  }
226  if ( pair->type == "SensitiveRegion" )
227  {
228  do
229  {
230  if ( pair->value == "CalorimeterRegion" )
231  {
232  G4Region * region( NULL );
234  {
235  region = G4RegionStore::GetInstance()->
236  GetRegion( CexmcCalorimeterRegionName );
237  }
238  else
239  {
240  region = new G4Region(
242  G4ProductionCuts * cuts(
243  new G4ProductionCuts );
244  G4double defaultProductionCut( 1.0 * mm );
245  const G4VUserPhysicsList * physicsList(
247  GetUserPhysicsList() );
248  if ( physicsList )
249  defaultProductionCut =
250  physicsList->GetDefaultCutValue();
251  cuts->SetProductionCut( defaultProductionCut );
252  region->SetProductionCuts( cuts );
254  }
255  region->AddRootLogicalVolume( *lvIter );
256  break;
257  }
258  } while ( false );
259  G4cout << CEXMC_LINE_START "Sensitive Region for logical "
260  "volume '" << volumeName << "' registered" <<
261  G4endl;
262  break;
263  }
264  if ( pair->type == "SpecialVolume" )
265  {
266  do
267  {
268  if ( pair->value == "Monitor" )
269  {
270  monitorVolume = *lvIter;
271  G4cout << CEXMC_LINE_START "Monitor volume '";
272  break;
273  }
274  if ( pair->value == "VetoCounter" )
275  {
276  vetoCounterVolume = *lvIter;
277  G4cout << CEXMC_LINE_START "VetoCounter volume '";
278  break;
279  }
280  if ( pair->value == "Calorimeter" )
281  {
282  calorimeterVolume = *lvIter;
283  G4cout << CEXMC_LINE_START "Calorimeter volume '";
284  ReadCalorimeterGeometryData( *lvIter );
286  break;
287  }
288  if ( pair->value == "Target" )
289  {
290  targetVolume = *lvIter;
291  G4cout << CEXMC_LINE_START "Target volume '";
292  break;
293  }
294  } while ( false );
295  G4cout << volumeName << "' registered" << G4endl;
296  break;
297  }
298  }
299  while ( false );
300 
301  if ( scorer )
302  {
303  /* curDetectorRole must be intact when scorer is not NULL */
304  if ( ! detector[ curDetectorRole ] )
305  {
306  detector[ curDetectorRole ] =
307  new G4MultiFunctionalDetector( detectorName );
308  }
309  detector[ curDetectorRole ]->RegisterPrimitive( scorer );
310  /* now that scorer has initialized pointer to its detector, its
311  * messenger's path shall be properly initialized as well */
312  scorer->InitializeMessenger();
313  /* NB: logical volumes in GDML file may not have multiple
314  * detector roles: for example volume Monitor may have only one
315  * role MonitorRole. This restriction arises from that fact that
316  * a logical volume may contain only one sensitive detector. */
317  ( *lvIter )->SetSensitiveDetector(
318  detector[ curDetectorRole ] );
319  }
320  }
321  }
322 
325 
328 
329  for ( G4int i( 0 ); i < CexmcNumberOfDetectorRoles; ++i )
330  {
331  if ( detector[ i ] )
332  G4SDManager::GetSDMpointer()->AddNewDetector( detector[ i ] );
333  }
334 }
335 
336 
337 void CexmcSetup::ReadTransforms( const G4GDMLParser & gdmlParser )
338 {
339  G4ThreeVector position( gdmlParser.GetPosition( "TargetPos" ) );
340  G4ThreeVector rotation( gdmlParser.GetRotation( "TargetRot" ) );
341  G4RotationMatrix rm;
342 
343  RotateMatrix( rotation, rm );
346 
347  position = gdmlParser.GetPosition( "CalorimeterLeftPos" );
348  rotation = gdmlParser.GetRotation( "CalorimeterLeftRot" );
349  rm = G4RotationMatrix();
350  RotateMatrix( rotation, rm );
353 
354  position = gdmlParser.GetPosition( "CalorimeterRightPos" );
355  rotation = gdmlParser.GetRotation( "CalorimeterRightRot" );
356  rm = G4RotationMatrix();
357  RotateMatrix( rotation, rm );
360 }
361 
362 
364  const G4LogicalVolume * lVolume )
365 {
366  if ( lVolume->GetNoDaughters() == 0 )
368 
369  G4VPhysicalVolume * pVolume( lVolume->GetDaughter( 0 ) );
370  EAxis axis;
371  G4double width;
372  G4double offset;
373  G4bool consuming;
374 
375  if ( ! pVolume )
377 
378  if ( pVolume->IsReplicated() )
379  {
380  pVolume->GetReplicationData( axis,
382  width, offset, consuming );
383  }
384 
385  lVolume = pVolume->GetLogicalVolume();
386 
387  if ( lVolume->GetNoDaughters() == 0 )
389 
390  pVolume = lVolume->GetDaughter( 0 );
391 
392  if ( ! pVolume )
394 
395  if ( pVolume->IsReplicated() )
396  {
397  pVolume->GetReplicationData( axis, calorimeterGeometry.nCrystalsInRow,
398  width, offset, consuming );
399  }
400 
401  lVolume = pVolume->GetLogicalVolume();
402 
403  /* NB: this is not necessarily a crystal itself as far as crystals can be
404  * wrapped in paper and other materials, but this is what reconstructor and
405  * digitizers really need */
406  G4Box * crystalBox( dynamic_cast< G4Box * >( lVolume->GetSolid() ) );
407 
408  if ( ! crystalBox )
410 
411  calorimeterGeometry.crystalWidth = crystalBox->GetXHalfLength() * 2;
414 }
415 
416 
418  G4int & row, G4int & column, G4ThreeVector & dst ) const
419 {
420  G4int nCrystalsInColumn( calorimeterGeometry.nCrystalsInColumn );
421  G4int nCrystalsInRow( calorimeterGeometry.nCrystalsInRow );
422  G4double crystalWidth( calorimeterGeometry.crystalWidth );
423  G4double crystalHeight( calorimeterGeometry.crystalHeight );
424 
425  row = G4int( ( src.y() + crystalHeight * nCrystalsInColumn / 2 ) /
426  crystalHeight );
427  column = G4int( ( src.x() + crystalWidth * nCrystalsInRow / 2 ) /
428  crystalWidth );
429  G4double xInCalorimeterOffset(
430  ( G4double( column ) - G4double( nCrystalsInRow ) / 2 ) *
431  crystalWidth + crystalWidth / 2 );
432  G4double yInCalorimeterOffset(
433  ( G4double( row ) - G4double( nCrystalsInColumn ) / 2 ) *
434  crystalHeight + crystalHeight / 2 );
435  dst.setX( src.x() - xInCalorimeterOffset );
436  dst.setY( src.y() - yInCalorimeterOffset );
437 }
438 
439 
441 {
443 
444  for ( std::vector< G4VPhysicalVolume * >::const_iterator k( pvs->begin() );
445  k != pvs->end(); ++k )
446  {
447  /* FIXME: it would be more reasonable to find detectors from volumes
448  * tagged with 'EnergyDepositDetector' or 'TrackPointsDetector', and not
449  * from volumes tagged with 'SpecialVolume' as it is done here. However
450  * in case of calorimeters the role of detectors are played by crystal
451  * volumes, not the calorimeters themselves, but only calorimeters can
452  * hold information about their left or right positions! Thus, following
453  * considerations of convenience, right detectors for all detector roles
454  * are chosen from volumes tagged with 'SpecialVolume' */
455  do
456  {
457  if ( ( *k )->GetLogicalVolume() == vetoCounterVolume )
458  {
459  if ( ( *k )->GetName().contains( "Right" ) )
460  rightVetoCounter = *k;
461  break;
462  }
463  if ( ( *k )->GetLogicalVolume() == calorimeterVolume )
464  {
465  if ( ( *k )->GetName().contains( "Right" ) )
466  rightCalorimeter = *k;
467  break;
468  }
469  } while ( false );
470  }
471 }
472 
473 
475  CexmcDetectorRole value )
476 {
477  if ( detectorRole != CexmcNumberOfDetectorRoles && detectorRole != value )
479 
480  detectorRole = value;
481 }
482 
483 
485  G4RotationMatrix & rm )
486 {
487  rm.rotateX( rot.x() );
488  rm.rotateY( rot.y() );
489  rm.rotateZ( rot.z() );
490 }
491 
G4bool RegisterPrimitive(G4VPrimitiveScorer *)
G4VPhysicalVolume * rightVetoCounter
Definition: CexmcSetup.hh:147
G4double GetXHalfLength() const
static constexpr double mm
Definition: G4SIunits.hh:115
CLHEP::Hep3Vector G4ThreeVector
void AddRootLogicalVolume(G4LogicalVolume *lv)
Definition: G4Region.cc:290
CLHEP::HepRotation G4RotationMatrix
G4bool validateGDMLFile
Definition: CexmcSetup.hh:133
Definition: G4Box.hh:64
G4VPhysicalVolume * GetWorldVolume(const G4String &setupName="Default") const
void ConvertToCrystalGeometry(const G4ThreeVector &src, G4int &row, G4int &column, G4ThreeVector &dst) const
Definition: CexmcSetup.cc:417
void SetupConstructionHook(void)
void SetFilter(G4VSDFilter *f)
const G4String CexmcDetectorTypeName[CexmcNumberOfDetectorTypes]
G4VSolid * GetSolid() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
void SetupSpecialVolumes(const G4GDMLParser &gdmlParser)
Definition: CexmcSetup.cc:117
#define width
CalorimeterGeometryData calorimeterGeometry
Definition: CexmcSetup.hh:157
void SetProductionCut(G4double cut, G4int index=-1)
CexmcSetup(const G4String &gdmlFile="default.gdml", G4bool validateGDMLFile=true)
Definition: CexmcSetup.cc:71
G4GDMLAuxListType GetVolumeAuxiliaryInformation(G4LogicalVolume *lvol) const
int G4int
Definition: G4Types.hh:78
G4double GetZHalfLength() const
G4bool calorimeterGeometryDataInitialized
Definition: CexmcSetup.hh:137
G4AffineTransform calorimeterRightTransform
Definition: CexmcSetup.hh:155
G4VPhysicalVolume * rightCalorimeter
Definition: CexmcSetup.hh:149
static G4PhysicalVolumeStore * GetInstance()
static G4RegionStore * GetInstance()
static void RotateMatrix(const G4ThreeVector &pos, G4RotationMatrix &rm)
Definition: CexmcSetup.cc:484
#define position
Definition: xmlparse.cc:622
G4double GetDefaultCutValue() const
G4GLOB_DLL std::ostream G4cout
void SetNetTranslation(const G4ThreeVector &tlate)
void SetNetRotation(const G4RotationMatrix &rot)
#define CEXMC_LINE_START
Definition: CexmcCommon.hh:52
G4LogicalVolume * calorimeterVolume
Definition: CexmcSetup.hh:143
bool G4bool
Definition: G4Types.hh:79
G4AffineTransform calorimeterLeftTransform
Definition: CexmcSetup.hh:153
G4String gdmlFile
Definition: CexmcSetup.hh:131
static G4LogicalVolumeStore * GetInstance()
void ReadCalorimeterGeometryData(const G4LogicalVolume *lVolume)
Definition: CexmcSetup.cc:363
G4double GetYHalfLength() const
const G4String CexmcDetectorRoleName[CexmcNumberOfDetectorRoles]
void ReadRightDetectors(void)
Definition: CexmcSetup.cc:440
virtual void SetupConstructionHook(const CexmcSetup *setup)=0
G4LogicalVolume * monitorVolume
Definition: CexmcSetup.hh:139
G4int GetNoDaughters() const
void AddNewDetector(G4VSensitiveDetector *aSD)
Definition: G4SDManager.cc:71
static void AssertAndAsignDetectorRole(CexmcDetectorRole &detectorRole, CexmcDetectorRole value)
Definition: CexmcSetup.cc:474
G4ThreeVector GetRotation(const G4String &name) const
static G4RunManager * GetRunManager()
Definition: G4RunManager.cc:79
const G4String CexmcCalorimeterRegionName("Calorimeter")
std::vector< G4GDMLAuxStructType > G4GDMLAuxListType
EAxis
Definition: geomdefs.hh:54
G4bool calorimeterRegionInitialized
Definition: CexmcSetup.hh:135
static G4SDManager * GetSDMpointer()
Definition: G4SDManager.cc:40
void Read(const G4String &filename, G4bool Validate=true)
G4LogicalVolume * targetVolume
Definition: CexmcSetup.hh:145
void ReadTransforms(const G4GDMLParser &gdmlParser)
Definition: CexmcSetup.cc:337
#define G4endl
Definition: G4ios.hh:61
void SetProductionCuts(G4ProductionCuts *cut)
G4VPhysicalVolume * world
Definition: CexmcSetup.hh:129
G4VPhysicalVolume * Construct(void)
Definition: CexmcSetup.cc:81
double G4double
Definition: G4Types.hh:76
const G4VUserPhysicsList * GetUserPhysicsList() const
G4LogicalVolume * vetoCounterVolume
Definition: CexmcSetup.hh:141
G4AffineTransform targetTransform
Definition: CexmcSetup.hh:151
G4ThreeVector GetPosition(const G4String &name) const