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