Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/advanced/ChargeExchangeMC/src/CexmcSetup.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 ]

Diff markup

Differences between /examples/advanced/ChargeExchangeMC/src/CexmcSetup.cc (Version 11.3.0) and /examples/advanced/ChargeExchangeMC/src/CexmcSetup.cc (Version 9.6.p4)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 /*                                                 26 /*
 27  * ===========================================     27  * =============================================================================
 28  *                                                 28  *
 29  *       Filename:  CexmcSetup.cc                  29  *       Filename:  CexmcSetup.cc
 30  *                                                 30  *
 31  *    Description:  physical setup                 31  *    Description:  physical setup
 32  *                                                 32  *
 33  *        Version:  1.0                            33  *        Version:  1.0
 34  *        Created:  10.10.2009 23:00:50            34  *        Created:  10.10.2009 23:00:50
 35  *       Revision:  none                           35  *       Revision:  none
 36  *       Compiler:  gcc                            36  *       Compiler:  gcc
 37  *                                                 37  *
 38  *         Author:  Alexey Radkov (),              38  *         Author:  Alexey Radkov (), 
 39  *        Company:  PNPI                           39  *        Company:  PNPI
 40  *                                                 40  *
 41  * ===========================================     41  * =============================================================================
 42  */                                                42  */
 43                                                    43 
 44 #include <G4GDMLParser.hh>                         44 #include <G4GDMLParser.hh>
 45 #include <G4MultiFunctionalDetector.hh>            45 #include <G4MultiFunctionalDetector.hh>
 46 #include <G4SDManager.hh>                          46 #include <G4SDManager.hh>
 47 #include <G4LogicalVolume.hh>                      47 #include <G4LogicalVolume.hh>
 48 #include <G4VPhysicalVolume.hh>                    48 #include <G4VPhysicalVolume.hh>
 49 #include <G4PhysicalVolumeStore.hh>                49 #include <G4PhysicalVolumeStore.hh>
 50 #include <G4Box.hh>                                50 #include <G4Box.hh>
 51 #include <G4LogicalVolumeStore.hh>                 51 #include <G4LogicalVolumeStore.hh>
 52 #include <G4Region.hh>                             52 #include <G4Region.hh>
 53 #include <G4RegionStore.hh>                        53 #include <G4RegionStore.hh>
 54 #include <G4ProductionCuts.hh>                     54 #include <G4ProductionCuts.hh>
 55 #include <G4VUserPhysicsList.hh>                   55 #include <G4VUserPhysicsList.hh>
 56 #include <G4SystemOfUnits.hh>                  << 
 57 #include "CexmcSetup.hh"                           56 #include "CexmcSetup.hh"
 58 #include "CexmcPrimitiveScorer.hh"                 57 #include "CexmcPrimitiveScorer.hh"
 59 #include "CexmcTrackPoints.hh"                     58 #include "CexmcTrackPoints.hh"
 60 #include "CexmcTrackPointsInLeftRightSet.hh"       59 #include "CexmcTrackPointsInLeftRightSet.hh"
 61 #include "CexmcTrackPointsInCalorimeter.hh"        60 #include "CexmcTrackPointsInCalorimeter.hh"
 62 #include "CexmcTrackPointsFilter.hh"               61 #include "CexmcTrackPointsFilter.hh"
 63 #include "CexmcSimpleEnergyDeposit.hh"             62 #include "CexmcSimpleEnergyDeposit.hh"
 64 #include "CexmcEnergyDepositInLeftRightSet.hh"     63 #include "CexmcEnergyDepositInLeftRightSet.hh"
 65 #include "CexmcEnergyDepositInCalorimeter.hh"      64 #include "CexmcEnergyDepositInCalorimeter.hh"
 66 #include "CexmcRunManager.hh"                      65 #include "CexmcRunManager.hh"
 67 #include "CexmcPhysicsManager.hh"                  66 #include "CexmcPhysicsManager.hh"
 68 #include "CexmcException.hh"                       67 #include "CexmcException.hh"
 69                                                    68 
 70                                                    69 
 71 CexmcSetup::CexmcSetup( const G4String &  gdml <<  70 CexmcSetup::CexmcSetup( const G4String &  gdmlFile, G4bool  validateGDMLFile ) :
 72                         G4bool  validateGDMLFi <<  71     world( 0 ), gdmlFile( gdmlFile ), validateGDMLFile( validateGDMLFile ),
 73     world( 0 ), gdmlFile( gdmlFile_ ), validat << 
 74     calorimeterRegionInitialized( false ),         72     calorimeterRegionInitialized( false ),
 75     calorimeterGeometryDataInitialized( false      73     calorimeterGeometryDataInitialized( false ), monitorVolume( NULL ),
 76     vetoCounterVolume( NULL ), calorimeterVolu     74     vetoCounterVolume( NULL ), calorimeterVolume( NULL ), targetVolume( NULL ),
 77     rightVetoCounter( NULL ), rightCalorimeter     75     rightVetoCounter( NULL ), rightCalorimeter( NULL )
 78 {                                                  76 {
 79 }                                                  77 }
 80                                                    78 
 81                                                    79 
 82 G4VPhysicalVolume *  CexmcSetup::Construct( vo     80 G4VPhysicalVolume *  CexmcSetup::Construct( void )
 83 {                                                  81 {
 84     if ( world )                                   82     if ( world )
 85         return world;                              83         return world;
 86                                                    84 
 87     G4GDMLParser  gdmlParser;                      85     G4GDMLParser  gdmlParser;
 88                                                    86 
 89     gdmlParser.Read( gdmlFile, validateGDMLFil     87     gdmlParser.Read( gdmlFile, validateGDMLFile );
 90     world = gdmlParser.GetWorldVolume();           88     world = gdmlParser.GetWorldVolume();
 91                                                    89 
 92     SetupSpecialVolumes( gdmlParser );             90     SetupSpecialVolumes( gdmlParser );
 93                                                    91 
 94     ReadTransforms( gdmlParser );                  92     ReadTransforms( gdmlParser );
 95                                                    93 
 96     ReadRightDetectors();                          94     ReadRightDetectors();
 97                                                    95 
 98     CexmcRunManager *  runManager( static_cast     96     CexmcRunManager *  runManager( static_cast< CexmcRunManager * >(
 99                                             G4     97                                             G4RunManager::GetRunManager() ) );
100                                                    98 
101     runManager->SetupConstructionHook();           99     runManager->SetupConstructionHook();
102                                                   100 
103     const CexmcPhysicsManager *  physicsManage    101     const CexmcPhysicsManager *  physicsManager(
104             dynamic_cast< const CexmcPhysicsMa    102             dynamic_cast< const CexmcPhysicsManager * >(
105                                         runMan    103                                         runManager->GetUserPhysicsList() ) );
106                                                   104 
107     if ( ! physicsManager )                       105     if ( ! physicsManager )
108         throw CexmcException( CexmcWeirdExcept    106         throw CexmcException( CexmcWeirdException );
109                                                   107 
110     CexmcPhysicsManager *        thePhysicsMan    108     CexmcPhysicsManager *        thePhysicsManager(
111             const_cast< CexmcPhysicsManager *     109             const_cast< CexmcPhysicsManager * >( physicsManager ) );
112     thePhysicsManager->SetupConstructionHook(     110     thePhysicsManager->SetupConstructionHook( this );
113                                                   111 
114     return world;                                 112     return world;
115 }                                                 113 }
116                                                   114 
117                                                   115 
118 void  CexmcSetup::SetupSpecialVolumes( const G    116 void  CexmcSetup::SetupSpecialVolumes( const G4GDMLParser &  gdmlParser )
119 {                                                 117 {
120     G4MultiFunctionalDetector *   detector[ Ce    118     G4MultiFunctionalDetector *   detector[ CexmcNumberOfDetectorRoles ] =
121                                                   119                                                                     { NULL };
122     const G4LogicalVolumeStore *  lvs( G4Logic    120     const G4LogicalVolumeStore *  lvs( G4LogicalVolumeStore::GetInstance() );
123                                                   121 
124     for ( std::vector< G4LogicalVolume * >::co    122     for ( std::vector< G4LogicalVolume * >::const_iterator
125                         lvIter( lvs->begin() )    123                         lvIter( lvs->begin() ); lvIter != lvs->end(); ++lvIter )
126     {                                             124     {
127         G4String           volumeName( G4Strin    125         G4String           volumeName( G4String( ( *lvIter )->GetName() ) );
128         G4GDMLAuxListType  auxInfo( gdmlParser    126         G4GDMLAuxListType  auxInfo( gdmlParser.GetVolumeAuxiliaryInformation(
129                                                   127                                                                     *lvIter ) );
130         CexmcDetectorRole  curDetectorRole( Ce    128         CexmcDetectorRole  curDetectorRole( CexmcNumberOfDetectorRoles );
131                                                   129 
132         for ( G4GDMLAuxListType::const_iterato    130         for ( G4GDMLAuxListType::const_iterator  pair( auxInfo.begin() );
133                                                   131                                               pair != auxInfo.end(); ++pair )
134         {                                         132         {
135             CexmcPrimitiveScorer *  scorer( NU    133             CexmcPrimitiveScorer *  scorer( NULL );
136             G4String                detectorNa    134             G4String                detectorName( "uninitialized" );
137             do                                    135             do
138             {                                     136             {
139                 if ( pair->type == "EnergyDepo    137                 if ( pair->type == "EnergyDepositDetector" )
140                 {                                 138                 {
141                     do                            139                     do
142                     {                             140                     {
143                         if ( pair->value == "M    141                         if ( pair->value == "MonitorRole" )
144                         {                         142                         {
145                             AssertAndAsignDete    143                             AssertAndAsignDetectorRole( curDetectorRole,
146                                                   144                                                 CexmcMonitorDetectorRole );
147                             scorer = new Cexmc    145                             scorer = new CexmcSimpleEnergyDeposit(
148                                     CexmcDetec    146                                     CexmcDetectorTypeName[ CexmcEDDetector ] );
149                             break;                147                             break;
150                         }                         148                         }
151                         if ( pair->value == "V    149                         if ( pair->value == "VetoCounterRole" )
152                         {                         150                         {
153                             AssertAndAsignDete    151                             AssertAndAsignDetectorRole( curDetectorRole,
154                                                   152                                                 CexmcVetoCounterDetectorRole );
155                             scorer = new Cexmc    153                             scorer = new CexmcEnergyDepositInLeftRightSet(
156                                     CexmcDetec    154                                     CexmcDetectorTypeName[ CexmcEDDetector ],
157                                     this );       155                                     this );
158                             break;                156                             break;
159                         }                         157                         }
160                         if ( pair->value == "C    158                         if ( pair->value == "CalorimeterRole" )
161                         {                         159                         {
162                             AssertAndAsignDete    160                             AssertAndAsignDetectorRole( curDetectorRole,
163                                                   161                                                 CexmcCalorimeterDetectorRole );
164                             scorer = new Cexmc    162                             scorer = new CexmcEnergyDepositInCalorimeter(
165                                     CexmcDetec    163                                     CexmcDetectorTypeName[ CexmcEDDetector ],
166                                     this );       164                                     this );
167                             break;                165                             break;
168                         }                         166                         }
169                     } while ( false );            167                     } while ( false );
170                     detectorName = CexmcDetect    168                     detectorName = CexmcDetectorRoleName[ curDetectorRole ];
171                     G4cout << CEXMC_LINE_START    169                     G4cout << CEXMC_LINE_START "ED Scorer of detector role '" <<
172                                detectorName <<    170                                detectorName << "' in volume '" << volumeName <<
173                                "'" << G4endl;     171                                "'" << G4endl;
174                     break;                        172                     break;
175                 }                                 173                 }
176                 if ( pair->type == "TrackPoint    174                 if ( pair->type == "TrackPointsDetector" )
177                 {                                 175                 {
178                     do                            176                     do
179                     {                             177                     {
180                         if ( pair->value == "M    178                         if ( pair->value == "MonitorRole" )
181                         {                         179                         {
182                             AssertAndAsignDete    180                             AssertAndAsignDetectorRole( curDetectorRole,
183                                                   181                                                 CexmcMonitorDetectorRole );
184                             scorer = new Cexmc    182                             scorer = new CexmcTrackPoints(
185                                     CexmcDetec    183                                     CexmcDetectorTypeName[ CexmcTPDetector ] );
186                             break;                184                             break;
187                         }                         185                         }
188                         if ( pair->value == "V    186                         if ( pair->value == "VetoCounterRole"  )
189                         {                         187                         {
190                             AssertAndAsignDete    188                             AssertAndAsignDetectorRole( curDetectorRole,
191                                                   189                                                 CexmcVetoCounterDetectorRole );
192                             scorer = new Cexmc    190                             scorer = new CexmcTrackPointsInLeftRightSet(
193                                     CexmcDetec    191                                     CexmcDetectorTypeName[ CexmcTPDetector ],
194                                     this );       192                                     this );
195                             break;                193                             break;
196                         }                         194                         }
197                         if ( pair->value == "C    195                         if ( pair->value == "CalorimeterRole" )
198                         {                         196                         {
199                             AssertAndAsignDete    197                             AssertAndAsignDetectorRole( curDetectorRole,
200                                                   198                                                 CexmcCalorimeterDetectorRole );
201                             scorer = new Cexmc    199                             scorer = new CexmcTrackPointsInCalorimeter(
202                                     CexmcDetec    200                                     CexmcDetectorTypeName[ CexmcTPDetector ],
203                                     this );       201                                     this );
204                             break;                202                             break;
205                         }                         203                         }
206                         if ( pair->value == "T    204                         if ( pair->value == "TargetRole" )
207                         {                         205                         {
208                             AssertAndAsignDete    206                             AssertAndAsignDetectorRole( curDetectorRole,
209                                                   207                                                 CexmcTargetDetectorRole );
210                             scorer = new Cexmc    208                             scorer = new CexmcTrackPoints(
211                                     CexmcDetec    209                                     CexmcDetectorTypeName[ CexmcTPDetector ] );
212                             break;                210                             break;
213                         }                         211                         }
214                     } while ( false );            212                     } while ( false );
215                     detectorName = CexmcDetect    213                     detectorName = CexmcDetectorRoleName[ curDetectorRole ];
216                     G4cout << CEXMC_LINE_START    214                     G4cout << CEXMC_LINE_START "TP Scorer of detector role '" <<
217                                detectorName <<    215                                detectorName << "' in volume '" << volumeName <<
218                                "'" << G4endl;     216                                "'" << G4endl;
219                     if ( scorer )                 217                     if ( scorer )
220                     {                             218                     {
221                         CexmcTrackPointsFilter    219                         CexmcTrackPointsFilter *  filter(
222                                  new CexmcTrac    220                                  new CexmcTrackPointsFilter( "trackPoints" ) );
223                         scorer->SetFilter( fil    221                         scorer->SetFilter( filter );
224                     }                             222                     }
225                     break;                        223                     break;
226                 }                                 224                 }
227                 if ( pair->type == "SensitiveR    225                 if ( pair->type == "SensitiveRegion" )
228                 {                                 226                 {
229                     do                            227                     do
230                     {                             228                     {
231                         if ( pair->value == "C    229                         if ( pair->value == "CalorimeterRegion" )
232                         {                         230                         {
233                             G4Region *  region    231                             G4Region *  region( NULL );
234                             if ( calorimeterRe    232                             if ( calorimeterRegionInitialized )
235                             {                     233                             {
236                                 region = G4Reg    234                                 region = G4RegionStore::GetInstance()->
237                                         GetReg    235                                         GetRegion( CexmcCalorimeterRegionName );
238                             }                     236                             }
239                             else                  237                             else
240                             {                     238                             {
241                                 region = new G    239                                 region = new G4Region(
242                                                   240                                                 CexmcCalorimeterRegionName );
243                                 G4ProductionCu    241                                 G4ProductionCuts *  cuts(
244                                                   242                                                         new G4ProductionCuts );
245                                 G4double  defa    243                                 G4double  defaultProductionCut( 1.0 * mm );
246                                 const G4VUserP    244                                 const G4VUserPhysicsList *  physicsList(
247                                             G4    245                                             G4RunManager::GetRunManager()->
248                                                   246                                                         GetUserPhysicsList() );
249                                 if ( physicsLi    247                                 if ( physicsList )
250                                     defaultPro    248                                     defaultProductionCut =
251                                             ph    249                                             physicsList->GetDefaultCutValue();
252                                 cuts->SetProdu    250                                 cuts->SetProductionCut( defaultProductionCut );
253                                 region->SetPro    251                                 region->SetProductionCuts( cuts );
254                                 calorimeterReg    252                                 calorimeterRegionInitialized = true;
255                             }                     253                             }
256                             region->AddRootLog    254                             region->AddRootLogicalVolume( *lvIter );
257                             break;                255                             break;
258                         }                         256                         }
259                     } while ( false );            257                     } while ( false );
260                     G4cout << CEXMC_LINE_START    258                     G4cout << CEXMC_LINE_START "Sensitive Region for logical "
261                                "volume '" << v    259                                "volume '" << volumeName << "' registered" <<
262                                G4endl;            260                                G4endl;
263                     break;                        261                     break;
264                 }                                 262                 }
265                 if ( pair->type == "SpecialVol    263                 if ( pair->type == "SpecialVolume" )
266                 {                                 264                 {
267                     do                            265                     do
268                     {                             266                     {
269                         if ( pair->value == "M    267                         if ( pair->value == "Monitor" )
270                         {                         268                         {
271                             monitorVolume = *l    269                             monitorVolume = *lvIter;
272                             G4cout << CEXMC_LI    270                             G4cout << CEXMC_LINE_START "Monitor volume '";
273                             break;                271                             break;
274                         }                         272                         }
275                         if ( pair->value == "V    273                         if ( pair->value == "VetoCounter" )
276                         {                         274                         {
277                             vetoCounterVolume     275                             vetoCounterVolume = *lvIter;
278                             G4cout << CEXMC_LI    276                             G4cout << CEXMC_LINE_START "VetoCounter volume '";
279                             break;                277                             break;
280                         }                         278                         }
281                         if ( pair->value == "C    279                         if ( pair->value == "Calorimeter" )
282                         {                         280                         {
283                             calorimeterVolume     281                             calorimeterVolume = *lvIter;
284                             G4cout << CEXMC_LI    282                             G4cout << CEXMC_LINE_START "Calorimeter volume '";
285                             ReadCalorimeterGeo    283                             ReadCalorimeterGeometryData( *lvIter );
286                             calorimeterGeometr    284                             calorimeterGeometryDataInitialized = true;
287                             break;                285                             break;
288                         }                         286                         }
289                         if ( pair->value == "T    287                         if ( pair->value == "Target" )
290                         {                         288                         {
291                             targetVolume = *lv    289                             targetVolume = *lvIter;
292                             G4cout << CEXMC_LI    290                             G4cout << CEXMC_LINE_START "Target volume '";
293                             break;                291                             break;
294                         }                         292                         }
295                     } while ( false );            293                     } while ( false );
296                     G4cout << volumeName << "'    294                     G4cout << volumeName << "' registered" << G4endl;
297                     break;                        295                     break;
298                 }                                 296                 }
299             }                                     297             }
300             while ( false );                      298             while ( false );
301                                                   299 
302             if ( scorer )                         300             if ( scorer )
303             {                                     301             {
304                 /* curDetectorRole must be int    302                 /* curDetectorRole must be intact when scorer is not NULL */
305                 if ( ! detector[ curDetectorRo    303                 if ( ! detector[ curDetectorRole ] )
306                 {                                 304                 {
307                     detector[ curDetectorRole     305                     detector[ curDetectorRole ] =
308                                 new G4MultiFun    306                                 new G4MultiFunctionalDetector( detectorName );
309                 }                                 307                 }
310                 detector[ curDetectorRole ]->R    308                 detector[ curDetectorRole ]->RegisterPrimitive( scorer );
311                 /* now that scorer has initial    309                 /* now that scorer has initialized pointer to its detector, its
312                  * messenger's path shall be p    310                  * messenger's path shall be properly initialized as well */
313                 scorer->InitializeMessenger();    311                 scorer->InitializeMessenger();
314                 /* NB: logical volumes in GDML    312                 /* NB: logical volumes in GDML file may not have multiple
315                  * detector roles: for example    313                  * detector roles: for example volume Monitor may have only one
316                  * role MonitorRole. This rest    314                  * role MonitorRole. This restriction arises from that fact that
317                  * a logical volume may contai    315                  * a logical volume may contain only one sensitive detector. */
318                 ( *lvIter )->SetSensitiveDetec    316                 ( *lvIter )->SetSensitiveDetector(
319                                                   317                                                 detector[ curDetectorRole ] );
320             }                                     318             }
321         }                                         319         }
322     }                                             320     }
323                                                   321 
324     if ( ! calorimeterRegionInitialized )         322     if ( ! calorimeterRegionInitialized )
325         throw CexmcException( CexmcCalorimeter    323         throw CexmcException( CexmcCalorimeterRegionNotInitialized );
326                                                   324 
327     if ( ! calorimeterGeometryDataInitialized     325     if ( ! calorimeterGeometryDataInitialized )
328         throw CexmcException( CexmcCalorimeter    326         throw CexmcException( CexmcCalorimeterGeometryDataNotInitialized );
329                                                   327 
330     for ( G4int  i( 0 ); i < CexmcNumberOfDete    328     for ( G4int  i( 0 ); i < CexmcNumberOfDetectorRoles; ++i )
331     {                                             329     {
332         if ( detector[ i ] )                      330         if ( detector[ i ] )
333             G4SDManager::GetSDMpointer()->AddN    331             G4SDManager::GetSDMpointer()->AddNewDetector( detector[ i ] );
334     }                                             332     }
335 }                                                 333 }
336                                                   334 
337                                                   335 
338 void  CexmcSetup::ReadTransforms( const G4GDML    336 void  CexmcSetup::ReadTransforms( const G4GDMLParser &  gdmlParser )
339 {                                                 337 {
340     G4ThreeVector     position( gdmlParser.Get    338     G4ThreeVector     position( gdmlParser.GetPosition( "TargetPos" ) );
341     G4ThreeVector     rotation( gdmlParser.Get    339     G4ThreeVector     rotation( gdmlParser.GetRotation( "TargetRot" ) );
342     G4RotationMatrix  rm;                         340     G4RotationMatrix  rm;
343                                                   341 
344     RotateMatrix( rotation, rm );                 342     RotateMatrix( rotation, rm );
345     targetTransform.SetNetTranslation( positio    343     targetTransform.SetNetTranslation( position );
346     targetTransform.SetNetRotation( rm );         344     targetTransform.SetNetRotation( rm );
347                                                   345 
348     position = gdmlParser.GetPosition( "Calori    346     position = gdmlParser.GetPosition( "CalorimeterLeftPos" );
349     rotation = gdmlParser.GetRotation( "Calori    347     rotation = gdmlParser.GetRotation( "CalorimeterLeftRot" );
350     rm = G4RotationMatrix();                      348     rm = G4RotationMatrix();
351     RotateMatrix( rotation, rm );                 349     RotateMatrix( rotation, rm );
352     calorimeterLeftTransform.SetNetTranslation    350     calorimeterLeftTransform.SetNetTranslation( position );
353     calorimeterLeftTransform.SetNetRotation( r    351     calorimeterLeftTransform.SetNetRotation( rm );
354                                                   352 
355     position = gdmlParser.GetPosition( "Calori    353     position = gdmlParser.GetPosition( "CalorimeterRightPos" );
356     rotation = gdmlParser.GetRotation( "Calori    354     rotation = gdmlParser.GetRotation( "CalorimeterRightRot" );
357     rm = G4RotationMatrix();                      355     rm = G4RotationMatrix();
358     RotateMatrix( rotation, rm );                 356     RotateMatrix( rotation, rm );
359     calorimeterRightTransform.SetNetTranslatio    357     calorimeterRightTransform.SetNetTranslation( position );
360     calorimeterRightTransform.SetNetRotation(     358     calorimeterRightTransform.SetNetRotation( rm );
361 }                                                 359 }
362                                                   360 
363                                                   361 
364 void  CexmcSetup::ReadCalorimeterGeometryData(    362 void  CexmcSetup::ReadCalorimeterGeometryData(
365                                             co    363                                             const G4LogicalVolume *  lVolume )
366 {                                                 364 {
367     if ( lVolume->GetNoDaughters() == 0 )         365     if ( lVolume->GetNoDaughters() == 0 )
368         throw CexmcException( CexmcIncompatibl    366         throw CexmcException( CexmcIncompatibleGeometry );
369                                                   367 
370     G4VPhysicalVolume *  pVolume( lVolume->Get    368     G4VPhysicalVolume *  pVolume( lVolume->GetDaughter( 0 ) );
371     EAxis                axis;                    369     EAxis                axis;
372     G4double             width;                   370     G4double             width;
373     G4double             offset;                  371     G4double             offset;
374     G4bool               consuming;               372     G4bool               consuming;
375                                                   373 
376     if ( ! pVolume )                              374     if ( ! pVolume )
377         throw CexmcException( CexmcIncompatibl    375         throw CexmcException( CexmcIncompatibleGeometry );
378                                                   376 
379     if ( pVolume->IsReplicated() )                377     if ( pVolume->IsReplicated() )
380     {                                             378     {
381         pVolume->GetReplicationData( axis,        379         pVolume->GetReplicationData( axis,
382                                      calorimet    380                                      calorimeterGeometry.nCrystalsInColumn,
383                                      width, of    381                                      width, offset, consuming );
384     }                                             382     }
385                                                   383 
386     lVolume = pVolume->GetLogicalVolume();        384     lVolume = pVolume->GetLogicalVolume();
387                                                   385 
388     if ( lVolume->GetNoDaughters() == 0 )         386     if ( lVolume->GetNoDaughters() == 0 )
389         throw CexmcException( CexmcIncompatibl    387         throw CexmcException( CexmcIncompatibleGeometry );
390                                                   388 
391     pVolume = lVolume->GetDaughter( 0 );          389     pVolume = lVolume->GetDaughter( 0 );
392                                                   390 
393     if ( ! pVolume )                              391     if ( ! pVolume )
394         throw CexmcException( CexmcIncompatibl    392         throw CexmcException( CexmcIncompatibleGeometry );
395                                                   393 
396     if ( pVolume->IsReplicated() )                394     if ( pVolume->IsReplicated() )
397     {                                             395     {
398         pVolume->GetReplicationData( axis, cal    396         pVolume->GetReplicationData( axis, calorimeterGeometry.nCrystalsInRow,
399                                      width, of    397                                      width, offset, consuming );
400     }                                             398     }
401                                                   399 
402     lVolume = pVolume->GetLogicalVolume();        400     lVolume = pVolume->GetLogicalVolume();
403                                                   401 
404     /* NB: this is not necessarily a crystal i    402     /* NB: this is not necessarily a crystal itself as far as crystals can be
405      * wrapped in paper and other materials, b    403      * wrapped in paper and other materials, but this is what reconstructor and
406      * digitizers really need */                  404      * digitizers really need */
407     G4Box *  crystalBox( dynamic_cast< G4Box *    405     G4Box *  crystalBox( dynamic_cast< G4Box * >( lVolume->GetSolid() ) );
408                                                   406 
409     if ( ! crystalBox )                           407     if ( ! crystalBox )
410         throw CexmcException( CexmcIncompatibl    408         throw CexmcException( CexmcIncompatibleGeometry );
411                                                   409 
412     calorimeterGeometry.crystalWidth = crystal    410     calorimeterGeometry.crystalWidth = crystalBox->GetXHalfLength() * 2;
413     calorimeterGeometry.crystalHeight = crysta    411     calorimeterGeometry.crystalHeight = crystalBox->GetYHalfLength() * 2;
414     calorimeterGeometry.crystalLength = crysta    412     calorimeterGeometry.crystalLength = crystalBox->GetZHalfLength() * 2;
415 }                                                 413 }
416                                                   414 
417                                                   415 
418 void  CexmcSetup::ConvertToCrystalGeometry( co    416 void  CexmcSetup::ConvertToCrystalGeometry( const G4ThreeVector &  src,
419                     G4int &  row, G4int &  col    417                     G4int &  row, G4int &  column, G4ThreeVector &  dst ) const
420 {                                                 418 {
421     G4int     nCrystalsInColumn( calorimeterGe    419     G4int     nCrystalsInColumn( calorimeterGeometry.nCrystalsInColumn );
422     G4int     nCrystalsInRow( calorimeterGeome    420     G4int     nCrystalsInRow( calorimeterGeometry.nCrystalsInRow );
423     G4double  crystalWidth( calorimeterGeometr    421     G4double  crystalWidth( calorimeterGeometry.crystalWidth );
424     G4double  crystalHeight( calorimeterGeomet    422     G4double  crystalHeight( calorimeterGeometry.crystalHeight );
425                                                   423 
426     row = G4int( ( src.y() + crystalHeight * n    424     row = G4int( ( src.y() + crystalHeight * nCrystalsInColumn / 2 ) /
427                  crystalHeight );                 425                  crystalHeight );
428     column = G4int( ( src.x() + crystalWidth *    426     column = G4int( ( src.x() + crystalWidth * nCrystalsInRow / 2 ) /
429                     crystalWidth );               427                     crystalWidth );
430     G4double   xInCalorimeterOffset(              428     G4double   xInCalorimeterOffset(
431                     ( G4double( column ) - G4d    429                     ( G4double( column ) - G4double( nCrystalsInRow ) / 2 ) *
432                                             cr    430                                             crystalWidth + crystalWidth / 2 );
433     G4double   yInCalorimeterOffset(              431     G4double   yInCalorimeterOffset(
434                     ( G4double( row ) - G4doub    432                     ( G4double( row ) - G4double( nCrystalsInColumn ) / 2 ) *
435                                             cr    433                                             crystalHeight + crystalHeight / 2 );
436     dst.setX( src.x() - xInCalorimeterOffset )    434     dst.setX( src.x() - xInCalorimeterOffset );
437     dst.setY( src.y() - yInCalorimeterOffset )    435     dst.setY( src.y() - yInCalorimeterOffset );
438 }                                                 436 }
439                                                   437 
440                                                   438 
441 void  CexmcSetup::ReadRightDetectors( void )      439 void  CexmcSetup::ReadRightDetectors( void )
442 {                                                 440 {
443     G4PhysicalVolumeStore *  pvs( G4PhysicalVo    441     G4PhysicalVolumeStore *  pvs( G4PhysicalVolumeStore::GetInstance() );
444                                                   442 
445     for ( std::vector< G4VPhysicalVolume * >::    443     for ( std::vector< G4VPhysicalVolume * >::const_iterator  k( pvs->begin() );
446                                                   444                                                         k != pvs->end(); ++k )
447     {                                             445     {
448         /* FIXME: it would be more reasonable     446         /* FIXME: it would be more reasonable to find detectors from volumes
449          * tagged with 'EnergyDepositDetector'    447          * tagged with 'EnergyDepositDetector' or 'TrackPointsDetector', and not
450          * from volumes tagged with 'SpecialVo    448          * from volumes tagged with 'SpecialVolume' as it is done here. However
451          * in case of calorimeters the role of    449          * in case of calorimeters the role of detectors are played by crystal
452          * volumes, not the calorimeters thems    450          * volumes, not the calorimeters themselves, but only calorimeters can
453          * hold information about their left o    451          * hold information about their left or right positions! Thus, following
454          * considerations of convenience, righ    452          * considerations of convenience, right detectors for all detector roles
455          * are chosen from volumes tagged with    453          * are chosen from volumes tagged with 'SpecialVolume' */
456         do                                        454         do
457         {                                         455         {
458             if ( ( *k )->GetLogicalVolume() ==    456             if ( ( *k )->GetLogicalVolume() == vetoCounterVolume )
459             {                                     457             {
460                 if ( G4StrUtil::contains(( *k  << 458                 if ( ( *k )->GetName().contains( "Right" ) )
461                     rightVetoCounter = *k;        459                     rightVetoCounter = *k;
462                 break;                            460                 break;
463             }                                     461             }
464             if ( ( *k )->GetLogicalVolume() ==    462             if ( ( *k )->GetLogicalVolume() == calorimeterVolume )
465             {                                     463             {
466                 if ( G4StrUtil::contains(( *k  << 464                 if ( ( *k )->GetName().contains( "Right" ) )
467                     rightCalorimeter = *k;        465                     rightCalorimeter = *k;
468                 break;                            466                 break;
469             }                                     467             }
470         } while ( false );                        468         } while ( false );
471     }                                             469     }
472 }                                                 470 }
473                                                   471 
474                                                   472 
475 void  CexmcSetup::AssertAndAsignDetectorRole(     473 void  CexmcSetup::AssertAndAsignDetectorRole( CexmcDetectorRole &  detectorRole,
476                                                   474                                               CexmcDetectorRole  value )
477 {                                                 475 {
478     if ( detectorRole != CexmcNumberOfDetector    476     if ( detectorRole != CexmcNumberOfDetectorRoles && detectorRole != value )
479         throw CexmcException( CexmcMultipleDet    477         throw CexmcException( CexmcMultipleDetectorRoles );
480                                                   478 
481     detectorRole = value;                         479     detectorRole = value;
482 }                                                 480 }
483                                                   481 
484                                                   482 
485 void  CexmcSetup::RotateMatrix( const G4ThreeV    483 void  CexmcSetup::RotateMatrix( const G4ThreeVector &  rot,
486                                 G4RotationMatr    484                                 G4RotationMatrix &  rm )
487 {                                                 485 {
488     rm.rotateX( rot.x() );                        486     rm.rotateX( rot.x() );
489     rm.rotateY( rot.y() );                        487     rm.rotateY( rot.y() );
490     rm.rotateZ( rot.z() );                        488     rm.rotateZ( rot.z() );
491 }                                                 489 }
492                                                   490 
493                                                   491