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.2.p2)


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