00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00045
00046
00071
00072
00073
00074
00075 #include "database/MJDatabase.hh"
00076 #include "geometry/MJGeometryCloverDetector.hh"
00077 #include "geometry/MJGeometryGlobals.hh"
00078 #include "io/MJLogger.hh"
00079
00080
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
00090 #include "TMath.h"
00091
00092
00093 #include <string>
00094
00095 using namespace std;
00096
00097
00098 MJGeometryCloverDetector::MJGeometryCloverDetector( G4String serNum ) :
00099 MJGeometryDetector( serNum ), theDBdetector(0)
00100
00101 {
00102 theDBdetector = MJDatabase::GetCloverDetector( serialNumber );
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 MJGeometryCloverDetector::~MJGeometryCloverDetector()
00115 {;}
00116
00117
00118
00119 void MJGeometryCloverDetector::ConstructDetector() {
00120
00121
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
00153 for (int i=0; i<4; i++) {
00154 theCrystals[i] = new MJGeometryCloverCrystal((theDBdetector->GetCrystalSerialNumbers())[i]);
00155 }
00156
00157
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
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 );
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
00188 theDetectorLogical = new G4LogicalVolume( cryo6, cryoMaterial, "theDetectorLogical" );
00189 theDetectorLogical->SetVisAttributes( cryostatVisAtt );
00190
00191
00192
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 );
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 );
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
00210 G4VSolid *innerChamberSolid = new G4UnionSolid( "innerChamberSolid", thinWallChamber6, thickWallChamber6, 0, G4ThreeVector(x*cm,y*cm,-z*cm) );
00211
00212
00213
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
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
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 }