#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; namespace RAT { void GeoPanelFactory::Construct( DBLinkPtr table, const bool checkOverlaps ) { // Get the mother volume to find the mother material string motherName = table->GetS("mother"); G4LogicalVolume *mother = Detector::FindLogicalVolume( motherName ); AssembleFullPMT( table, mother->GetMaterial() ); SetupOpticalModel( table ); ConstructPanels( table, checkOverlaps ); PlacePanels( table, checkOverlaps ); DeletePanels(); return; } void GeoPanelFactory::ConstructPanels( DBLinkPtr table, const bool checkOverlaps ) { // Get the PANELINFO and build the panels DBLinkPtr panelInfo = DB::Get()->GetLink( "PANELINFO" ); vector panelNumber = panelInfo->GetIArray( "panel_number" ); vector panelType = panelInfo->GetIArray( "panel_type" ); vector panelR = panelInfo->GetDArray( "r" ); vector panelS = panelInfo->GetDArray( "s" ); vector panelT = panelInfo->GetDArray( "t" ); vector panelU = panelInfo->GetDArray( "u" ); vector panelV = panelInfo->GetDArray( "v" ); vector panelW = panelInfo->GetDArray( "w" ); vector panelX = panelInfo->GetDArray( "x" ); vector panelY = panelInfo->GetDArray( "y" ); vector panelZ = panelInfo->GetDArray( "z" ); string volumeName = table->GetIndex(); string motherName = table->GetS("mother"); G4LogicalVolume *mother = Detector::FindLogicalVolume( motherName ); // Panels are logical envelopes thus same material as mother G4Material* panelMaterial = mother->GetMaterial(); G4VisAttributes* visAttributes = GeoFactory::LoadVisualisation( table ); for( unsigned int uPanel = 0; uPanel < panelNumber.size(); uPanel++ ) { const int panel = panelNumber[uPanel]; const G4ThreeVector pos( panelX[uPanel], panelY[uPanel], panelZ[uPanel] ); const G4ThreeVector xAxis( panelR[uPanel], panelS[uPanel], panelT[uPanel] ); const G4ThreeVector zAxis( panelU[uPanel], panelV[uPanel], panelW[uPanel] ); switch( panelType[uPanel] ) { case 0: // S7 fPanels[panel] = new PanelS7( volumeName, pos, zAxis, xAxis, panelMaterial, visAttributes ); break; case 1: // S19 fPanels[panel] = new PanelS19( volumeName, pos, zAxis, xAxis, panelMaterial, visAttributes ); break; case 2: // T21 fPanels[panel] = new PanelT21( volumeName, pos, zAxis, xAxis, panelMaterial, visAttributes ); break; case 3: // T14 fPanels[panel] = new PanelT14( volumeName, pos, zAxis, xAxis, panelMaterial, visAttributes ); break; case 4: // T10 fPanels[panel] = new PanelT10( volumeName, pos, zAxis, xAxis, panelMaterial, visAttributes ); break; } } // Now place the PMTs into the panels DBLinkPtr pmtInfo = DB::Get()->GetLink( "PMTINFO" ); panelNumber = pmtInfo->GetIArray("panelnumber"); vector type = pmtInfo->GetIArray("pmt_type"); vector pmtX = pmtInfo->GetDArray("x"); vector pmtY = pmtInfo->GetDArray("y"); vector pmtZ = pmtInfo->GetDArray("z"); vector dirX = pmtInfo->GetDArray("u"); vector dirY = pmtInfo->GetDArray("v"); vector dirZ = pmtInfo->GetDArray("w"); vector pmtTypeToBuild( 1, 1 ); // Default normal try { pmtTypeToBuild = table->GetIArray("pmt_build_type"); } catch (DBNotFoundError &e) { /*Default Normal PMTs*/ } //Loop over all the PMTs for( unsigned int uPMT = 0; uPMT < panelNumber.size(); uPMT++ ) { const int panel = panelNumber[uPMT]; G4ThreeVector pos( pmtX[uPMT], pmtY[uPMT], pmtZ[uPMT] ); G4ThreeVector dir( dirX[uPMT], dirY[uPMT], dirZ[uPMT] ); // Build only prescribed pmts, default is Normal if( find( pmtTypeToBuild.begin(), pmtTypeToBuild.end(), type[uPMT] ) == pmtTypeToBuild.end() ) continue; CorrectPMTPosAndDir( type[uPMT], pos, dir ); // Check if PMT is in a panel, if not then skip if( panel == -1 ) continue; // Add the pmt to the panel fPanels[panel]->AddPMT( fEnvelope[ type[uPMT] ], uPMT, pos, dir ); } // Finally loop over and build the panels for( map::iterator iTer = fPanels.begin(); iTer != fPanels.end(); ++iTer ) iTer->second->Construct( checkOverlaps ); } void GeoPanelFactory::PlacePanels( DBLinkPtr table, const bool checkOverlaps ) { string volumeName = table->GetIndex(); string motherName = table->GetS( "mother" ); G4VPhysicalVolume* physMother = Detector::FindPhysicalVolume( motherName ); for( map::iterator iTer = fPanels.begin(); iTer != fPanels.end(); ++iTer ) { string panelName = volumeName +std::string("_panel") + ::to_string( iTer->first ); G4ThreeVector panelPosition; G4RotationMatrix* panelRotation = new G4RotationMatrix(); //Deleted by Magic :) iTer->second->GetRotationAndPosition( panelRotation, &panelPosition ); // Place panel in the detector new G4PVPlacement( panelRotation, panelPosition, panelName, iTer->second->GetLogicalVolume(), physMother, false, iTer->first, checkOverlaps ); } } void GeoPanelFactory::DeletePanels() { for( map::iterator iTer = fPanels.begin(); iTer != fPanels.end(); ++iTer ) delete iTer->second; fPanels.clear(); } } // namespace RAT