00001 #include "BDSDebug.hh"
00002 #include "BDSExecOptions.hh"
00003 #include "BDSGlobalConstants.hh"
00004 #include "BDSGeometrySQL.hh"
00005 #include "G4Box.hh"
00006 #include "G4Trap.hh"
00007 #include "G4Tubs.hh"
00008 #include "G4EllipticalTube.hh"
00009 #include "G4Cons.hh"
00010 #include "G4EllipticalCone.hh"
00011 #include "G4Torus.hh"
00012 #include "G4SubtractionSolid.hh"
00013 #include "G4IntersectionSolid.hh"
00014 #include "G4UnionSolid.hh"
00015 #include "G4Polycone.hh"
00016 #include "G4VisAttributes.hh"
00017 #include "G4LogicalVolume.hh"
00018 #include "G4VPhysicalVolume.hh"
00019 #include "G4PVPlacement.hh"
00020 #include "G4UserLimits.hh"
00021 #include "G4ProductionCuts.hh"
00022 #include "G4RegionStore.hh"
00023 #include "BDSMySQLWrapper.hh"
00024 #include "BDSMaterials.hh"
00025 #include "BDSSamplerSD.hh"
00026 #include "BDSSampler.hh"
00027 #include "BDSPCLTube.hh"
00028 #include <vector>
00029 #include <cstdlib>
00030 #include <cstring>
00031
00032 BDSGeometrySQL::BDSGeometrySQL(G4String DBfile, G4double markerlength, G4LogicalVolume *marker):
00033 rotateComponent(NULL),itsMarkerLength(markerlength),itsMarkerVol(marker)
00034 {
00035 VOL_LIST.push_back(itsMarkerVol);
00036 #ifdef BDSDEBUG
00037 G4cout << "BDSGeometrySQL constructor: loading SQL file " << DBfile << G4endl;
00038 #endif
00039 ifs.open(DBfile.c_str());
00040 G4String exceptionString = "Unable to load SQL database file: " + DBfile;
00041 if(!ifs) G4Exception(exceptionString.c_str(), "-1", FatalException, "");
00042 align_in_volume = NULL;
00043 align_out_volume = NULL;
00044 HasFields = false;
00045 nPoleField = 0;
00046 HasUniformField = false;
00047
00048
00049 G4String pRegName="precisionRegionSQL";
00050 _precisionRegionSQL = G4RegionStore::GetInstance()->FindOrCreateRegion(pRegName);
00051
00052 G4ProductionCuts* theProductionCuts = new G4ProductionCuts();
00053 if(BDSGlobalConstants::Instance()->GetProdCutPhotonsP()>0)
00054 theProductionCuts->SetProductionCut(BDSGlobalConstants::Instance()->GetProdCutPhotonsP(),G4ProductionCuts::GetIndex("gamma"));
00055 if(BDSGlobalConstants::Instance()->GetProdCutElectronsP()>0)
00056 theProductionCuts->SetProductionCut(BDSGlobalConstants::Instance()->GetProdCutElectronsP(),G4ProductionCuts::GetIndex("e-"));
00057 if(BDSGlobalConstants::Instance()->GetProdCutPositronsP()>0)
00058 theProductionCuts->SetProductionCut(BDSGlobalConstants::Instance()->GetProdCutPositronsP(),G4ProductionCuts::GetIndex("e+"));
00059 _precisionRegionSQL->SetProductionCuts(theProductionCuts);
00060
00061
00062 G4String vRegName="approximationRegionSQL";
00063 _approximationRegionSQL = G4RegionStore::GetInstance()->FindOrCreateRegion(vRegName);
00064
00065 G4ProductionCuts* approxProductionCuts = new G4ProductionCuts();
00066 approxProductionCuts->SetProductionCut(BDSGlobalConstants::Instance()->GetProdCutPhotonsA(),G4ProductionCuts::GetIndex("gamma"));
00067 approxProductionCuts->SetProductionCut(BDSGlobalConstants::Instance()->GetProdCutElectronsA(),G4ProductionCuts::GetIndex("e-"));
00068 approxProductionCuts->SetProductionCut(BDSGlobalConstants::Instance()->GetProdCutPositronsA(),G4ProductionCuts::GetIndex("e+"));
00069 _approximationRegionSQL->SetProductionCuts(approxProductionCuts);
00070
00071 Construct();
00072 }
00073
00074 BDSGeometrySQL::~BDSGeometrySQL(){
00075 }
00076
00077 void BDSGeometrySQL::Construct()
00078 {
00079 G4String file;
00080 char buffer[1000];
00081 while (ifs>>file)
00082 {
00083 if(file.contains("#")) ifs.getline(buffer,1000);
00084 else{
00085 G4String sBDSPATH = BDSExecOptions::Instance()->GetBDSIMPATH();
00086 G4String fullPath = sBDSPATH + file;
00087 BuildSQLObjects(fullPath);}
00088 }
00089
00090
00091 ifs.close();
00092 }
00093
00094 void BDSGeometrySQL::BuildSQLObjects(G4String file)
00095 {
00096 #ifdef BDSDEBUG
00097 G4cout << "BDSGeometrySQL::BuildSQLObjects Loading file " << file << G4endl;
00098 #endif
00099
00100 BDSMySQLWrapper sql(file);
00101 itsSQLTable=sql.ConstructTable();
00102
00103 for (G4int i=0; i<(G4int)itsSQLTable.size(); i++)
00104 {
00105 #ifdef BDSDEBUG
00106 itsSQLTable[i]->Print();
00107 #endif
00108 _TableName = itsSQLTable[i]->GetName();
00109 #ifdef BDSDEBUG
00110 G4cout << __METHOD_NAME__ << " i = " << i << ", TableName = " << _TableName << G4endl;
00111 #endif
00112 G4int pos = _TableName.find("_");
00113 G4String ObjectType = _TableName.substr(pos+1,_TableName.length() - pos);
00114 G4String::caseCompare cmpmode = G4String::ignoreCase;
00115 _NVariables = itsSQLTable[i]->GetVariable(0)->GetNVariables();
00116 for(G4int k=0; k<_NVariables; k++){
00117 SetCommonParams(itsSQLTable[i], k);
00118 G4LogicalVolume* logVol;
00119 if(ObjectType.compareTo("CONE",cmpmode)==0) logVol = BuildCone(itsSQLTable[i],k);
00120 else if(ObjectType.compareTo("ELLIPTICALCONE",cmpmode)==0) logVol = BuildEllipticalCone(itsSQLTable[i],k);
00121 else if(ObjectType.compareTo("POLYCONE",cmpmode)==0) logVol = BuildPolyCone(itsSQLTable[i],k);
00122 else if(ObjectType.compareTo("BOX",cmpmode)==0) logVol = BuildBox(itsSQLTable[i],k);
00123 else if(ObjectType.compareTo("TRAP",cmpmode)==0) logVol = BuildTrap(itsSQLTable[i],k);
00124 else if(ObjectType.compareTo("TORUS",cmpmode)==0) logVol = BuildTorus(itsSQLTable[i],k);
00125 else if(ObjectType.compareTo("SAMPLER",cmpmode)==0) logVol = BuildSampler(itsSQLTable[i],k);
00126 else if(ObjectType.compareTo("TUBE",cmpmode)==0) logVol = BuildTube(itsSQLTable[i],k);
00127 else if(ObjectType.compareTo("ELLIPTICALTUBE",cmpmode)==0) logVol = BuildEllipticalTube(itsSQLTable[i],k);
00128 else if(ObjectType.compareTo("PCLTUBE",cmpmode)==0) logVol = BuildPCLTube(itsSQLTable[i],k);
00129 else {
00130 G4cerr << __METHOD_NAME__ << ObjectType << " not known" << G4endl;
00131 exit(1);
00132 }
00133
00134 SetLogVolAtt(logVol, _lengthUserLimit);
00135 VOL_LIST.push_back(logVol);
00136 }
00137 PlaceComponents(itsSQLTable[i], VOL_LIST);
00138 }
00139 }
00140
00141 void BDSGeometrySQL::SetCommonParams(BDSMySQLTable* aSQLTable, G4int k){
00142
00143 _VisRed = _VisGreen = _VisBlue = 0.5;
00144 _VisAlpha = 0.5;
00145 _VisType = "S";
00146 _Material = BDSGlobalConstants::Instance()->GetVacuumMaterial();
00147 _Name="";
00148 _PrecisionRegion=0;
00149 _ApproximationRegion=0;
00150
00151 if(aSQLTable->GetVariable("RED")!=NULL)
00152 _VisRed = aSQLTable->GetVariable("RED")->GetDblValue(k);
00153 if(aSQLTable->GetVariable("BLUE")!=NULL)
00154 _VisBlue = aSQLTable->GetVariable("BLUE")->GetDblValue(k);
00155 if(aSQLTable->GetVariable("GREEN")!=NULL)
00156 _VisGreen = aSQLTable->GetVariable("GREEN")->GetDblValue(k);
00157 if(aSQLTable->GetVariable("ALPHA")!=NULL)
00158 _VisAlpha = aSQLTable->GetVariable("ALPHA")->GetDblValue(k);
00159 if(aSQLTable->GetVariable("VISATT")!=NULL)
00160 _VisType = aSQLTable->GetVariable("VISATT")->GetStrValue(k);
00161 if(aSQLTable->GetVariable("MATERIAL")!=NULL)
00162 _Material = aSQLTable->GetVariable("MATERIAL")->GetStrValue(k);
00163 if(aSQLTable->GetVariable("PRECISIONREGION")!=NULL)
00164 _PrecisionRegion = aSQLTable->GetVariable("PRECISIONREGION")->GetIntValue(k);
00165 if(aSQLTable->GetVariable("APPROXIMATIONREGION")!=NULL)
00166 _ApproximationRegion = aSQLTable->GetVariable("APPROXIMATIONREGION")->GetIntValue(k);
00167 if(aSQLTable->GetVariable("NAME")!=NULL)
00168 _Name = aSQLTable->GetVariable("NAME")->GetStrValue(k);
00169 if(_Name=="_SQL") _Name = _TableName+BDSGlobalConstants::Instance()->StringFromInt(k) + "_SQL";
00170 if(_Name=="") _Name = _TableName+BDSGlobalConstants::Instance()->StringFromInt(k);
00171 _Name = itsMarkerVol->GetName()+"_"+_Name;
00172 #ifdef BDSDEBUG
00173 G4cout << __METHOD_NAME__ << " k = " << k << ", _Name = " << _Name << G4endl;
00174 #endif
00175 }
00176
00177 void BDSGeometrySQL::SetPlacementParams(BDSMySQLTable* aSQLTable, G4int k){
00178
00179 _PosX = _PosY = _PosZ = 0.;
00180 _RotPsi = _RotTheta = _RotPhi = 0.;
00181 _K1 = _K2 = _K3 = _K4 = 0.;
00182 _PARENTNAME = "";
00183 _InheritStyle = "";
00184 _Parameterisation = "";
00185 _align_in=0;
00186 _align_out=0;
00187 _SetSensitive=0;
00188 _MagType = "";
00189 _FieldX = _FieldY = _FieldZ = 0.0;
00190 _Name="";
00191 if(aSQLTable->GetVariable("PARENTNAME")!=NULL)
00192 _PARENTNAME = aSQLTable->GetVariable("PARENTNAME")->GetStrValue(k);
00193 if(aSQLTable->GetVariable("POSX")!=NULL)
00194 _PosX = aSQLTable->GetVariable("POSX")->GetDblValue(k);
00195 if(aSQLTable->GetVariable("POSY")!=NULL)
00196 _PosY = aSQLTable->GetVariable("POSY")->GetDblValue(k);
00197 if(aSQLTable->GetVariable("POSZ")!=NULL)
00198 _PosZ = aSQLTable->GetVariable("POSZ")->GetDblValue(k);
00199 if(aSQLTable->GetVariable("ROTPSI")!=NULL)
00200 _RotPsi = aSQLTable->GetVariable("ROTPSI")->GetDblValue(k);
00201 if(aSQLTable->GetVariable("ROTTHETA")!=NULL)
00202 _RotTheta = aSQLTable->GetVariable("ROTTHETA")->GetDblValue(k);
00203 if(aSQLTable->GetVariable("ROTPHI")!=NULL)
00204 _RotPhi = aSQLTable->GetVariable("ROTPHI")->GetDblValue(k);
00205 if(aSQLTable->GetVariable("K1")!=NULL)
00206 _K1 = aSQLTable->GetVariable("K1")->GetDblValue(k);
00207 if(aSQLTable->GetVariable("K2")!=NULL)
00208 _K2 = aSQLTable->GetVariable("K2")->GetDblValue(k);
00209 if(aSQLTable->GetVariable("K3")!=NULL)
00210 _K3 = aSQLTable->GetVariable("K3")->GetDblValue(k);
00211 if(aSQLTable->GetVariable("K4")!=NULL)
00212 _K4 = aSQLTable->GetVariable("K4")->GetDblValue(k);
00213 if(aSQLTable->GetVariable("MAGTYPE")!=NULL)
00214 _MagType = aSQLTable->GetVariable("MAGTYPE")->GetStrValue(k);
00215 if(aSQLTable->GetVariable("FIELDX")!=NULL)
00216 _FieldX = aSQLTable->GetVariable("FIELDX")->GetDblValue(k);
00217 if(aSQLTable->GetVariable("FIELDY")!=NULL)
00218 _FieldY = aSQLTable->GetVariable("FIELDY")->GetDblValue(k);
00219 if(aSQLTable->GetVariable("FIELDZ")!=NULL)
00220 _FieldZ = aSQLTable->GetVariable("FIELDZ")->GetDblValue(k);
00221 if(aSQLTable->GetVariable("ALIGNIN")!=NULL)
00222 _align_in = aSQLTable->GetVariable("ALIGNIN")->GetIntValue(k);
00223 if(aSQLTable->GetVariable("ALIGNOUT")!=NULL)
00224 _align_out = aSQLTable->GetVariable("ALIGNOUT")->GetIntValue(k);
00225 if(aSQLTable->GetVariable("SETSENSITIVE")!=NULL)
00226 _SetSensitive = aSQLTable->GetVariable("SETSENSITIVE")->GetIntValue(k);
00227 if(aSQLTable->GetVariable("INHERITSTYLE")!=NULL)
00228 _InheritStyle = aSQLTable->GetVariable("INHERITSTYLE")->GetStrValue(k);
00229 if(aSQLTable->GetVariable("PARAMETERISATION")!=NULL)
00230 _Parameterisation = aSQLTable->GetVariable("PARAMETERISATION")->GetStrValue(k);
00231 if(_PARENTNAME=="") _PosZ-=itsMarkerLength/2;
00232 _PARENTNAME=itsMarkerVol->GetName()+"_"+_PARENTNAME;
00233 if(aSQLTable->GetVariable("NAME")!=NULL)
00234 _Name = aSQLTable->GetVariable("NAME")->GetStrValue(k);
00235 if(_Name=="_SQL") _Name = _TableName+BDSGlobalConstants::Instance()->StringFromInt(k) + "_SQL";
00236 if(_Name=="") _Name = _TableName+BDSGlobalConstants::Instance()->StringFromInt(k);
00237 _Name = itsMarkerVol->GetName()+"_"+_Name;
00238 #ifdef BDSDEBUG
00239 G4cout << __METHOD_NAME__ << " k = " << k << ", _Name = " << _Name << G4endl;
00240 #endif
00241 }
00242
00243 G4VisAttributes* BDSGeometrySQL::VisAtt(){
00244 G4VisAttributes* VisAtt =
00245 new G4VisAttributes(G4Colour(_VisRed, _VisGreen, _VisBlue, _VisAlpha));
00246 switch (_VisType(0))
00247 {
00248 case 'W': VisAtt->SetForceWireframe(true); break;
00249 case 'I': VisAtt->SetVisibility(false); break;
00250 case 'S': VisAtt->SetForceSolid(true); break;
00251 case 'w': VisAtt->SetForceWireframe(true); break;
00252 case 'i': VisAtt->SetVisibility(false); break;
00253 case 's': VisAtt->SetForceSolid(true); break;
00254 }
00255 return VisAtt;
00256 }
00257
00258 G4UserLimits* BDSGeometrySQL::UserLimits(G4double var){
00259 G4UserLimits* UserLimits = new G4UserLimits();
00260 UserLimits->SetMaxAllowedStep(var*0.5);
00261 UserLimits->SetUserMaxTime(BDSGlobalConstants::Instance()->GetMaxTime());
00262 if(BDSGlobalConstants::Instance()->GetThresholdCutCharged()>0){
00263 UserLimits->SetUserMinEkine(BDSGlobalConstants::Instance()->GetThresholdCutCharged());
00264 }
00265 return UserLimits;
00266 }
00267
00268
00269 void BDSGeometrySQL::SetLogVolAtt(G4LogicalVolume* logVol, G4double k){
00270 logVol->SetVisAttributes(VisAtt());
00271 #ifndef NOUSERLIMITS
00272 logVol->SetUserLimits(UserLimits(k));
00273 #endif
00274 SetLogVolRegion(logVol);
00275 }
00276
00277 void BDSGeometrySQL::SetLogVolRegion(G4LogicalVolume* logVol){
00278 if(_PrecisionRegion){
00279 logVol->SetRegion(_precisionRegionSQL);
00280 _precisionRegionSQL->AddRootLogicalVolume(logVol);
00281 }
00282 if(_ApproximationRegion){
00283 logVol->SetRegion(_approximationRegionSQL);
00284 _approximationRegionSQL->AddRootLogicalVolume(logVol);
00285 }
00286 }
00287
00288 G4LogicalVolume* BDSGeometrySQL::BuildCone(BDSMySQLTable* aSQLTable, G4int k)
00289 {
00290 G4double length;
00291 G4double rInnerStart;
00292 G4double rInnerEnd;
00293 G4double rOuterStart;
00294 G4double rOuterEnd;
00295 G4double sphi;
00296 G4double dphi;
00297
00298
00299 sphi =0.0;
00300 dphi = CLHEP::twopi*CLHEP::radian;
00301 length = rOuterStart = rOuterEnd = 10.*CLHEP::mm;
00302 rInnerStart = rInnerEnd = 0.0;
00303
00304 if(aSQLTable->GetVariable("LENGTH")!=NULL)
00305 length = aSQLTable->GetVariable("LENGTH")->GetDblValue(k);
00306 if(aSQLTable->GetVariable("RINNERSTART")!=NULL)
00307 rInnerStart = aSQLTable->GetVariable("RINNERSTART")->GetDblValue(k);
00308 if(aSQLTable->GetVariable("RINNEREND")!=NULL)
00309 rInnerEnd = aSQLTable->GetVariable("RINNEREND")->GetDblValue(k);
00310 if(aSQLTable->GetVariable("ROUTERSTART")!=NULL)
00311 rOuterStart = aSQLTable->GetVariable("ROUTERSTART")->GetDblValue(k);
00312 if(aSQLTable->GetVariable("ROUTEREND")!=NULL)
00313 rOuterEnd = aSQLTable->GetVariable("ROUTEREND")->GetDblValue(k);
00314 if(aSQLTable->GetVariable("STARTPHI")!=NULL)
00315 sphi = aSQLTable->GetVariable("STARTPHI")->GetDblValue(k);
00316 if(aSQLTable->GetVariable("DELTAPHI")!=NULL)
00317 dphi = aSQLTable->GetVariable("DELTAPHI")->GetDblValue(k);
00318
00319 G4Cons* aCone = new G4Cons(_Name+"_Cone",
00320 rInnerStart,
00321 rOuterStart,
00322 rInnerEnd,
00323 rOuterEnd,
00324 length/2,
00325 sphi,
00326 dphi);
00327
00328 G4LogicalVolume* aConeVol =
00329 new G4LogicalVolume(aCone,
00330 BDSMaterials::Instance()->GetMaterial(_Material),
00331 _Name+"_LogVol");
00332 _lengthUserLimit=length;
00333 return aConeVol;
00334 }
00335
00336 G4LogicalVolume* BDSGeometrySQL::BuildEllipticalCone(BDSMySQLTable* aSQLTable, G4int k){
00337
00338 G4double lengthZ = 0;
00339 G4double pxSemiAxis = 0;
00340 G4double pySemiAxis = 0;
00341 G4double pzTopCut = 0;
00342
00343
00344 lengthZ = 10.*CLHEP::mm;
00345
00346 if(aSQLTable->GetVariable("LENGTHZ")!=NULL)
00347 lengthZ = aSQLTable->GetVariable("LENGTHZ")->GetDblValue(k);
00348 if(aSQLTable->GetVariable("XSEMIAXIS")!=NULL)
00349 pxSemiAxis = aSQLTable->GetVariable("XSEMIAXIS")->GetDblValue(k);
00350 if(aSQLTable->GetVariable("YSEMIAXIS")!=NULL)
00351 pySemiAxis = aSQLTable->GetVariable("YSEMIAXIS")->GetDblValue(k);
00352 if(aSQLTable->GetVariable("ZCUT")!=NULL)
00353 pzTopCut = aSQLTable->GetVariable("ZCUT")->GetDblValue(k);
00354
00355 G4EllipticalCone* aEllipticalCone = new G4EllipticalCone(_Name+"_EllipticalCone",
00356 pxSemiAxis,
00357 pySemiAxis,
00358 lengthZ/2,
00359 pzTopCut);
00360
00361 G4LogicalVolume* aEllipticalConeVol =
00362 new G4LogicalVolume(aEllipticalCone,
00363 BDSMaterials::Instance()->GetMaterial(_Material),
00364 _Name+"_LogVol");
00365
00366 _lengthUserLimit=lengthZ*0.5;
00367 return aEllipticalConeVol;
00368 }
00369
00370 G4LogicalVolume* BDSGeometrySQL::BuildPolyCone(BDSMySQLTable* aSQLTable, G4int k)
00371 {
00372 G4int numZplanes;
00373 G4double* rInner = NULL;
00374 G4double* rOuter = NULL;
00375 G4double* zPos = NULL;
00376 G4double sphi;
00377 G4double dphi;
00378
00379
00380 sphi = 0.0;
00381 dphi = CLHEP::twopi*CLHEP::radian;
00382 numZplanes = 0;
00383
00384 if(aSQLTable->GetVariable("NZPLANES")!=NULL)
00385 numZplanes = aSQLTable->GetVariable("NZPLANES")->GetIntValue(k);
00386 rInner = new G4double[numZplanes+1];
00387 rOuter = new G4double[numZplanes+1];
00388 zPos = new G4double[numZplanes+1];
00389
00390 for(G4int planenum=0; planenum<numZplanes; planenum++)
00391 {
00392 G4String rInner_ID = "RINNER" + BDSGlobalConstants::Instance()->StringFromInt(planenum+1);
00393 G4String rOuter_ID = "ROUTER" + BDSGlobalConstants::Instance()->StringFromInt(planenum+1);
00394 G4String zPos_ID = "PLANEPOS" + BDSGlobalConstants::Instance()->StringFromInt(planenum+1);
00395
00396 if(aSQLTable->GetVariable(rInner_ID)!=NULL)
00397 rInner[planenum] = aSQLTable->GetVariable(rInner_ID)->GetDblValue(k);
00398 if(aSQLTable->GetVariable(rOuter_ID)!=NULL)
00399 rOuter[planenum] = aSQLTable->GetVariable(rOuter_ID)->GetDblValue(k);
00400
00401 if(aSQLTable->GetVariable(zPos_ID)!=NULL)
00402 zPos[planenum] = aSQLTable->GetVariable(zPos_ID)->GetDblValue(k);
00403 }
00404
00405 if(aSQLTable->GetVariable("STARTPHI")!=NULL)
00406 sphi = aSQLTable->GetVariable("STARTPHI")->GetDblValue(k);
00407 if(aSQLTable->GetVariable("DELTAPHI")!=NULL)
00408 dphi = aSQLTable->GetVariable("DELTAPHI")->GetDblValue(k);
00409
00410 G4Polycone* aPolyCone = new G4Polycone(_Name+"_PolyCone",
00411 sphi,
00412 dphi,
00413 numZplanes,
00414 zPos,
00415 rInner,
00416 rOuter);
00417
00418 G4LogicalVolume* aPolyConeVol =
00419 new G4LogicalVolume(aPolyCone,
00420 BDSMaterials::Instance()->GetMaterial(_Material),
00421 _Name+"_LogVol");
00422
00423 _lengthUserLimit=fabs(zPos[0]-zPos[numZplanes-1])/2;
00424
00425 delete [] rInner;
00426 rInner = NULL;
00427 delete [] rOuter;
00428 rOuter = NULL;
00429 delete [] zPos;
00430 zPos = NULL;
00431
00432 return aPolyConeVol;
00433 }
00434
00435 G4LogicalVolume* BDSGeometrySQL::BuildBox(BDSMySQLTable* aSQLTable, G4int k)
00436 {
00437 #ifdef BDSDEBUG
00438 G4cout << __METHOD_NAME__ << G4endl;
00439 #endif
00440
00441 G4double lengthX;
00442 G4double lengthY;
00443 G4double lengthZ;
00444
00445 lengthX = lengthY = lengthZ = 10.*CLHEP::mm;
00446
00447 if(aSQLTable->GetVariable("LENGTHX")!=NULL)
00448 lengthX = aSQLTable->GetVariable("LENGTHX")->GetDblValue(k);
00449 if(aSQLTable->GetVariable("LENGTHY")!=NULL)
00450 lengthY = aSQLTable->GetVariable("LENGTHY")->GetDblValue(k);
00451 if(aSQLTable->GetVariable("LENGTHZ")!=NULL)
00452 lengthZ = aSQLTable->GetVariable("LENGTHZ")->GetDblValue(k);
00453
00454 G4Box* aBox = new G4Box(_Name+"_Box",
00455 lengthX/2,
00456 lengthY/2,
00457 lengthZ/2);
00458
00459 G4LogicalVolume* aBoxVol =
00460 new G4LogicalVolume(aBox,
00461 BDSMaterials::Instance()->GetMaterial(_Material),
00462 _Name+"_LogVol");
00463
00464 _lengthUserLimit = lengthZ;
00465 return aBoxVol;
00466 }
00467
00468 G4LogicalVolume* BDSGeometrySQL::BuildTrap(BDSMySQLTable* aSQLTable, G4int k)
00469 {
00470
00471 G4double trapTheta = 0;
00472 G4double lengthXPlus = 0;
00473 G4double lengthXMinus = 0;
00474 G4double lengthYPlus = 0;
00475 G4double lengthYMinus = 0;
00476 G4double lengthZ = 0;
00477
00478 if(aSQLTable->GetVariable("TRAPTHETA")!=NULL)
00479 trapTheta = aSQLTable->GetVariable("TRAPTHETA")->GetDblValue(k);
00480 if(aSQLTable->GetVariable("LENGTHXPLUS")!=NULL)
00481 lengthXPlus = aSQLTable->GetVariable("LENGTHXPLUS")->GetDblValue(k);
00482 if(aSQLTable->GetVariable("LENGTHXMINUS")!=NULL)
00483 lengthXMinus = aSQLTable->GetVariable("LENGTHXMINUS")->GetDblValue(k);
00484 if(aSQLTable->GetVariable("LENGTHYPLUS")!=NULL)
00485 lengthYPlus = aSQLTable->GetVariable("LENGTHYPLUS")->GetDblValue(k);
00486 if(aSQLTable->GetVariable("LENGTHYMINUS")!=NULL)
00487 lengthYMinus = aSQLTable->GetVariable("LENGTHYMINUS")->GetDblValue(k);
00488 if(aSQLTable->GetVariable("LENGTHZ")!=NULL)
00489 lengthZ = aSQLTable->GetVariable("LENGTHZ")->GetDblValue(k);
00490
00491 G4Trap* aTrap = new G4Trap(_Name+"_Trd",
00492 lengthZ/2,
00493 trapTheta, 0,
00494 lengthYPlus/2,
00495 lengthXPlus/2,
00496 lengthXPlus/2,
00497 0,
00498 lengthYMinus/2,
00499 lengthXMinus/2,
00500 lengthXMinus/2,
00501 0);
00502
00503
00504 G4LogicalVolume* aTrapVol =
00505 new G4LogicalVolume(aTrap,
00506 BDSMaterials::Instance()->GetMaterial(_Material),
00507 _Name+"_LogVol");
00508
00509 _lengthUserLimit = lengthZ*0.5;
00510 return aTrapVol;
00511 }
00512
00513 G4LogicalVolume* BDSGeometrySQL::BuildTorus(BDSMySQLTable* aSQLTable, G4int k)
00514 {
00515
00516 G4double rInner;
00517 G4double rOuter;
00518 G4double rSwept;
00519 G4double sphi;
00520 G4double dphi;
00521
00522
00523 rSwept = 20.*CLHEP::mm;
00524 rOuter = 10.*CLHEP::mm;
00525 rInner = 0.0;
00526 sphi = 0.0;
00527 dphi=2*CLHEP::pi*CLHEP::radian;
00528
00529 if(aSQLTable->GetVariable("RINNER")!=NULL)
00530 rInner = aSQLTable->GetVariable("RINNER")->GetDblValue(k);
00531 if(aSQLTable->GetVariable("ROUTER")!=NULL)
00532 rOuter = aSQLTable->GetVariable("ROUTER")->GetDblValue(k);
00533 if(aSQLTable->GetVariable("RSWEPT")!=NULL)
00534 rSwept = aSQLTable->GetVariable("RSWEPT")->GetDblValue(k);
00535 if(aSQLTable->GetVariable("STARTPHI")!=NULL)
00536 sphi = aSQLTable->GetVariable("STARTPHI")->GetDblValue(k);
00537 if(aSQLTable->GetVariable("DELTAPHI")!=NULL)
00538 dphi = aSQLTable->GetVariable("DELTAPHI")->GetDblValue(k);
00539
00540 G4Torus* aTorus = new G4Torus(_Name+"_Torus",
00541 rInner,
00542 rOuter,
00543 rSwept,
00544 sphi,
00545 dphi);
00546
00547
00548 G4LogicalVolume* aTorusVol =
00549 new G4LogicalVolume(aTorus,
00550 BDSMaterials::Instance()->GetMaterial(_Material),
00551 _Name+"_LogVol");
00552
00553 _lengthUserLimit = rOuter*0.5;
00554 return aTorusVol;
00555 }
00556
00557 G4LogicalVolume* BDSGeometrySQL::BuildSampler(BDSMySQLTable* aSQLTable, G4int k)
00558 {
00559
00560 G4double length;
00561 G4double rInnerStart;
00562 G4double rInnerEnd;
00563 G4double rOuterStart;
00564 G4double rOuterEnd;
00565
00566
00567 length = rOuterStart = rOuterEnd = 10.*CLHEP::mm;
00568 rInnerStart = rInnerEnd = 0.0;
00569
00570 if(aSQLTable->GetVariable("LENGTH")!=NULL)
00571 length = aSQLTable->GetVariable("LENGTH")->GetDblValue(k);
00572 if(aSQLTable->GetVariable("RINNERSTART")!=NULL)
00573 rInnerStart = aSQLTable->GetVariable("RINNERSTART")->GetDblValue(k);
00574 if(aSQLTable->GetVariable("RINNEREND")!=NULL)
00575 rInnerEnd = aSQLTable->GetVariable("RINNEREND")->GetDblValue(k);
00576 if(aSQLTable->GetVariable("ROUTERSTART")!=NULL)
00577 rOuterStart = aSQLTable->GetVariable("ROUTERSTART")->GetDblValue(k);
00578 if(aSQLTable->GetVariable("ROUTEREND")!=NULL)
00579 rOuterEnd = aSQLTable->GetVariable("ROUTEREND")->GetDblValue(k);
00580 if(aSQLTable->GetVariable("NAME")!=NULL)
00581 {
00582 _Name = aSQLTable->GetVariable("NAME")->GetStrValue(k);
00583 aSQLTable->GetVariable("NAME")->SetStrValue(k,_Name+"_SQL");
00584 _Name = aSQLTable->GetVariable("NAME")->GetStrValue(k);
00585 }
00586 if(_Name=="_SQL") _Name = _TableName+BDSGlobalConstants::Instance()->StringFromInt(k)+"_SQL";
00587
00588 _Name = itsMarkerVol->GetName()+"_"+_Name;
00589
00590 G4Cons* aSampler = new G4Cons(_Name+"_samp",
00591 rInnerStart,
00592 rOuterStart,
00593 rInnerEnd,
00594 rOuterEnd,
00595 length/2,
00596 0,
00597 CLHEP::twopi*CLHEP::radian);
00598
00599 G4LogicalVolume* aSamplerVol =
00600 new G4LogicalVolume(aSampler,
00601 BDSMaterials::Instance()->GetMaterial(_Material),
00602 _Name+"_LogVol");
00603
00604 _lengthUserLimit = length*0.5;
00605
00606 aSamplerVol->SetSensitiveDetector(BDSSampler::GetSensitiveDetector());
00607
00608 BDSSampler::AddExternalSampler(BDSGlobalConstants::Instance()->StringFromInt(BDSSampler::GetNSamplers())+"_"+_Name+"_1");
00609
00610 return aSamplerVol;
00611 }
00612
00613 G4LogicalVolume* BDSGeometrySQL::BuildTube(BDSMySQLTable* aSQLTable, G4int k)
00614 {
00615
00616 G4double rInner;
00617 G4double rOuter;
00618 G4double length;
00619 G4double sphi;
00620 G4double dphi;
00621
00622
00623 length = 100.*CLHEP::mm;
00624 rOuter = 10.*CLHEP::mm;
00625 rInner = 0.0;
00626 sphi = 0.0;
00627 dphi=2*CLHEP::pi*CLHEP::radian;
00628
00629 if(aSQLTable->GetVariable("RINNER")!=NULL)
00630 rInner = aSQLTable->GetVariable("RINNER")->GetDblValue(k);
00631 if(aSQLTable->GetVariable("ROUTER")!=NULL)
00632 rOuter = aSQLTable->GetVariable("ROUTER")->GetDblValue(k);
00633 if(aSQLTable->GetVariable("LENGTH")!=NULL)
00634 length = aSQLTable->GetVariable("LENGTH")->GetDblValue(k);
00635 if(aSQLTable->GetVariable("STARTPHI")!=NULL)
00636 sphi = aSQLTable->GetVariable("STARTPHI")->GetDblValue(k);
00637 if(aSQLTable->GetVariable("DELTAPHI")!=NULL)
00638 dphi = aSQLTable->GetVariable("DELTAPHI")->GetDblValue(k);
00639
00640 G4Tubs* aTubs = new G4Tubs(_Name+"_Tubs",
00641 rInner,
00642 rOuter,
00643 length/2,
00644 sphi,
00645 dphi);
00646
00647 G4LogicalVolume* aTubsVol =
00648 new G4LogicalVolume(aTubs,
00649 BDSMaterials::Instance()->GetMaterial(_Material),
00650 _Name+"_LogVol");
00651
00652 _lengthUserLimit = length*0.5;
00653 return aTubsVol;
00654 }
00655
00656 G4LogicalVolume* BDSGeometrySQL::BuildEllipticalTube(BDSMySQLTable* aSQLTable, G4int k)
00657 {
00658 G4double lengthX;
00659 G4double lengthY;
00660 G4double lengthZ;
00661
00662
00663 lengthX = 100.*CLHEP::mm;
00664 lengthY = 50.*CLHEP::mm;
00665 lengthZ = 200.*CLHEP::mm;
00666
00667 if(aSQLTable->GetVariable("LENGTHX")!=NULL)
00668 lengthX = aSQLTable->GetVariable("LENGTHX")->GetDblValue(k);
00669 if(aSQLTable->GetVariable("LENGTHY")!=NULL)
00670 lengthY = aSQLTable->GetVariable("LENGTHY")->GetDblValue(k);
00671 if(aSQLTable->GetVariable("LENGTHZ")!=NULL)
00672 lengthZ = aSQLTable->GetVariable("LENGTHZ")->GetDblValue(k);
00673
00674 G4EllipticalTube* aEllipticalTube = new G4EllipticalTube(_Name+"_EllipticalTube",
00675 lengthX/2,
00676 lengthY/2,
00677 lengthZ/2
00678 );
00679
00680
00681 G4LogicalVolume* aEllipticalTubeVol =
00682 new G4LogicalVolume(aEllipticalTube,
00683 BDSMaterials::Instance()->GetMaterial(_Material),
00684 _Name+"_LogVol");
00685 G4double maxLength = lengthX;
00686 if (lengthY>lengthX&&lengthY>lengthZ){
00687 maxLength = lengthY;
00688 }
00689 else if(lengthZ>lengthY&&lengthZ>lengthX){
00690 maxLength = lengthZ;
00691 }
00692 _lengthUserLimit = maxLength*0.5;
00693 return aEllipticalTubeVol;
00694 }
00695
00696
00697 G4LogicalVolume* BDSGeometrySQL::BuildPCLTube(BDSMySQLTable* aSQLTable, G4int k)
00698 {
00699 G4double aperX;
00700 G4double aperYUp;
00701 G4double aperYDown;
00702 G4double aperDy;
00703 G4double thickness;
00704 G4double length;
00705
00706
00707 aperX = 100.*CLHEP::mm;
00708 aperYUp = 50.*CLHEP::mm;
00709 aperYDown = 200.*CLHEP::mm;
00710 aperDy = 0.*CLHEP::mm;
00711 thickness = BDSGlobalConstants::Instance()->GetBeamPipeThickness();
00712 length = 200.0*CLHEP::mm;
00713
00714 if(aSQLTable->GetVariable("APERX")!=NULL)
00715 aperX = aSQLTable->GetVariable("APERX")->GetDblValue(k);
00716 if(aSQLTable->GetVariable("APERYUP")!=NULL)
00717 aperYUp = aSQLTable->GetVariable("APERYUP")->GetDblValue(k);
00718 if(aSQLTable->GetVariable("APERYDOWN")!=NULL)
00719 aperYDown = aSQLTable->GetVariable("APERYDOWN")->GetDblValue(k);
00720 if(aSQLTable->GetVariable("APERDY")!=NULL)
00721 aperDy = aSQLTable->GetVariable("APERDY")->GetDblValue(k);
00722 if(aSQLTable->GetVariable("THICKNESS")!=NULL)
00723 thickness = aSQLTable->GetVariable("THICKNESS")->GetDblValue(k);
00724 if(aSQLTable->GetVariable("LENGTH")!=NULL)
00725 length = aSQLTable->GetVariable("LENGTH")->GetDblValue(k);
00726
00727 BDSPCLTube* aPCLTubeBuilder = new BDSPCLTube(aperX, aperYUp, aperYDown, aperDy, thickness, length, _Name+"_PCLTube");
00728 G4VSolid* aPCLTube = aPCLTubeBuilder->GetSolid();
00729 delete aPCLTubeBuilder;
00730
00731 G4LogicalVolume* aPCLTubeVol =
00732 new G4LogicalVolume(aPCLTube,
00733 BDSMaterials::Instance()->GetMaterial(_Material),
00734 _Name+"_LogVol");
00735 G4double totalYLength = aperDy+aperYUp+aperYDown+thickness;
00736 G4double totalXLength = aperX+thickness;
00737 G4double maxLength = length;
00738 if (totalYLength>length&&totalYLength>totalXLength){
00739 maxLength = totalYLength;
00740 }
00741 else if(totalXLength>totalYLength&&totalXLength>length){
00742 maxLength = totalXLength;
00743 }
00744 _lengthUserLimit = maxLength*0.5;
00745 return aPCLTubeVol;
00746 }
00747
00748 G4RotationMatrix* BDSGeometrySQL::RotateComponent(G4double psi,G4double phi,G4double theta)
00749 {
00750 rotateComponent = new G4RotationMatrix;
00751 if(psi==0 && phi==0 && theta==0) return rotateComponent;
00752
00753 G4RotationMatrix* LocalRotation = new G4RotationMatrix;
00754 G4ThreeVector* localX = new G4ThreeVector(1.,0.,0.);
00755 G4ThreeVector* localY = new G4ThreeVector(0.,1.,0.);
00756 G4ThreeVector* localZ = new G4ThreeVector(0.,0.,1.);
00757
00758 LocalRotation->rotate(psi,*localZ);
00759 localX->rotate(psi,*localZ);
00760 localY->rotate(psi,*localZ);
00761
00762
00763 LocalRotation->rotate(phi,*localY);
00764 localX->rotate(phi,*localY);
00765 localZ->rotate(phi,*localY);
00766
00767
00768 LocalRotation->rotate(theta,*localX);
00769 localY->rotate(theta,*localX);
00770 localZ->rotate(theta,*localX);
00771
00772 rotateComponent->transform(*LocalRotation);
00773 rotateComponent->invert();
00774
00775 return rotateComponent;
00776 }
00777
00778
00779 void BDSGeometrySQL::PlaceComponents(BDSMySQLTable* aSQLTable, std::vector<G4LogicalVolume*> VOL_LIST)
00780 {
00781 G4String::caseCompare cmpmode = G4String::ignoreCase;
00782 for(G4int k=0; k<_NVariables; k++)
00783 {
00784 SetPlacementParams(aSQLTable, k);
00785 G4int PARENTID=0;
00786 if(_PARENTNAME!=""){
00787 _PARENTNAME+="_LogVol";
00788 for(G4int i=0; i<(G4int)VOL_LIST.size(); i++)
00789 {
00790 if(_PARENTNAME.compareTo(VOL_LIST[i]->GetName(),cmpmode)==0)
00791 {
00792 PARENTID = i;
00793 continue;
00794 }
00795 }
00796 }
00797
00798
00799 G4String tmpname = _Name+"_LogVol";
00800 G4int ID=0;
00801 for(G4int i=0; i<(G4int)VOL_LIST.size(); i++)
00802 {
00803 if(tmpname.compareTo(VOL_LIST[i]->GetName(),cmpmode)==0)
00804 {
00805 ID = i;
00806 continue;
00807 }
00808 }
00809
00810 if(_SetSensitive) SensitiveComponents.push_back(VOL_LIST[ID]);
00811
00812 G4ThreeVector PlacementPoint(_PosX,_PosY,_PosZ);
00813
00814 if(_InheritStyle.compareTo("",cmpmode)){
00815 if(_InheritStyle.compareTo("SUBTRACT",cmpmode)==0)
00816 {
00817 G4VSolid* original = VOL_LIST[PARENTID]->GetSolid();
00818 G4VSolid* sub = VOL_LIST[ID]->GetSolid();
00819 VOL_LIST[PARENTID]->SetSolid(new G4SubtractionSolid(VOL_LIST[PARENTID]->GetName(),
00820 original,
00821 sub,
00822 RotateComponent(_RotPsi,_RotPhi,_RotTheta),
00823 PlacementPoint));
00824
00825 }else if(_InheritStyle.compareTo("INTERSECT",cmpmode)==0){
00826 G4VSolid* original = VOL_LIST[PARENTID]->GetSolid();
00827 G4VSolid* sub = VOL_LIST[ID]->GetSolid();
00828 VOL_LIST[PARENTID]->SetSolid(new G4IntersectionSolid(VOL_LIST[PARENTID]->GetName(),
00829 original,
00830 sub,
00831 RotateComponent(_RotPsi,_RotPhi,_RotTheta),
00832 PlacementPoint));
00833
00834 } else if(_InheritStyle.compareTo("UNION",cmpmode)==0)
00835 {
00836 G4VSolid* original = VOL_LIST[PARENTID]->GetSolid();
00837 G4VSolid* sub = VOL_LIST[ID]->GetSolid();
00838 VOL_LIST[PARENTID]->SetSolid(new G4UnionSolid(VOL_LIST[PARENTID]->GetName(),
00839 original,
00840 sub,
00841 RotateComponent(_RotPsi,_RotPhi,_RotTheta),
00842 PlacementPoint));
00843 }
00844 }
00845
00846 if(_Parameterisation.compareTo("GFLASH",cmpmode)==0){
00847 itsGFlashComponents.push_back(VOL_LIST[ID]);
00848 }
00849
00850 #ifdef BDSDEBUG
00851 G4cout << __METHOD_NAME__ << " k = " << k << ", volume = " << VOL_LIST[ID]->GetName() << G4endl;
00852 #endif
00853
00854 G4VPhysicalVolume* PhysiComp =
00855 new G4PVPlacement(RotateComponent(_RotPsi,_RotPhi,_RotTheta),
00856 PlacementPoint,
00857 VOL_LIST[ID],
00858 _Name,
00859 VOL_LIST[PARENTID],
00860 false,
00861 0, BDSGlobalConstants::Instance()->GetCheckOverlaps());
00862 SetMultiplePhysicalVolumes(PhysiComp);
00863 if(_align_in)
00864 {
00865
00866 if(align_in_volume!=NULL)
00867 {
00868 G4cerr<<"\nBDSGeometrySQL.cc:486: Trying to align in-beam to SQL volume to " << PhysiComp->GetName() << " but alignment already set to " << align_in_volume->GetName() << G4endl;
00869 G4Exception("Aborting Program", "-1", FatalException, "");
00870
00871 }
00872
00873 else
00874 align_in_volume=PhysiComp;
00875
00876 }
00877
00878 if(_align_out)
00879 {
00880 if(align_out_volume!=NULL)
00881 {
00882 G4cerr<<"\nBDSGeometrySQL.cc:486: Trying to align out-beam to SQL volume to " << PhysiComp->GetName() << " but alignment already set to " << align_out_volume->GetName() << G4endl;
00883 G4Exception("Aborting Program", "-1", FatalException, "");
00884
00885 }
00886
00887 else
00888 align_out_volume=PhysiComp;
00889 }
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899 G4double charge = BDSGlobalConstants::Instance()->GetParticleDefinition()->GetPDGCharge();
00900
00901 G4double momentum = BDSGlobalConstants::Instance()->GetBeamMomentum();
00902
00903 G4double brho = ( (momentum/CLHEP::GeV) / (0.299792458 * charge));
00904
00905 brho *= (CLHEP::tesla*CLHEP::m);
00906
00907 if(_MagType.compareTo("QUAD",cmpmode)==0)
00908 {
00909 HasFields = true;
00910 nPoleField = 1;
00911 QuadBgrad.push_back(- brho * _K1 / CLHEP::m2);
00912 Quadvol.push_back(PhysiComp->GetName());
00913 QuadVolBgrad[PhysiComp->GetName()]=(- brho * _K1 / CLHEP::m2);
00914 }
00915
00916 if(_MagType.compareTo("SEXT",cmpmode)==0)
00917 {
00918 HasFields = true;
00919 nPoleField = 2;
00920 SextBgrad.push_back(- brho * _K2 / CLHEP::m3);
00921 Sextvol.push_back(PhysiComp->GetName());
00922 SextVolBgrad[PhysiComp->GetName()]=(- brho * _K2 / CLHEP::m3);
00923 }
00924
00925 if(_MagType.compareTo("OCT",cmpmode)==0)
00926 {
00927 HasFields = true;
00928 nPoleField = 3;
00929 OctBgrad.push_back(- brho * _K3 / (CLHEP::m2*CLHEP::m2));
00930 Octvol.push_back(PhysiComp->GetName());
00931 OctVolBgrad[PhysiComp->GetName()]=(- brho * _K3 / (CLHEP::m2*CLHEP::m2));
00932 }
00933
00934 if(_FieldX || _FieldY || _FieldZ)
00935 {
00936 HasFields = true;
00937 HasUniformField=true;
00938 #ifdef BDSDEBUG
00939 G4cout << "BDSGeometrySQL> volume " << PhysiComp->GetName() << " has the following uniform field: " << _FieldX << " " << _FieldY << " " << _FieldZ << " " << G4endl;
00940 #endif
00941 UniformField.push_back(G4ThreeVector(_FieldX*CLHEP::tesla,_FieldY*CLHEP::tesla,_FieldZ*CLHEP::tesla));
00942 Fieldvol.push_back(PhysiComp->GetName());
00943 UniformFieldVolField[PhysiComp->GetName()]=G4ThreeVector(_FieldX*CLHEP::tesla,_FieldY*CLHEP::tesla,_FieldZ*CLHEP::tesla);
00944 }
00945 }
00946 }