#include #include #include #include #include #include #include #include #include #include #include using namespace RAT; using namespace std; void GeoSolidFactory::Construct( DBLinkPtr table, const bool checkOverlaps ) { DBLinkPtr solidTable = table; try { string solidTableIndex = table->GetS( "solid_definition" ); solidTable = DB::Get()->GetLink( "SOLID", solidTableIndex ); } catch( DBNotFoundError& e ) { /* Optional */ } G4VSolid* solid = GeoSolid::ConstructSolid( table->GetIndex(), solidTable ); // See if the solid should be split try { double splitZ = table->GetD( "split_z" ); pair< G4VSolid*, G4VSolid* > solids = SplitSolid( solid, table->GetIndex(), splitZ ); G4LogicalVolume* logicalTop = BuildVolume( table->GetIndex() + "_top", table, solids.first, G4Material::GetMaterial( table->GetS( "material_top" ) ) ); PlaceVolume( table->GetIndex() + "_top", table, logicalTop, checkOverlaps ); G4LogicalVolume* logicalBottom = BuildVolume( table->GetIndex() + "_bottom", table, solids.second, G4Material::GetMaterial( table->GetS( "material_bottom" ) ) ); PlaceVolume( table->GetIndex() + "_bottom", table, logicalBottom, checkOverlaps ); } catch( DBNotFoundError& e ) // Just a single solid to place { const string name = table->GetIndex(); G4LogicalVolume* logicalVolume = BuildVolume( name, table, solid, G4Material::GetMaterial( table->GetS( "material" ) ) ); PlaceVolume( name, table, logicalVolume, checkOverlaps ); } } G4LogicalVolume* GeoSolidFactory::BuildVolume( const std::string& name, DBLinkPtr table, G4VSolid* const solid, G4Material* const material ) const { Log::Assert( material != NULL, "GeoSolidFactory::BuildVolume: Material for " + name + " not found." ); G4LogicalVolume* logicalVolume = new G4LogicalVolume( solid, material, name + "_logical" ); try // Optional skin surface addition { new G4LogicalSkinSurface( name + "_surface", logicalVolume, Surfaces::GetSurface( table->GetS( "material" ) ) ); } catch (DBNotFoundError &e) { }; try // Optionally disable voxel optimization, GEANT4 default is to always optimize { if( table->GetI("optimize") == 0 ) logicalVolume->SetOptimisation( false ); } catch (DBNotFoundError &e) { }; logicalVolume->SetVisAttributes( LoadVisualisation( table ) ); return logicalVolume; } void GeoSolidFactory::PlaceVolume( const std::string& name, DBLinkPtr table, G4LogicalVolume* const logicalVolume, const bool checkOverlaps ) const { pair< G4ThreeVector, G4RotationMatrix* > translation = LoadTranslation( table ); string motherName = table->GetS( "mother" ); G4LogicalVolume* mother = NULL; if( motherName == string("") ) mother = NULL; // World volume has no mother else mother = Detector::FindLogicalVolume( motherName ); // Now place the logical volume in the mother new G4PVPlacement( translation.second, translation.first, logicalVolume, name, mother, false, 0, checkOverlaps ); }