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 10.7.p3)


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