00001 #include "BDSGlobalConstants.hh"
00002 #include "BDSScreenLayer.hh"
00003 #include "BDSMaterials.hh"
00004 #include "BDSSampler.hh"
00005 #include "BDSSamplerSD.hh"
00006 #include "G4Box.hh"
00007 #include "G4VisAttributes.hh"
00008 #include "G4LogicalVolume.hh"
00009 #include "G4VPhysicalVolume.hh"
00010 #include "G4PVPlacement.hh"
00011 #include "G4UserLimits.hh"
00012 #include "G4OpticalSurface.hh"
00013 #include "G4LogicalBorderSurface.hh"
00014
00015 BDSScreenLayer::BDSScreenLayer(){
00016 }
00017
00018 BDSScreenLayer::BDSScreenLayer (G4ThreeVector size, G4String name, G4String material, G4double grooveWidth, G4double grooveSpatialFrequency):
00019 _size(size), _name(name),_material(material),_grooveWidth(grooveWidth),_grooveSpatialFrequency(grooveSpatialFrequency)
00020 {
00021 _nGrooves=0;
00022 _color=G4Colour(0.1,0.8,0.1,0.3);
00023 build();
00024 }
00025
00026 void BDSScreenLayer::build(){
00027 buildGroove();
00028 buildScreen();
00029 visAtt();
00030 }
00031
00032 void BDSScreenLayer::buildGroove(){
00033 if (_grooveWidth==0){
00034 _grooveSolid=NULL;
00035 _grooveLog=NULL;
00036 return;
00037 }
00038 _grooveSolid = new G4Box((_name+"_grooveSolid").c_str(),_grooveWidth/2.0, _size.y()/2.0, _size.z()/2.0);
00039 _grooveLog = new G4LogicalVolume(_grooveSolid,BDSMaterials::Instance()->GetMaterial("air"),(_name+"_grooveLog").c_str(),0,0,0);
00040 }
00041
00042 void BDSScreenLayer::buildScreen(){
00043 _solid = new G4Box((_name+"_solid").c_str(),_size.x()/2.0,_size.y()/2.0,_size.z()/2.0);
00044 _log = new G4LogicalVolume(_solid,BDSMaterials::Instance()->GetMaterial(_material),(_name+"_log").c_str(),0,0,0);
00045 cutGrooves();
00046 }
00047
00048 void BDSScreenLayer::cutGrooves(){
00049 if(_grooveWidth>0){
00050 for(G4double xPosition=-_size.x()/2.0+_grooveWidth/2.0;
00051 xPosition<((_size.x()/2.0)-_grooveWidth/2.0);
00052 xPosition+=_grooveSpatialFrequency){
00053 cutGroove(xPosition);
00054 }
00055 }
00056 }
00057
00058 void BDSScreenLayer::cutGroove(G4double xPosition){
00059 if (!_grooveLog) return;
00060 G4ThreeVector pos;
00061 pos.setX(xPosition);
00062 pos.setY(0);
00063 pos.setZ(0);
00064 new G4PVPlacement((G4RotationMatrix*)NULL,
00065 pos,
00066 _grooveLog,
00067 (G4String)(_name+"_groove"),
00068 _log,
00069 true,
00070 _nGrooves,
00071 false
00072 );
00073 _nGrooves++;
00074 }
00075
00076 void BDSScreenLayer::visAtt()
00077 {
00078 G4VisAttributes* visAtt=new G4VisAttributes(_color);
00079 visAtt->SetForceSolid(true);
00080 G4VisAttributes* visAttGroove=new G4VisAttributes(G4Colour(0.0,0.0,0.0));
00081 visAttGroove->SetForceSolid(true);
00082 _log->SetVisAttributes(visAtt);
00083 if(_grooveLog){
00084 _grooveLog->SetVisAttributes(visAttGroove);
00085 }
00086 }
00087
00088 void BDSScreenLayer::phys(G4PVPlacement* phys){
00089 if(phys->GetLogicalVolume() != log()){
00090 G4cerr << "BDSScreenLayer - error: physical volume placement does not match logical volume. Exiting." << G4endl;
00091 exit(1);
00092 }
00093 _phys=phys;
00094 }
00095
00096 void BDSScreenLayer::color(G4Color col){
00097 _color=col;
00098 visAtt();
00099 }
00100
00101 void BDSScreenLayer::backInternalMirror(){
00102 _internalMirror = new InternalMirror(InternalMirror::_BACK, _size,_material,_log,_phys);
00103 }
00104
00105 void BDSScreenLayer::frontInternalMirror(){
00106 _internalMirror = new InternalMirror(InternalMirror::_FRONT,_size,_material,_log,_phys);
00107 }
00108
00109 BDSScreenLayer::InternalMirror::~InternalMirror(){
00110 }
00111
00112 BDSScreenLayer::InternalMirror::InternalMirror(G4int varside, G4ThreeVector size, G4String material, G4LogicalVolume* motherLog, G4PVPlacement* motherPhys):_side(varside),_motherSize(size),_motherMaterial(material),_motherLog(motherLog),_motherPhys(motherPhys)
00113 {
00114 _thickness=1e-9*CLHEP::m;
00115 compute();
00116 geom();
00117 place();
00118 optical();
00119 }
00120
00121 void BDSScreenLayer::InternalMirror::geom(){
00122 _solid = new G4Box("internalMirrorSolid",_motherSize.x()/2.0,_motherSize.y()/2.0,_thickness);
00123 _log = new G4LogicalVolume(_solid,BDSMaterials::Instance()->GetMaterial("titanium"),"internalMirrorLog",0,0,0);
00124 }
00125
00126 void BDSScreenLayer::InternalMirror::place(){
00127 _phys=new G4PVPlacement((G4RotationMatrix*)NULL,
00128 G4ThreeVector(0,0,_pos),
00129 _log,
00130 "internalMirrorPhys",
00131 _motherLog,
00132 false,
00133 0,
00134 true
00135 );
00136 }
00137
00138 void BDSScreenLayer::InternalMirror::optical(){
00139 G4OpticalSurface* OpSurface=new G4OpticalSurface("OpSurface");
00140
00141 new G4LogicalBorderSurface("LogSurface", _motherPhys, _phys, OpSurface);
00142
00143 OpSurface -> SetType(dielectric_metal);
00144 OpSurface -> SetModel(unified);
00145 OpSurface -> SetFinish(polished);
00146 G4MaterialPropertiesTable* SMPT = new G4MaterialPropertiesTable();
00147 SMPT->AddConstProperty("REFLECTIVITY",0.8);
00148
00149 OpSurface->SetMaterialPropertiesTable(SMPT);
00150 }
00151
00152 void BDSScreenLayer::InternalMirror::compute(){
00153 G4double sign=0;
00154 try{
00155 if(_side==_BACK){
00156 sign = 1;
00157 }else if(_side==_FRONT){
00158 sign = -1;
00159 }else{
00160 throw 1;
00161 }
00162 }catch(int e){
00163 G4cerr<< "BDSScreenLayer::computInternalMirror - exception number " << e << " occurred. Exiting." << G4endl;
00164 exit(e);
00165 }
00166
00167 _pos = sign*(_motherSize.z()/2.0-_thickness/2.0);
00168 }
00169
00170 void BDSScreenLayer::sampler(){
00171 G4String samplerName = _name + "_1";
00172
00173 _log->SetSensitiveDetector(BDSSampler::GetSensitiveDetector());
00174 BDSSampler::AddExternalSampler(samplerName);
00175
00176 #ifndef NOUSERLIMITS
00177 G4double maxStepFactor=0.5;
00178 G4UserLimits* itsScoringPlaneUserLimits = new G4UserLimits();
00179 itsScoringPlaneUserLimits->SetMaxAllowedStep(_size.z()*maxStepFactor);
00180 _log->SetUserLimits(itsScoringPlaneUserLimits);
00181 #endif
00182 }
00183
00184
00185
00186 BDSScreenLayer::~BDSScreenLayer(){
00187 }