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