#include #include #include #include #include #include #include using namespace RAT; #include #include using namespace CLHEP; using namespace std; void GeoSolidArrayFactory::PlaceVolume( const std::string& name, DBLinkPtr table, G4LogicalVolume* const logicalVolume, const bool checkOverlaps ) const { pair< G4ThreeVector, G4RotationMatrix* > translation = LoadTranslation( table ); const string motherName = table->GetS("mother"); G4VPhysicalVolume* mother = NULL; if( motherName == string("") ) mother = NULL; // World volume has no mother else mother = Detector::FindPhysicalVolume( motherName ); // 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" ); }// Really need a has method -PGJ catch( DBNotFoundError& e ) { string locations = table->GetS( "locations" ); locationTable = DB::Get()->GetLink( "GEO_LOCATIONS", locations ); try { locationTable->GetDArray( "x" ); }// Really need a has method -PGJ catch( DBNotFoundError& e ) { Log::Die( "GeoSolidArrayFactory::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& error ) { 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& error ) { roll.resize( x.size(), 0.0 ); } if( x.size() != y.size() || x.size() != z.size() || x.size() != roll.size() ) Log::Die( "GeoSolidArrayFactory::PlaceVolume: Position array size mismatch." ); for( size_t uPlacement = 0; 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] ); position += translation.first; if( translation.second != NULL ) rotation->transform( *translation.second ); stringstream volumeName; volumeName << name << "_" << uPlacement; // Use the constructor that specifies the PHYSICAL mother, since each Solid occurs only once in one physical volume. // This saves the GeometryManager some work. -GHS. new G4PVPlacement( rotation, position, volumeName.str(), logicalVolume, mother, false, uPlacement, checkOverlaps ); } }