/scratch0/jsnuveri/BDSIM/BDSIMgit/bdsim/src/BDSScintillatorScreen.cc

00001 /* BDSIM code.    
00002 A scintillator screen.
00003 Work in progress.  
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   //Set the rotation of the screen
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   //The cellulose protective layerx
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   //Build and place the volume...
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   //SPM bdsOutput->nSamplers++;
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   //Build and place the volume...
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   //SPM bdsOutput->nSamplers++;
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 // The phosphor layer
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   //Build and place the volume...
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     (*LogVol)[_screenSamplerName]=itsScintillatorLayerLog;
00164   }
00165   itsScintillatorLayerLog->SetSensitiveDetector(BDSSampler::GetSensitiveDetector());
00166   //SPM bdsOutput->nSamplers++;
00167   BDSSampler::AddExternalSampler();
00168   bdsOutput->SampName.push_back(_screenSamplerName+"_1");
00169 #ifndef NOUSERLIMITS
00170   G4double maxStepFactor=0.5;
00171   G4UserLimits* itsScintillatorLayerUserLimits =  new G4UserLimits();
00172   itsScintillatorLayerUserLimits->SetMaxAllowedStep(_scoringPlaneThickness*maxStepFactor);
00173   itsScintillatorLayerLog->SetUserLimits(itsScintillatorLayerUserLimits);
00174 #endif
00175   */
00176 }
00177 
00178 void BDSScintillatorScreen::BuildBaseLayer(){
00179   //The PET backing layer
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   //Add the optical surfaces.
00202   //Mirrored surface between the phosphor and the PET backing.
00203   G4OpticalSurface* OpSurface=new G4OpticalSurface("OpSurface");
00204   /*G4LogicalBorderSurface* Surface = */
00205   new G4LogicalBorderSurface("phosphor_PET_surface", itsScintillatorLayerPhys, itsBaseLayerPhys, OpSurface);
00206   G4double sigma_alpha=1.0;
00207   //TiO2 particles provide the reflectivity in the PET layer hence dielectric-metal
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   //Surface between the phosphor and the cellulose front.
00219   G4OpticalSurface* OpSurface2=new G4OpticalSurface("OpSurface2");
00220   /*G4LogicalBorderSurface* Surface2 = */ 
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   //Surface between the cellulose and the experimental hall.
00232   
00233   /*
00234   G4OpticalSurface* OpSurface3=new G4OpticalSurface("OpSurface3");
00235   G4LogicalBorderSurface* Surface3 = new 
00236     G4LogicalBorderSurface("cellulose_hall_surface", itsFrontLayerPhys, itsMarkerPhysicalVolume, OpSurface3);
00237   OpSurface3 -> SetType(dielectric_dielectric);
00238   OpSurface3 -> SetModel(unified);
00239   OpSurface3 -> SetFinish(ground);
00240   OpSurface3 -> SetSigmaAlpha(sigma_alpha);
00241   G4MaterialPropertiesTable* SMPT3 = new G4MaterialPropertiesTable();
00242   SMPT3->AddConstProperty("REFLECTIVITY",0.0);
00243   SMPT3->AddConstProperty("RINDEX",1.0);
00244   OpSurface3->SetMaterialPropertiesTable(SMPT3);
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   //Scintillator grains sudpended in a polyurethane elastomer with a specific fill factor
00271   G4double fill_factor=0.5; //i.e. fraction by volume
00272   G4double yag_screen_density=fill_factor*BDSMaterials::Instance()->GetMaterial("YAG")->GetDensity()+(1-fill_factor)*BDSMaterials::Instance()->GetMaterial("Polyurethane")->GetDensity();
00273   G4double yag_fraction_by_mass=fill_factor*BDSMaterials::Instance()->GetMaterial("YAG")->GetDensity()/yag_screen_density;
00274   G4double pur_fraction_by_mass=1-yag_fraction_by_mass;
00275   _scintillatorLayerMaterial = new G4Material("ScintillatorMaterial", yag_screen_density, 2);
00276   _scintillatorLayerMaterial->AddMaterial(BDSMaterials::Instance()->GetMaterial("YAG"), yag_fraction_by_mass);
00277   _scintillatorLayerMaterial->AddMaterial(BDSMaterials::Instance()->GetMaterial("Polyurethane"), pur_fraction_by_mass);
00278   */
00279 }
00280 
00281 void BDSScintillatorScreen::BuildScintillatorOpticalProperties(){
00282   //Fill the material properties table of the _scintillatorLayerMaterial
00283 
00284   /*The below is required for mie scattering
00285   G4double scatteringLength=2.17*CLHEP::um;
00286   G4double anisotropyFactor=0.800;
00287   _mptScintillatorMaterial->AddConstProperty("MIEHG",scatteringLength);
00288   _mptScintillatorMaterial->AddConstProperty("MIEHG_FORWARD",anisotropyFactor); 
00289   _mptScintillatorMaterial->AddConstProperty("MIEHG_BACKWARD",0.0);
00290   _mptScintillatorMaterial->AddConstProperty("MIEHG_FORWARD_RATIO",1.0);
00291   //Absoroption length is irrelevant as the screen should be pretty thin
00292   //  _mptScintillatorMaterial->AddProperty("ABSLENGTH",    PhotonEnergy, Absorption1,     nEntries)
00293   //    ->SetSpline(true);
00294   */
00295   
00296 
00297 }
00298 
00299 
00300 void BDSScintillatorScreen::ComputeDimensions()
00301 {
00302   _screenWidth=1*CLHEP::m;
00303   _screenHeight=3*CLHEP::cm;
00304 
00305   //Length due to the screen thickness
00306   _frontThickness=0;//13*CLHEP::um;
00307   _baseThickness=0;//275*CLHEP::um;
00308   _backThickness=0;//13*CLHEP::um;
00309 
00310   //The scoring plane...
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   //Compute the marker volume length according to the screen thickness and width.
00323   G4double z_wid = _screenWidth * std::sin(std::abs(_screenAngle));//Length due to the screen width and angle
00324   G4double z_thi = _totalThickness * std::cos(_screenAngle);//Length due to the screen thickness
00325   G4double x_wid = _screenWidth * std::cos(std::abs(_screenAngle));//Length due to the screen width and angle
00326   G4double x_thi = _totalThickness * std::sin(_screenAngle);//Length due to the screen thickness
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); //z half length 
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 }

Generated on 28 Jun 2015 for BDSIM by  doxygen 1.4.7