Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

MJGeometryCloverDetector.cc

Go to the documentation of this file.
00001 //---------------------------------------------------------------------------//
00002 //bb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nu//
00003 //                                                                           //
00004 //                         MAJORANA Simulation                               //
00005 //                                                                           //
00006 //      This code implementation is the intellectual property of the         //
00007 //      MAJORANA Collaboration. It is based on Geant4, an intellectual       //
00008 //      property of the RD44 GEANT4 collaboration.                           //
00009 //                                                                           //
00010 //                        *********************                              //
00011 //                                                                           //
00012 //    Neither the authors of this software system, nor their employing       //
00013 //    institutes, nor the agencies providing financial support for this      //
00014 //    work  make  any representation or  warranty, express or implied,       //
00015 //    regarding this software system or assume any liability for its use.    //
00016 //    By copying, distributing or modifying the Program (or any work based   //
00017 //    on on the Program) you indicate your acceptance of this statement,     //
00018 //    and all its terms.                                                     //
00019 //                                                                           //
00020 //bb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nubb0nu//
00021 //---------------------------------------------------------------------------//
00022 //                                                          
00023 // $Id: MJGeometryCloverDetector.cc,v 1.2 2004/11/09 13:42:39 xliu Exp $ 
00024 //      
00025 // CLASS IMPLEMENTATION:  MJGeometryCloverDetector.cc
00026 //
00027 //---------------------------------------------------------------------------//
00045 // 
00046 //---------------------------------------------------------------------------//
00071 //---------------------------------------------------------------------------//
00072 //
00073 
00074 //  MJ headers
00075 #include "database/MJDatabase.hh"
00076 #include "geometry/MJGeometryCloverDetector.hh" 
00077 #include "geometry/MJGeometryGlobals.hh"
00078 #include "io/MJLogger.hh"
00079 
00080 //  GEANT4 headers
00081 #include "G4Material.hh"
00082 #include "G4Box.hh"
00083 #include "G4Tubs.hh"
00084 #include "G4SubtractionSolid.hh"
00085 #include "G4LogicalVolume.hh"
00086 #include "G4PVPlacement.hh"
00087 #include "G4UnionSolid.hh"
00088 
00089 //  ROOT headers
00090 #include "TMath.h"
00091 
00092 //  G++ headers
00093 #include <string>
00094 
00095 using namespace std;
00096 
00097 //---------------------------------------------------------------------------//
00098 MJGeometryCloverDetector::MJGeometryCloverDetector( G4String serNum ) :
00099 MJGeometryDetector( serNum ), theDBdetector(0)
00100         //  Database call to get the detector object keyed on the serial number
00101 {
00102         theDBdetector = MJDatabase::GetCloverDetector( serialNumber );
00103 }
00104 
00105 //---------------------------------------------------------------------------//
00106 //MJGeometryCloverDetector::MJGeometryCloverDetector(const MJGeometryCloverDetector & other)
00107 //{
00108 //      theDBdetector = MJDatabase::MJDatabaseCloverDetector->GetCloverDetector( serialNumber );
00109 //      ConstructDetector();
00110 //}
00111 
00112 //---------------------------------------------------------------------------//
00113 
00114 MJGeometryCloverDetector::~MJGeometryCloverDetector()
00115 {;}
00116 
00117 //---------------------------------------------------------------------------//
00118 
00119 void MJGeometryCloverDetector::ConstructDetector() {
00120 
00121         //  Grab the relevant variables from the database object to avoid multiple dereferenced lookups
00122         G4double cryoThinWallThickness = theDBdetector->GetCryoThinWallThickness();
00123         G4double cryoThickWallThickness = theDBdetector->GetCryoThickWallThickness();
00124         G4double cryoThinWallLength = theDBdetector->GetCryoThinWallLength();
00125         G4double cryoLength = theDBdetector->GetCryoLength();
00126         G4double cryoWidth = theDBdetector->GetCryoWidth();
00127         G4double cryoCornerRadius = theDBdetector->GetCryoCornerRadius();
00128         G4Material *cryoMaterial = G4Material::GetMaterial( theDBdetector->GetCryoMaterialName() );
00129         if(!cryoMaterial) {
00130           MJLog(error) << "NULL pointer for G4Material: " 
00131                        << theDBdetector->GetCryoMaterialName() << endlog;
00132           MJLog(fatal);
00133         }
00134         string *crystalSerialNumbers = theDBdetector->GetCrystalSerialNumbers();
00135         G4double cryoEndGap = theDBdetector->GetCryoEndGap();
00136         G4double coldplateThickness = theDBdetector->GetColdplateThickness();
00137         G4double coldplateGap = theDBdetector->GetColdplateGap();
00138         G4Material *coldplateMaterial = G4Material::GetMaterial( theDBdetector->GetColdplateMaterialName() );
00139         if(!coldplateMaterial) {
00140           MJLog(error) << "NULL pointer for G4Material: " 
00141                        << theDBdetector->GetColdplateMaterialName() << endlog;
00142           MJLog(fatal);
00143         }
00144         G4double spacerWidth = theDBdetector->GetSpacerWidth();
00145         G4Material *spacerMaterial = G4Material::GetMaterial( theDBdetector->GetSpacerMaterialName() );
00146         if(!spacerMaterial) {
00147           MJLog(error) << "NULL pointer for G4Material: " 
00148                        << theDBdetector->GetSpacerMaterialName() << endlog;
00149           MJLog(fatal);
00150         }
00151         
00152 //  Instantiate the clover crystals
00153         for (int i=0; i<4; i++) {
00154           theCrystals[i] = new MJGeometryCloverCrystal((theDBdetector->GetCrystalSerialNumbers())[i]);
00155         }
00156 
00157         //  Set the visualization attributes for each of the components
00158         G4VisAttributes *cryostatVisAtt = new G4VisAttributes( ltgray );
00159         cryostatVisAtt->SetVisibility( true );
00160         cryostatVisAtt->SetForceWireframe( true );
00161         
00162         G4VisAttributes *coldplateVisAtt = new G4VisAttributes( ltgray );
00163         coldplateVisAtt->SetVisibility( true );
00164         coldplateVisAtt->SetForceSolid( true );
00165         
00166         G4VisAttributes *spacerVisAtt = new G4VisAttributes( blue );
00167         spacerVisAtt->SetVisibility( true );
00168         spacerVisAtt->SetForceSolid( true );
00169 
00170         //  Build the cryostat
00171         G4Box *cryo1 = new G4Box( "cryo1", (cryoWidth/2)*cm, (cryoWidth/2)*cm, (cryoLength/2)*cm );
00172         G4Tubs *cryo2 = new G4Tubs( "cryo2", cryoCornerRadius*cm, (cryoCornerRadius * TMath::Sqrt(2.) + 0.1)*cm, (cryoLength/2 + .01)*cm, 0*deg, 90*deg ); // Added 0.01/2 to z, RH 7/29/2004
00173         G4double x = (cryoWidth/2 - cryoCornerRadius);
00174         G4double y = x;
00175         G4double z = 0;
00176         G4RotationMatrix *rotZ90 = new G4RotationMatrix;
00177         rotZ90->rotateZ(90*deg);
00178         G4RotationMatrix *rotZ180 = new G4RotationMatrix;
00179         rotZ180->rotateZ(180*deg);
00180         G4RotationMatrix *rotZ270 = new G4RotationMatrix;
00181         rotZ270->rotateZ(270*deg);
00182         G4VSolid *cryo3 = new G4SubtractionSolid( "cryo3", cryo1, cryo2, 0, G4ThreeVector(x*cm,y*cm,z*cm) );
00183         G4VSolid *cryo4 = new G4SubtractionSolid( "cryo4", cryo3, cryo2, rotZ90, G4ThreeVector(x*cm,-y*cm,z*cm) );
00184         G4VSolid *cryo5 = new G4SubtractionSolid( "cryo5", cryo4, cryo2, rotZ180, G4ThreeVector(-x*cm,-y*cm,z*cm) );
00185         G4VSolid *cryo6 = new G4SubtractionSolid( "cryo6", cryo5, cryo2, rotZ270, G4ThreeVector(-x*cm,y*cm,z*cm) );
00186         
00187         //  Use this outermost cryostat object as the logical detector, and fit everything else inside of it.
00188         theDetectorLogical = new G4LogicalVolume( cryo6, cryoMaterial, "theDetectorLogical" );
00189         theDetectorLogical->SetVisAttributes( cryostatVisAtt );
00190 
00191         //  First put in the inner chamber. This inner chamber comes in two parts: the thin wall
00192         //  chamber and the thick wall chamber
00193         G4Box *thinWallChamber1 = new G4Box( "thinWallChamber1", (cryoWidth/2-cryoThinWallThickness)*cm, (cryoWidth/2-cryoThinWallThickness)*cm, ((cryoThinWallLength-cryoThinWallThickness)/2)*cm );
00194         G4Tubs *thinWallChamber2 = new G4Tubs( "thinWallChamber2", (cryoCornerRadius-cryoThinWallThickness)*cm, ((cryoCornerRadius-cryoThinWallThickness)*TMath::Sqrt(2.) + 0.1)*cm, ((cryoThinWallLength-cryoThinWallThickness+.01)/2)*cm, 0*deg, 90*deg ); // Added .01/2 to z, RH 7/29/2004
00195         G4VSolid *thinWallChamber3 = new G4SubtractionSolid( "thinWallChamber3", thinWallChamber1, thinWallChamber2, 0, G4ThreeVector(x*cm,y*cm,z*cm) );
00196         G4VSolid *thinWallChamber4 = new G4SubtractionSolid( "thinWallChamber4", thinWallChamber3, thinWallChamber2, rotZ90, G4ThreeVector(x*cm,-y*cm,z*cm) );
00197         G4VSolid *thinWallChamber5 = new G4SubtractionSolid( "thinWallChamber5", thinWallChamber4, thinWallChamber2, rotZ180, G4ThreeVector(-x*cm,-y*cm,z*cm) );
00198         G4VSolid *thinWallChamber6 = new G4SubtractionSolid( "thinWallChamber6", thinWallChamber5, thinWallChamber2, rotZ270, G4ThreeVector(-x*cm,y*cm,z*cm) );
00199 
00200         G4Box *thickWallChamber1 = new G4Box( "thickWallChamber1", (cryoWidth/2-cryoThickWallThickness)*cm, (cryoWidth/2-cryoThickWallThickness)*cm, ((cryoLength/2-cryoThickWallThickness))*cm );
00201         G4Tubs *thickWallChamber2 = new G4Tubs( "thickWallChamber2", (cryoCornerRadius-cryoThickWallThickness)*cm, ((cryoCornerRadius-cryoThickWallThickness)*TMath::Sqrt(2.) + 0.1)*cm, ((cryoLength/2.-cryoThickWallThickness+.01))*cm, 0*deg, 90*deg );// Added .01/2 to z, RH 7/29/2004
00202         G4VSolid *thickWallChamber3 = new G4SubtractionSolid( "thickWallChamber3", thickWallChamber1, thickWallChamber2, 0, G4ThreeVector(x*cm,y*cm,z*cm) );
00203         G4VSolid *thickWallChamber4 = new G4SubtractionSolid( "thickWallChamber4", thickWallChamber3, thickWallChamber2, rotZ90, G4ThreeVector(x*cm,-y*cm,z*cm) );
00204         G4VSolid *thickWallChamber5 = new G4SubtractionSolid( "thickWallChamber5", thickWallChamber4, thickWallChamber2, rotZ180, G4ThreeVector(-x*cm,-y*cm,z*cm) );
00205         G4VSolid *thickWallChamber6 = new G4SubtractionSolid( "thickWallChamber6", thickWallChamber5, thickWallChamber2, rotZ270, G4ThreeVector(-x*cm,y*cm,z*cm) );
00206 
00207         x = y = 0;
00208         z = (cryoLength - cryoThinWallThickness - cryoThinWallLength)/2.0;
00209 //      z = cryoLength/2;
00210         G4VSolid *innerChamberSolid = new G4UnionSolid( "innerChamberSolid", thinWallChamber6, thickWallChamber6, 0, G4ThreeVector(x*cm,y*cm,-z*cm) );
00211         
00212         //  Now that the two inner chambers are unionized, place them as a single object in the cryostat.
00213         //  All the other objects will be placed inside the innerChamberPhysical volume.
00214         G4LogicalVolume *innerChamberLogical = new G4LogicalVolume( innerChamberSolid, G4Material::GetMaterial("Vacuum"), "innerChamberLogical" );
00215         z = (cryoLength - cryoThinWallLength - cryoThinWallThickness) / 2.0;
00216         G4PVPlacement *innerChamberPhysical = new G4PVPlacement( 0, G4ThreeVector(x*cm,y*cm,z*cm), innerChamberLogical, "innerChamber", theDetectorLogical, false, 0 );
00217         
00218         //  Put the crystals and coldplates in the inner chamber
00219         for( G4int index = 0; index<4; index++ )
00220                 theCrystals[index] = new MJGeometryCloverCrystal( crystalSerialNumbers[index] );
00221         G4PVPlacement *thePhysicalCrystals[4];
00222         
00223         G4double largerDeficit = theCrystals[0]->GetDBCrystal()->GetLeftDeficit();
00224         if( largerDeficit < theCrystals[0]->GetDBCrystal()->GetRightDeficit())
00225                 largerDeficit = theCrystals[0]->GetDBCrystal()->GetRightDeficit();
00226         G4Tubs *coldplateSolid = new G4Tubs( "coldplateSolid", 0*cm,  (theCrystals[0]->GetDBCrystal()->GetCrystalRadius() - largerDeficit )*cm, (coldplateThickness/2)*cm, 0*deg, 360*deg );
00227         G4LogicalVolume *coldplateLogic = new G4LogicalVolume( coldplateSolid, coldplateMaterial, "coldplateLogic" );
00228         coldplateLogic->SetVisAttributes( coldplateVisAtt );
00229 
00230         for( G4int index = 0; index < 4; index++ ) {
00231                 if( index==0 || index==3 )
00232                         x = theCrystals[index]->GetDBCrystal()->GetCrystalRadius() - theCrystals[index]->GetDBCrystal()->GetRightDeficit() + spacerWidth;
00233                 else
00234                         x = theCrystals[index]->GetDBCrystal()->GetCrystalRadius() - theCrystals[index]->GetDBCrystal()->GetLeftDeficit() + spacerWidth;
00235                 if( index==0 || index==1 )
00236                         y = theCrystals[index]->GetDBCrystal()->GetCrystalRadius() - theCrystals[index]->GetDBCrystal()->GetBottomDeficit() + spacerWidth;
00237                 else
00238                         y = theCrystals[index]->GetDBCrystal()->GetCrystalRadius() - theCrystals[index]->GetDBCrystal()->GetTopDeficit() + spacerWidth;
00239                 z = (cryoThinWallLength - cryoThinWallThickness - theCrystals[index]->GetDBCrystal()->GetCrystalHeight())/2 - cryoEndGap;
00240                 if( index==0 || index==3 ) x *= -1;
00241                 if( index==2 || index==3 ) y *= -1;
00242                 char physiName[15];
00243                 sprintf( physiName, "Crystal %d", index+1 );
00244                 thePhysicalCrystals[index] = new G4PVPlacement( 0, G4ThreeVector(x*cm,y*cm,z*cm), physiName, theCrystals[index]->GetCrystalLogical(), innerChamberPhysical, false, 0 );
00245                 z = theCrystals[index]->GetDBCrystal()->GetCrystalHeight()/2 - z + coldplateGap + coldplateThickness/2;
00246                 G4PVPlacement *coldplatePhysical = new G4PVPlacement( 0, G4ThreeVector(x*cm,y*cm,-z*cm), "coldplateLogical", coldplateLogic, innerChamberPhysical, false, index );
00247         }
00248         
00249         //  Put the crystal spacer in the chamber
00250         G4double maxHeight = 0;
00251         for( G4int index = 0; index < 4; index++ )
00252                 if( theCrystals[index]->GetDBCrystal()->GetCrystalHeight() > maxHeight )
00253                         maxHeight = theCrystals[index]->GetDBCrystal()->GetCrystalHeight();
00254         G4Box *spacer1 = new G4Box( "spacer1", (spacerWidth/2)*cm, ((cryoWidth-cryoThickWallThickness)/2)*cm, (maxHeight/2)*cm );
00255         G4VSolid *spacer2 = new G4UnionSolid( "spacer2", spacer1, spacer1, rotZ90, G4ThreeVector() );
00256         G4LogicalVolume *spacerLogical = new G4LogicalVolume( spacer2, spacerMaterial, "spacerLogical" );
00257         spacerLogical->SetVisAttributes( spacerVisAtt );
00258         x = 0;
00259         y = 0;
00260         z = (cryoThinWallLength - cryoThinWallThickness - maxHeight)/2 - cryoEndGap;
00261         G4PVPlacement *spacerPhysical = new G4PVPlacement( 0, G4ThreeVector(x*cm,y*cm,z*cm), "spacer", spacerLogical, innerChamberPhysical, false, 0 );
00262 
00263 }

Generated on Mon Nov 29 16:58:51 2004 for Majorana Simulation by  doxygen 1.3.9.1