00001
00002
00003
00004
00005
00006 #include "BDSGlobalConstants.hh"
00007 #include "BDSScintillatorScreen.hh"
00008 #include "BDSMaterials.hh"
00009 #include "BDSSampler.hh"
00010 #include "BDSSamplerSD.hh"
00011 #include "G4Box.hh"
00012 #include "G4VisAttributes.hh"
00013 #include "G4LogicalVolume.hh"
00014 #include "G4VPhysicalVolume.hh"
00015 #include "G4PVPlacement.hh"
00016 #include "G4UserLimits.hh"
00017 #include "G4OpticalSurface.hh"
00018 #include "G4LogicalBorderSurface.hh"
00019
00020 #include <map>
00021
00022 class BDSTiltOffset;
00023
00024 BDSScintillatorScreen::BDSScintillatorScreen(G4String name,
00025 G4double tScint,
00026 G4double angle,
00027 G4String scintMaterial,
00028 G4String airMaterial,
00029 BDSTiltOffset tiltOffset):
00030 BDSAcceleratorComponent(name, 1e-7, 0, "scintillatorscreen", tiltOffset),
00031 _scintillatorLayerMaterial(BDSMaterials::Instance()->GetMaterial(scintMaterial.data())),
00032 _airMaterial(BDSMaterials::Instance()->GetMaterial(airMaterial.data())),
00033 _screenAngle(angle),_scintillatorThickness(tScint)
00034 {
00035
00036 _screenRotationMatrix = new G4RotationMatrix();
00037 _screenAngle=angle;
00038 _screenRotationMatrix->rotateY(_screenAngle);
00039 }
00040
00041 void BDSScintillatorScreen::Build()
00042 {
00043 SetVisAttributes();
00044 ComputeDimensions();
00045 BuildContainerLogicalVolume();
00046 BuildScintillatorScreen();
00047 }
00048
00049 void BDSScintillatorScreen::SetVisAttributes()
00050 {
00051 G4VisAttributes* itsVisAttributes=new G4VisAttributes(G4Colour(0.3,0.4,0.2));
00052 itsVisAttributes->SetForceSolid(true);
00053
00054 _visAttFront=new G4VisAttributes(G4Colour(1.0,0.0,0.0,0.5));
00055 _visAttScint=new G4VisAttributes(G4Colour(0.0,1.0,0.0,0.5));
00056 _visAttBase =new G4VisAttributes(G4Colour(0.3,0.3,0.3,0.5));
00057 _visAttSampler=new G4VisAttributes(G4Colour(0.2,0.2,0.0,0.5));
00058
00059
00060 _visAttFront->SetForceSolid(true);
00061 _visAttScint->SetForceSolid(true);
00062 _visAttBase->SetForceSolid(true);
00063 _visAttSampler->SetForceSolid(true);
00064 }
00065
00066 void BDSScintillatorScreen::BuildFrontLayer(){
00067
00068 itsFrontLayerSolid = new G4Box("CelluloseFront",_screenWidth/2.0,_screenHeight/2.0,_frontThickness/2.0);
00069 itsFrontLayerLog = new G4LogicalVolume(itsFrontLayerSolid,BDSMaterials::Instance()->GetMaterial("Cellulose"),"CelluloseFront",0,0,0);
00070 itsFrontLayerLog->SetVisAttributes(_visAttFront);
00071 G4double dispZ=_frontThickness/2.0-_screenThickness/2.0;
00072 itsFrontLayerPhys = new G4PVPlacement(
00073 _screenRotationMatrix,
00074 G4ThreeVector(0,0,dispZ),
00075 itsFrontLayerLog,
00076 "ScreenCelluloseFrontPhys",
00077 containerLogicalVolume,
00078 false,
00079 0,
00080 BDSGlobalConstants::Instance()->GetCheckOverlaps()
00081 );
00082 SetMultiplePhysicalVolumes(itsFrontLayerPhys);
00083 }
00084
00085 void BDSScintillatorScreen::BuildCameraScoringPlane(){
00086 G4String tmp = "_cameraScoringPlane";
00087 _scoringPlaneName=name+tmp;
00088 int nThisSampler= BDSSampler::GetNSamplers() + 1;
00089 G4String ident="_camera";
00090 _samplerName = ("Sampler_"+BDSGlobalConstants::Instance()->StringFromInt(nThisSampler)+"_"+_scoringPlaneName);
00091
00092
00093 itsCameraScoringPlaneSolid = new G4Box("CameraScoringPlaneSolid",chordLength/2.0,_yLength/2.0,_scoringPlaneThickness/2.0);
00094 itsCameraScoringPlaneLog = new G4LogicalVolume(itsCameraScoringPlaneSolid,BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetVacuumMaterial()),"CameraScoringPlaneLog",0,0,0);
00095 itsCameraScoringPlaneLog->SetVisAttributes(_visAttScint);
00096 G4double dispX=-_xLength/2.0+_scoringPlaneThickness/2.0;
00097 G4double dispY=0;
00098 G4double dispZ=0;
00099 new G4PVPlacement(BDSGlobalConstants::Instance()->RotY90(),G4ThreeVector(dispX,dispY,dispZ),itsCameraScoringPlaneLog,_samplerName,
00100 containerLogicalVolume,false,0,BDSGlobalConstants::Instance()->GetCheckOverlaps());
00101
00102 itsCameraScoringPlaneLog->SetSensitiveDetector(BDSSampler::GetSensitiveDetector());
00103
00104 BDSSampler::AddExternalSampler(_samplerName+"_1");
00105 #ifndef NOUSERLIMITS
00106 G4double maxStepFactor=0.5;
00107 G4UserLimits* itsScoringPlaneUserLimits = new G4UserLimits();
00108 itsScoringPlaneUserLimits->SetMaxAllowedStep(_scoringPlaneThickness*maxStepFactor);
00109 itsCameraScoringPlaneLog->SetUserLimits(itsScoringPlaneUserLimits);
00110 #endif
00111 }
00112
00113
00114 void BDSScintillatorScreen::BuildScreenScoringPlane(){
00115 G4String tmp = "_screenScoringPlane";
00116 _screenScoringPlaneName=name+tmp;
00117 int nThisSampler= BDSSampler::GetNSamplers() + 1;
00118 G4String ident="_camera";
00119 _screenSamplerName = ("Sampler_"+BDSGlobalConstants::Instance()->StringFromInt(nThisSampler)+"_"+_screenScoringPlaneName);
00120
00121
00122 itsScreenScoringPlaneSolid = new G4Box("ScreenScoringPlaneSolid",_screenWidth/2.0,_screenHeight/2.0,_scoringPlaneThickness/2.0);
00123 itsScreenScoringPlaneLog = new G4LogicalVolume(itsScreenScoringPlaneSolid,BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetVacuumMaterial()),"ScreenScoringPlaneLog",0,0,0);
00124 itsScreenScoringPlaneLog->SetVisAttributes(_visAttSampler);
00125 G4double dispX=0;
00126 G4double dispY=0;
00127 G4double dispZ=sqrt(2)*(-_screenThickness/2.0- _scoringPlaneThickness/2.0);
00128 new G4PVPlacement(_screenRotationMatrix,G4ThreeVector(dispX,dispY,dispZ),itsScreenScoringPlaneLog,_screenSamplerName,
00129 containerLogicalVolume,false,0,BDSGlobalConstants::Instance()->GetCheckOverlaps());
00130
00131 itsScreenScoringPlaneLog->SetSensitiveDetector(BDSSampler::GetSensitiveDetector());
00132
00133 BDSSampler::AddExternalSampler(_screenSamplerName+"_1");
00134 #ifndef NOUSERLIMITS
00135 G4double maxStepFactor=0.5;
00136 G4UserLimits* itsScoringPlaneUserLimits = new G4UserLimits();
00137 itsScoringPlaneUserLimits->SetMaxAllowedStep(_scoringPlaneThickness*maxStepFactor);
00138 itsScreenScoringPlaneLog->SetUserLimits(itsScoringPlaneUserLimits);
00139 #endif
00140 }
00141
00142 void BDSScintillatorScreen::BuildScintillatorLayer(){
00143
00144
00145 G4String name = "ScintillatorLayerPhys";
00146 G4double dispZ=0;
00147 itsScintillatorLayerSolid = new G4Box("ScintillatorLayerSolid",_screenWidth/2.0,_screenHeight/2.0,_scintillatorThickness/2.0);
00148 itsScintillatorLayerLog = new G4LogicalVolume(itsScintillatorLayerSolid,_scintillatorLayerMaterial,"PhosphorLayer",0,0,0);
00149
00150 itsScintillatorLayerLog->SetVisAttributes(_visAttScint);
00151
00152
00153
00154 int nThisSampler= BDSSampler::GetNSamplers() + 1;
00155 _screenSamplerName = ("Sampler_"+BDSGlobalConstants::Instance()->StringFromInt(nThisSampler)+"_"+name);
00156
00157
00158 itsScintillatorLayerPhys= new G4PVPlacement(_screenRotationMatrix,G4ThreeVector(0,0,dispZ),itsScintillatorLayerLog,_screenSamplerName.c_str(),
00159 containerLogicalVolume,false,0,BDSGlobalConstants::Instance()->GetCheckOverlaps());
00160 SetMultiplePhysicalVolumes(itsScintillatorLayerPhys);
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 }
00177
00178 void BDSScintillatorScreen::BuildBaseLayer(){
00179
00180 G4double dispZ=_scintillatorThickness+_frontThickness+_baseThickness/2.0-_screenThickness/2.0;
00181 itsBaseLayerSolid = new G4Box("PETLayer",_screenWidth/2.0,_screenHeight/2.0,_baseThickness/2.0);
00182 itsBaseLayerLog = new G4LogicalVolume(itsBaseLayerSolid,BDSMaterials::Instance()->GetMaterial("PET"),"PETLayer",0,0,0);
00183
00184 itsBaseLayerLog->SetVisAttributes(_visAttBase);
00185 itsBaseLayerPhys = new G4PVPlacement(_screenRotationMatrix,G4ThreeVector(0,0,dispZ),itsBaseLayerLog,"ScreenPETLayer",
00186 containerLogicalVolume,false,0,BDSGlobalConstants::Instance()->GetCheckOverlaps());
00187 SetMultiplePhysicalVolumes(itsBaseLayerPhys);
00188 }
00189
00190 void BDSScintillatorScreen::BuildBackLayer(){
00191 G4double dispZ=_frontThickness+_scintillatorThickness+_baseThickness+_backThickness/2.0-_screenThickness/2.0;
00192 itsBackLayerSolid = new G4Box("CelluloseBack",_screenWidth/2.0,_screenHeight/2.0,_backThickness/2.0);
00193 itsBackLayerLog = new G4LogicalVolume(itsBackLayerSolid,BDSMaterials::Instance()->GetMaterial("Cellulose"),"CelluloseBack",0,0,0);
00194 itsBackLayerLog->SetVisAttributes(_visAttFront);
00195 itsBackLayerPhys = new G4PVPlacement(_screenRotationMatrix,G4ThreeVector(0,0,dispZ),itsBackLayerLog,"ScreenCelluloseBack",
00196 containerLogicalVolume,false,0,BDSGlobalConstants::Instance()->GetCheckOverlaps());
00197 SetMultiplePhysicalVolumes(itsBackLayerPhys);
00198 }
00199
00200 void BDSScintillatorScreen::BuildOpticalSurfaces(){
00201
00202
00203 G4OpticalSurface* OpSurface=new G4OpticalSurface("OpSurface");
00204
00205 new G4LogicalBorderSurface("phosphor_PET_surface", itsScintillatorLayerPhys, itsBaseLayerPhys, OpSurface);
00206 G4double sigma_alpha=1.0;
00207
00208 OpSurface -> SetType(dielectric_metal);
00209 OpSurface -> SetModel(unified);
00210 OpSurface -> SetFinish(ground);
00211 OpSurface -> SetSigmaAlpha(sigma_alpha);
00212 G4MaterialPropertiesTable* SMPT = new G4MaterialPropertiesTable();
00213 SMPT->AddConstProperty("REFLECTIVITY",0.8);
00214 SMPT->AddConstProperty("RINDEX",1.5750);
00215 OpSurface->SetMaterialPropertiesTable(SMPT);
00216
00217
00218
00219 G4OpticalSurface* OpSurface2=new G4OpticalSurface("OpSurface2");
00220
00221 new G4LogicalBorderSurface("phosphor_cellulose_surface", itsScintillatorLayerPhys, itsFrontLayerPhys, OpSurface2);
00222 OpSurface2 -> SetType(dielectric_dielectric);
00223 OpSurface2 -> SetModel(unified);
00224 OpSurface2 -> SetFinish(ground);
00225 OpSurface2 -> SetSigmaAlpha(sigma_alpha);
00226 G4MaterialPropertiesTable* SMPT2 = new G4MaterialPropertiesTable();
00227 SMPT2->AddConstProperty("REFLECTIVITY",0.0);
00228 SMPT2->AddConstProperty("RINDEX",1.532);
00229 OpSurface2->SetMaterialPropertiesTable(SMPT2);
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 }
00247
00248
00249 void BDSScintillatorScreen::BuildScintillatorScreen()
00250 {
00251 BuildScintillatorMaterial();
00252 BuildScintillatorLayer();
00253 BuildScreenScoringPlane();
00254 BuildCameraScoringPlane();
00255
00256 if(BDSGlobalConstants::Instance()->GetSensitiveComponents()){
00257 RegisterSensitiveVolume(itsScintillatorLayerLog);
00258 }
00259 G4cout << "BDSScintillatorScreen: finished building geometry" << G4endl;
00260 }
00261
00262 void BDSScintillatorScreen::BuildScintillatorMaterial(){
00263 BuildScintillatorCompound();
00264 BuildScintillatorOpticalProperties();
00265 }
00266
00267 void BDSScintillatorScreen::BuildScintillatorCompound(){
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 }
00280
00281 void BDSScintillatorScreen::BuildScintillatorOpticalProperties(){
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 }
00298
00299
00300 void BDSScintillatorScreen::ComputeDimensions()
00301 {
00302 _screenWidth=1*CLHEP::m;
00303 _screenHeight=3*CLHEP::cm;
00304
00305
00306 _frontThickness=0;
00307 _baseThickness=0;
00308 _backThickness=0;
00309
00310
00311 _scoringPlaneThickness=1*CLHEP::um;
00312
00313 _totalThickness =
00314 _frontThickness+
00315 _scintillatorThickness+
00316 _baseThickness+
00317 _backThickness+
00318 _scoringPlaneThickness;
00319
00320 _screenThickness = _totalThickness - _scoringPlaneThickness;
00321
00322
00323 G4double z_wid = _screenWidth * std::sin(std::abs(_screenAngle));
00324 G4double z_thi = _totalThickness * std::cos(_screenAngle);
00325 G4double x_wid = _screenWidth * std::cos(std::abs(_screenAngle));
00326 G4double x_thi = _totalThickness * std::sin(_screenAngle);
00327 chordLength = (z_wid + z_thi);
00328 _xLength = x_wid +x_thi + 2*_scoringPlaneThickness;
00329 _yLength = _screenHeight;
00330 }
00331
00332 void BDSScintillatorScreen::BuildContainerLogicalVolume()
00333 {
00334 containerSolid = new G4Box(name + "_container_solid",
00335 _xLength,
00336 _yLength,
00337 chordLength/2.0);
00338
00339 containerLogicalVolume = new G4LogicalVolume(containerSolid,
00340 _airMaterial,
00341 name + "_container_lv");
00342 #ifndef NOUSERLIMITS
00343 G4double maxStepFactor=0.5;
00344 G4UserLimits* itsMarkerUserLimits = new G4UserLimits();
00345 itsMarkerUserLimits->SetMaxAllowedStep(chordLength*maxStepFactor);
00346 itsMarkerUserLimits->SetUserMinEkine(BDSGlobalConstants::Instance()->GetThresholdCutCharged());
00347 containerLogicalVolume->SetUserLimits(itsMarkerUserLimits);
00348 #endif
00349 }
00350
00351
00352 BDSScintillatorScreen::~BDSScintillatorScreen()
00353 {
00354 }