#include #include #include #include #include #include #include #include #include #include using namespace RAT; #include #include using namespace CLHEP; using namespace std; void GeoSolidUnionFactory::Construct( DBLinkPtr table, const bool checkOverlaps ) { const string name = table->GetIndex(); DB* db = DB::Get(); G4VSolid* solid = GeoSolid::ConstructSolid( name + "_sub_solid", db->GetLink( "SOLID", table->GetS( "solid_definition" ) ) ); // Now load the locations, either in this table or another vector x, y, z, u, v, w, roll; DBLinkPtr locationTable = table; try { locationTable->GetDArray( "x" ); } catch( DBNotFoundError& e ) { string locations = table->GetS( "locations" ); locationTable = DB::Get()->GetLink( "GEO_LOCATIONS", locations ); try { locationTable->GetDArray( "x" ); } catch( DBNotFoundError& e ) { Log::Die( "GeoSolidUnionFactory::Construct: cannot find locations in GEO or ratdb" ); } } x = locationTable->GetDArray( "x" ); y = locationTable->GetDArray( "y" ); z = locationTable->GetDArray( "z" ); try // u, v, w are optional if absent u=0, v=0, w=1 { u = locationTable->GetDArray( "u" ); v = locationTable->GetDArray( "v" ); w = locationTable->GetDArray( "w" ); } catch( DBNotFoundError& e ) { u.resize( x.size(), 0.0 ); v.resize( x.size(), 0.0 ); w.resize( x.size(), 1.0 ); } try { roll = locationTable->GetDArray( "roll" ); } catch( DBNotFoundError& e ) { roll.resize( x.size(), 0.0 ); } if( x.size() != y.size() || x.size() != z.size() || x.size() != roll.size() ) Log::Die( "GeoSolidUnionFactory::PlaceVolume: Position array size mismatch." ); G4RotationMatrix* primaryRotation = DirectionToRotation( G4ThreeVector( u[0], v[0], w[0] ) ); primaryRotation->rotateZ( roll[0] * deg ); G4ThreeVector primaryPosition( x[0], y[0], z[0] ); G4VSolid* fullSolid = new G4DisplacedSolid( name + "_solid", solid, primaryRotation, primaryPosition ); for( size_t uPlacement = 1; uPlacement < x.size(); uPlacement++ ) { G4RotationMatrix* rotation = DirectionToRotation( G4ThreeVector( u[uPlacement], v[uPlacement], w[uPlacement] ) ); rotation->rotateZ( roll[uPlacement] * deg ); G4ThreeVector position( x[uPlacement], y[uPlacement], z[uPlacement] ); fullSolid = new G4UnionSolid( name + "_solid", fullSolid, solid, rotation, position ); } G4Material* material = G4Material::GetMaterial( table->GetS( "material" ) ); G4LogicalVolume* logicalVolume = BuildVolume( name, table, fullSolid, material ); try // Optional skin surface addition { new G4LogicalSkinSurface( name + "_surface", logicalVolume, Surfaces::GetSurface( table->GetS( "material" ) ) ); } catch (DBNotFoundError& e) { }; PlaceVolume( name, table, logicalVolume, checkOverlaps ); }