00001 #ifdef USE_LCDD
00002 #include "BDSGlobalConstants.hh"
00003 #include "BDSGeometryLCDD.hh"
00004 #include "BDSSbendMagField.hh"
00005 #include "G4Box.hh"
00006 #include "G4Colour.hh"
00007 #include "G4Tubs.hh"
00008 #include "G4Cons.hh"
00009 #include "G4Polycone.hh"
00010 #include "G4Polyhedra.hh"
00011 #include "G4VisAttributes.hh"
00012 #include "G4LogicalVolume.hh"
00013 #include "G4VPhysicalVolume.hh"
00014 #include "G4PVPlacement.hh"
00015 #include "G4UserLimits.hh"
00016 #include "BDSMySQLWrapper.hh"
00017 #include "BDSMaterials.hh"
00018 #include "BDSSamplerSD.hh"
00019 #include "BDSDetectorSolenoidMagField.hh"
00020 #include "G4Mag_UsualEqRhs.hh"
00021 #include "G4TessellatedSolid.hh"
00022 #include "G4UniformMagField.hh"
00023
00024 #include <cstdlib>
00025 #include <cstring>
00026 #include <list>
00027
00028 BDSGeometryLCDD::BDSGeometryLCDD(G4String LCDDfile):
00029 itsMarkerVol(NULL),itsMagField(NULL),itsUniformMagField(NULL)
00030 {
00031 #ifndef NOUSERLIMITS
00032 itsUserLimits = new G4UserLimits();
00033 itsUserLimits->SetUserMaxTime(BDSGlobalConstants::Instance()->GetMaxTime());
00034 if(BDSGlobalConstants::Instance()->GetThresholdCutCharged()>0){
00035 itsUserLimits->SetUserMinEkine(BDSGlobalConstants::Instance()->GetThresholdCutCharged());
00036 }
00037 #endif
00038
00039 itsFieldIsUniform=false;
00040 itsFieldVolName="";
00041 itsLCDDfile = LCDDfile;
00042 visRed = visGreen = visBlue = 0.0;
00043
00044
00045 CONST_REF aconst;
00046 aconst.name="pi";
00047 aconst.value=CLHEP::pi;
00048 CONST_LIST.push_back(aconst);
00049
00050 aconst.name="TWOPI";
00051 aconst.value=CLHEP::twopi;
00052 CONST_LIST.push_back(aconst);
00053
00054
00055 aconst.name="HALFPI";
00056 aconst.value=CLHEP::halfpi;
00057 CONST_LIST.push_back(aconst);
00058
00059
00060 aconst.name="radian";
00061 aconst.value=CLHEP::radian;
00062 CONST_LIST.push_back(aconst);
00063
00064 aconst.name="degree";
00065 aconst.value=CLHEP::degree;
00066 CONST_LIST.push_back(aconst);
00067
00068 aconst.name="mm";
00069 aconst.value=CLHEP::mm;
00070 CONST_LIST.push_back(aconst);
00071
00072 aconst.name="cm";
00073 aconst.value=CLHEP::cm;
00074 CONST_LIST.push_back(aconst);
00075
00076 aconst.name="m";
00077 aconst.value=CLHEP::m;
00078 CONST_LIST.push_back(aconst);
00079
00080 aconst.name="cm2";
00081 aconst.value=CLHEP::cm2;
00082 CONST_LIST.push_back(aconst);
00083
00084 aconst.name="cm3";
00085 aconst.value=CLHEP::cm3;
00086 CONST_LIST.push_back(aconst);
00087
00088 aconst.name="tesla";
00089 aconst.value=CLHEP::tesla;
00090 CONST_LIST.push_back(aconst);
00091
00092 aconst.name="g";
00093 aconst.value=CLHEP::g;
00094 CONST_LIST.push_back(aconst);
00095
00096 aconst.name="kg";
00097 aconst.value=CLHEP::kg;
00098 CONST_LIST.push_back(aconst);
00099
00100 aconst.name="mol";
00101 aconst.value=CLHEP::mole;
00102 CONST_LIST.push_back(aconst);
00103
00104 aconst.name="mole";
00105 aconst.value=CLHEP::mole;
00106 CONST_LIST.push_back(aconst);
00107 #ifdef BDSDEBUG
00108 G4cout << "BDSGeometryLCDD CONST_LIST defined units: " << G4endl;
00109 for(unsigned int i=0; i<CONST_LIST.size(); i++){
00110 G4cout << CONST_LIST[i].name << " " << CONST_LIST[i].value << G4endl;
00111 }
00112 #endif
00113 }
00114
00115 BDSGeometryLCDD::~BDSGeometryLCDD()
00116 {
00117 delete itsUniformMagField;
00118 delete itsMagField;
00119 delete itsUserLimits;
00120 }
00121
00122 void BDSGeometryLCDD::Construct(G4LogicalVolume *marker)
00123 {
00124 itsMarkerVol = marker;
00125 parseDoc();
00126
00127 }
00128
00129 G4bool BDSGeometryLCDD::GetFieldIsUniform(){
00130 return itsFieldIsUniform;
00131 }
00132
00133 BDSMagField* BDSGeometryLCDD::GetField()
00134 {
00135 return itsMagField;
00136 }
00137
00138 G4UniformMagField* BDSGeometryLCDD::GetUniformField()
00139 {
00140 return itsUniformMagField;
00141 }
00142
00143 void BDSGeometryLCDD::parseDoc()
00144 {
00145 const char* docname = itsLCDDfile.c_str();
00146 xmlDocPtr doc;
00147 xmlNodePtr cur;
00148
00149 doc = xmlParseFile(docname);
00150
00151 if (doc == NULL )
00152 {
00153 G4Exception("Document not parsed successfully", "-1", FatalException, "");
00154 }
00155
00156 cur = xmlDocGetRootElement(doc);
00157
00158 if (cur == NULL)
00159 {
00160 xmlFreeDoc(doc);
00161 G4Exception("empty document", "-1", FatalException, "");
00162 }
00163
00164
00165 if (xmlStrcmp(cur->name, (const xmlChar *) "lcdd"))
00166 {
00167 xmlFreeDoc(doc);
00168 G4Exception("XML document of the wrong type, root node != lcdd\nCheck your XML file\n", "-1", FatalException, "");
00169 }
00170
00171 cur = cur->xmlChildrenNode;
00172
00173 while (cur != NULL)
00174 {
00175 if ((!xmlStrcmp(cur->name, (const xmlChar *)"header")))
00176 {
00177 parseHEADER(cur);
00178 }
00179 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"iddict")))
00180 {
00181 G4cout << "Warning: from BDSGeometryLCDD.cc::parseDoc() - LCDD iddict not currently implemented in BDSIM" << G4endl;
00182 }
00183 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"sensitive_detectors")))
00184 {
00185 G4cout << "Warning: from BDSGeometryLCDD.cc::parseDoc() - LCDD sensitive_detectors not currently implemented in BDSIM" << G4endl;
00186 }
00187 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"limits")))
00188 {
00189 G4cout << "Warning: from BDSGeometryLCDD.cc::parseDoc() - LCDD limits not currently implemented in BDSIM" << G4endl;
00190 }
00191 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"regions")))
00192 {
00193 G4cout << "Warning: from BDSGeometryLCDD.cc::parseDoc() - LCDD limits not currently implemented in BDSIM" << G4endl;
00194 }
00195 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"display")))
00196 {
00197 parseDISPLAY(cur);
00198 }
00199 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"gdml")))
00200 {
00201 parseLCDD(cur);
00202 }
00203 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"fields")))
00204 {
00205 G4cout << "Importing LCDD fields" << G4endl;
00206 parseFIELDS(cur);
00207 }
00208 cur = cur->next;
00209 }
00210 if((!itsMagField) && (!itsUniformMagField)){
00211 #ifdef BDSDEBUG
00212 G4cout << "BDSGeometryLCDD.cc> No magnetic fields defined. Making default (zero) BDSMagField" << G4endl;
00213 #endif
00214 itsMagField = new BDSMagField();
00215 }
00216
00217 xmlFreeDoc(doc);
00218 return;
00219 }
00220
00221 void BDSGeometryLCDD::parseHEADER(xmlNodePtr cur)
00222 {
00223 G4cout << "================================" << G4endl;
00224 G4cout << " LCDD header " << G4endl;
00225 G4cout << "--------------------------------" << G4endl;
00226
00227
00228 xmlNodePtr tempcur = cur->xmlChildrenNode;
00229 while (tempcur != NULL)
00230 {
00231 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"detector")))
00232 {
00233 G4cout << "Detector: " << parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"name")) << G4endl;
00234 }
00235 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"generator")))
00236 {
00237 G4cout << "Generated by: " << parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"name"))
00238 << ", version " << parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"version"))
00239 << ", file " << parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"file"))
00240 << ", checksum " << parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"checksum"))
00241 << G4endl;
00242 }
00243 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"author")))
00244 {
00245 G4cout << "Author: " << parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"name")) << G4endl;
00246 }
00247 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"comment")))
00248 {
00249 G4cout << parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"name")) << G4endl;
00250 }
00251 tempcur = tempcur->next;
00252 }
00253 return;
00254 }
00255
00256 void BDSGeometryLCDD::parseDISPLAY(xmlNodePtr cur)
00257 {
00258 cur = cur->xmlChildrenNode;
00259
00260 while (cur != NULL)
00261 {
00262 if ((!xmlStrcmp(cur->name, (const xmlChar *)"vis")))
00263 {
00264 parseVIS(cur);
00265 }
00266 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"VisType")))
00267 {
00268 G4Exception("LCDD VisType not currently implemented in BDSIM", "-1", FatalException, "");
00269 }
00270 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"DisplayType")))
00271 {
00272 G4Exception("LCDD DisplayType not currently implemented in BDSIM", "-1", FatalException, "");
00273 }
00274 cur = cur->next;
00275 }
00276 return;
00277 }
00278
00279 void BDSGeometryLCDD::parseVIS(xmlNodePtr cur)
00280 {
00281 G4String name = parseStrChar(xmlGetProp(cur,(const xmlChar*)"name"));
00282 G4bool visible = parseBoolChar(xmlGetProp(cur,(const xmlChar*)"visible"));
00283 G4bool show_daughters = parseBoolChar(xmlGetProp(cur,(const xmlChar*)"show_daughters"));
00284 G4String line_style = parseStrChar(xmlGetProp(cur,(const xmlChar*)"line_style"));
00285 G4String drawing_style = parseStrChar(xmlGetProp(cur,(const xmlChar*)"drawing_style"));
00286
00287 G4double R = 1.0, G = 1.0, B = 1.0, alpha = 1.0;
00288
00289 cur = cur->xmlChildrenNode;
00290
00291 while(cur!=NULL)
00292 {
00293 if ((!xmlStrcmp(cur->name, (const xmlChar *)"color")))
00294 {
00295 R = parseDblChar(xmlGetProp(cur,(const xmlChar*)"R"));
00296 G = parseDblChar(xmlGetProp(cur,(const xmlChar*)"G"));
00297 B = parseDblChar(xmlGetProp(cur,(const xmlChar*)"R"));
00298 alpha = parseDblChar(xmlGetProp(cur,(const xmlChar*)"alpha"));
00299
00300 }
00301 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"color")))
00302 {
00303
00304 }
00305 cur = cur->next;
00306 }
00307
00308 G4VisAttributes* VisAtt =
00309 new G4VisAttributes(G4Colour(R,G,B,alpha));
00310
00311 if(drawing_style=="solid" )VisAtt->SetForceSolid(true);
00312 else if(drawing_style=="wireframe") VisAtt->SetForceWireframe(true);
00313
00314 if(line_style=="unbroken" )VisAtt->SetLineStyle(G4VisAttributes::unbroken);
00315 else if(line_style=="dashed") VisAtt->SetLineStyle(G4VisAttributes::dashed);
00316 else if(line_style=="dotted") VisAtt->SetLineStyle(G4VisAttributes::dotted);
00317
00318 VisAtt->SetVisibility(visible);
00319 if(show_daughters) VisAtt->SetDaughtersInvisible(false);
00320 else VisAtt->SetDaughtersInvisible(true);
00321
00322 VIS_REF avis;
00323 avis.name = name;
00324 avis.value = VisAtt;
00325 VIS_LIST.push_back(avis);
00326 return;
00327 }
00328
00329 void BDSGeometryLCDD::parseLCDD(xmlNodePtr cur)
00330 {
00331 cur = cur->xmlChildrenNode;
00332
00333 while (cur != NULL)
00334 {
00335 if ((!xmlStrcmp(cur->name, (const xmlChar *)"define")))
00336 {
00337 G4cout << "Importing LCDD Definitions" << G4endl;
00338 parseDEFINE(cur);
00339 }
00340 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"materials")))
00341 {
00342 G4cout << "Importing LCDD Materials" << G4endl;
00343 parseMATERIALS(cur);
00344 }
00345 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"solids")))
00346 {
00347 G4cout << "Importing LCDD Solids" << G4endl;
00348 parseSOLID(cur);
00349 }
00350 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"structure")))
00351 {
00352 G4cout << "Importing LCDD Structures" << G4endl;
00353 parseSTRUCTURE(cur);
00354 }
00355 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"setup")))
00356 {
00357 G4cout << "Importing LCDD Setup" << G4endl;
00358 G4String name = parseStrChar(xmlGetProp(cur,(const xmlChar*)"name"));
00359 G4String version = parseStrChar(xmlGetProp(cur,(const xmlChar*)"version"));
00360 xmlNodePtr tempcur = cur->xmlChildrenNode;
00361
00362 while(tempcur!=NULL)
00363 {
00364 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"world")))
00365 itsWorldRef = parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"ref"));
00366 tempcur = tempcur->next;
00367 }
00368
00369 G4LogicalVolume* topvol = GetLogVolByName(itsWorldRef);
00370 new G4PVPlacement(NULL,
00371 G4ThreeVector(0.,0.,0.),
00372 topvol,
00373 topvol->GetName()+"_PhysiComp",
00374 itsMarkerVol,
00375 false,
00376 0, BDSGlobalConstants::Instance()->GetCheckOverlaps());
00377 #ifndef NOUSERLIMITS
00378 topvol->SetUserLimits(itsUserLimits);
00379 #endif
00380 }
00381 cur = cur->next;
00382 }
00383 return;
00384 }
00385
00386 void BDSGeometryLCDD::parseFIELDS(xmlNodePtr cur)
00387 {
00388 xmlNodePtr tempcur = cur->xmlChildrenNode;
00389 tempcur=tempcur->next;
00390 while (tempcur != NULL){
00391 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"solenoid"))){
00392 if(itsFieldIsUniform==true){
00393 G4Exception("BDSGeometryLCDD::parseFIELDS> making solenoid field but already built dipole field...", "-1", FatalException, "");
00394 }
00395 G4String name = parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"name"));
00396 G4double lunit = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"lunit"));
00397 G4double funit = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"funit"));
00398 G4double outer_radius = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"outer_radius")) * lunit;
00399 G4double inner_radius = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"inner_radius")) * lunit;
00400 G4double inner_field = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"inner_field")) * funit;
00401 G4double outer_field = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"outer_field")) * funit;
00402 G4double zmax = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"zmax")) * lunit;
00403 G4double zmin = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"zmin")) * lunit;
00404
00405
00406 itsMagField = new BDSDetectorSolenoidMagField(inner_field, outer_field, inner_radius, outer_radius, zmin, zmax);
00407 }else if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"bdsimdipole"))){
00408 G4String name = parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"name"));
00409 itsFieldVolName = parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"volume"));
00410 G4double funit = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"funit"));
00411 G4double field = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"field")) * funit;
00412 const G4ThreeVector fieldVec(0,field,0);
00413 itsUniformMagField=new G4UniformMagField(fieldVec);
00414 itsFieldIsUniform=true;
00415 }else if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"text"))){
00416 } else {
00417 G4cout << tempcur->name << G4endl;
00418 G4Exception("BDSGeometryLCDD.cc: parsing <fields - types other than solenoid and bdsimdipole are not currently implemented in BDSIM", "-1", FatalException, "");
00419 }
00420 tempcur=tempcur->next;
00421 }
00422 }
00423
00424 void BDSGeometryLCDD::parseSTRUCTURE(xmlNodePtr cur)
00425 {
00426 cur = cur->xmlChildrenNode;
00427
00428 while (cur != NULL)
00429 {
00430
00431 if ((!xmlStrcmp(cur->name, (const xmlChar *)"volume")))
00432 parseVOLUME(cur);
00433 cur = cur->next;
00434 }
00435
00436 return;
00437 }
00438
00439
00440 void BDSGeometryLCDD::parseDEFINE(xmlNodePtr cur)
00441 {
00442 cur = cur->xmlChildrenNode;
00443
00444 while (cur != NULL)
00445 {
00446
00447 if ((!xmlStrcmp(cur->name, (const xmlChar *)"rotation")))
00448 {
00449 ROT_REF arot;
00450 arot.name=(parseStrChar(xmlGetProp(cur,(const xmlChar*)"name")));
00451 arot.value=G4ThreeVector(parseDblChar(xmlGetProp(cur,(const xmlChar*)"x")),
00452 parseDblChar(xmlGetProp(cur,(const xmlChar*)"y")),
00453 parseDblChar(xmlGetProp(cur,(const xmlChar*)"z")));
00454
00455 ROT_LIST.push_back(arot);
00456 }
00457 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"position")))
00458 {
00459 POS_REF apos;
00460 apos.name=(parseStrChar(xmlGetProp(cur,(const xmlChar*)"name")));
00461 apos.value=G4ThreeVector(parseDblChar(xmlGetProp(cur,(const xmlChar*)"x")),
00462 parseDblChar(xmlGetProp(cur,(const xmlChar*)"y")),
00463 parseDblChar(xmlGetProp(cur,(const xmlChar*)"z")));
00464
00465 POS_LIST.push_back(apos);
00466 }
00467 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"constant")))
00468 {
00469 CONST_REF aconst;
00470 aconst.name=(parseStrChar(xmlGetProp(cur,(const xmlChar*)"name")));
00471 aconst.value=parseDblChar(xmlGetProp(cur,(const xmlChar*)"value"));
00472 CONST_LIST.push_back(aconst);
00473 }
00474 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"expression")))
00475 {
00476 G4Exception("LCDD expression not currently implemented in BDSIM", "-1", FatalException, "");
00477 }
00478 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"quantity")))
00479 {
00480 G4Exception("LCDD quantity not currently implemented in BDSIM", "-1", FatalException, "");
00481 }
00482 cur = cur->next;
00483 }
00484
00485 return;
00486 }
00487
00488 void BDSGeometryLCDD::parseMATERIALS(xmlNodePtr cur)
00489 {
00490 cur = cur->xmlChildrenNode;
00491 while (cur != NULL)
00492 {
00493 if ((!xmlStrcmp(cur->name, (const xmlChar *)"define")))
00494 {
00495 G4Exception("LCDD define not currently implemented in BDSIM", "-1", FatalException, "");
00496
00497 }
00498 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"isotope")))
00499 {
00500 G4Exception("LCDD isotop not currently implemented in BDSIM", "-1", FatalException, "");
00501
00502 }
00503 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"element")))
00504 {
00505 xmlNodePtr tempcur = cur->xmlChildrenNode;
00506 tempcur = tempcur->next;
00507
00508 G4String name, formula, type;
00509 G4double Z, value, unit;
00510
00511 formula = parseStrChar(xmlGetProp(cur,(const xmlChar*)"formula"));
00512
00513 if(!BDSMaterials::Instance()->CheckElement(formula)){
00514 if(!xmlStrcmp(tempcur->name, (const xmlChar *)"atom")){
00515 type = parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"type"));
00516 if (strcmp("A",type)){
00517 G4Exception("BDSGeometryLCDD.cc: parsing <element - types other than A are not currently implemented in BDSIM", "-1", FatalException, "");
00518 }
00519 unit = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"unit"));
00520 name = parseStrChar(xmlGetProp(cur,(const xmlChar*)"name"));
00521 Z = parseDblChar(xmlGetProp(cur,(const xmlChar*)"Z"));
00522
00523 value = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"value"));
00524 BDSMaterials::Instance()->AddElement(name, formula, Z, value*unit/(CLHEP::g/CLHEP::mole));
00525 } else {
00526 G4Exception("BDSGeometryLCDD.cc: not an atom, not currently implemented in BDSIM", "-1", FatalException, "");
00527 }
00528 } else {
00529 G4cout << "Warning: BDSGeometryLCDD.cc: element " << formula << " already defined in BDSMaterials.cc" << G4endl;
00530 }
00531 }
00532 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"material")))
00533 {
00534 xmlNodePtr tempcur = cur->xmlChildrenNode;
00535
00536 G4String name, type;
00537 G4double value(0), unit(1);
00538
00539 name = parseStrChar(xmlGetProp(cur,(const xmlChar*)"name"));
00540 if(BDSMaterials::Instance()->CheckMaterial(name)){
00541 G4cout << "Warning: BDSGeometryLCDD.cc: material " << name << " already defined in BDSMaterials.cc" << G4endl;
00542 } else {
00543
00544 G4int numFractions = 0;
00545 G4int numComposites = 0;
00546 G4bool composite=false;
00547 G4bool fraction=false;
00548
00549 tempcur = cur->xmlChildrenNode;
00550 while(tempcur!=NULL){
00551
00552 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"fraction"))){
00553 numFractions++;
00554 fraction=true;
00555 }
00556 else if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"composite"))){
00557 numComposites++;
00558 composite=true;
00559 }
00560
00561 if ((!xmlStrcmp(tempcur->name, (const xmlChar *)"D"))){
00562 value = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"value"));
00563 unit = parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"unit"));
00564 type = parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"type"));
00565 #ifdef BDSDEBUG
00566 G4cout << "BDSGeometryLCDD:ParseMaterials value = " << value << ", unit = " << unit << ", type = " << type << G4endl;
00567 #endif
00568 if (!strcmp("",type)){
00569 G4cout << "Warning - BDSGeometryLCDD.cc: parsing <material - type not defined, assuming type density." << G4endl;
00570 } else if (strcmp("density",type)){
00571 G4Exception("BDSGeometryLCDD.cc: parsing <material - types other than density are not currently implemented in BDSIM", "-1", FatalException, "");
00572 }
00573 }
00574 tempcur = tempcur->next;
00575 }
00576
00577 if(fraction==composite){
00578 G4Exception("BDSGeometry LCDD: Ill defined material fractions.", "-1", FatalException, "");
00579 }
00580
00581 std::list<const char*> components;
00582 std::list<G4String> stComponents;
00583 std::list<G4int> weights;
00584 std::list<G4double> fractions;
00585
00586 tempcur = cur->xmlChildrenNode;
00587 #ifdef BDSDEBUG
00588 G4cout << "BDSGeometryLCDD::parseMATERIALS - making list of fractions/composites" << G4endl;
00589 #endif
00590 while(tempcur!=NULL){
00591 #ifdef BDSDEBUG
00592 G4cout << "BDSGeometryLCDD::parseMATERIALS - name = " << tempcur->name << G4endl;
00593 #endif
00594 if (!xmlStrcmp(tempcur->name, (const xmlChar *)"fraction")){
00595 #ifdef BDSDEBUG
00596 G4cout << "BDSGeometryLCDD::parseMATERIALS - component = " << parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"ref")) << G4endl;
00597 #endif
00598 components.push_back((G4String)parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"ref")).c_str());
00599 stComponents.push_back((G4String)parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"ref")));
00600 #ifdef BDSDEBUG
00601 G4cout << components.back() << G4endl;
00602 G4cout << "BDSGeometryLCDD::parseMATERIALS - fraction = " << parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"n")) << G4endl;
00603 #endif
00604 fractions.push_back(parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"n")));
00605 } else if (!xmlStrcmp(tempcur->name, (const xmlChar *)"composite")){
00606 components.push_back((G4String)parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"ref")).c_str());
00607 stComponents.push_back((G4String)parseStrChar(xmlGetProp(tempcur,(const xmlChar*)"ref")));
00608 weights.push_back((G4int)parseDblChar(xmlGetProp(tempcur,(const xmlChar*)"n")));
00609 }
00610 tempcur = tempcur->next;
00611 }
00612
00613 std::list<const char*>::iterator sIter;
00614 std::list<G4String>::iterator stIter;
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 components.clear();
00625
00626 for(stIter = stComponents.begin();
00627 stIter!= stComponents.end();
00628 stIter++){
00629 #ifdef BDSDEBUG
00630 G4cout << "String element: " << *stIter << G4endl;
00631 #endif
00632 components.push_back((*stIter).c_str());
00633 #ifdef BDSDEBUG
00634 G4cout << "Element: " << components.back() << G4endl;
00635 #endif
00636 }
00637
00638 if (weights.size()>0){
00639 #ifdef BDSDEBUG
00640 G4cout << "Size of weights: " << weights.size() << G4endl;
00641 #endif
00642 BDSMaterials::Instance()->AddMaterial(name, value*unit/(CLHEP::g/CLHEP::cm3), kStateSolid, 300, 1, components, weights);
00643 } else if(fractions.size()>0){
00644 #ifdef BDSDEBUG
00645 G4cout << "Size of fractions: " << fractions.size() << G4endl;
00646 #endif
00647 BDSMaterials::Instance()->AddMaterial(name, value*unit/(CLHEP::g/CLHEP::cm3), kStateSolid, 300, 1, components, fractions);
00648 } else G4Exception("BDSGeometry LCDD: Ill defined material fractions - list of fractions and weights empty.", "-1", FatalException, "");
00649
00650 }
00651 }
00652 cur = cur->next;
00653 }
00654 return;
00655 }
00656
00657
00658 void BDSGeometryLCDD::parseSOLID(xmlNodePtr cur)
00659 {
00660 cur = cur->xmlChildrenNode;
00661
00662 while (cur != NULL)
00663 {
00664
00665 if ((!xmlStrcmp(cur->name, (const xmlChar *)"tube")))
00666 BuildTube(cur);
00667
00668 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"box")))
00669 BuildBox(cur);
00670
00671 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"cone")))
00672 {
00673 G4Exception("LCDD cone not currently implemented in BDSIM", "-1", FatalException, "");
00674 }
00675 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"eltube")))
00676 {
00677 G4Exception("LCDD eltube not currently implemented in BDSIM", "-1", FatalException, "");
00678 }
00679 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"hype")))
00680 {
00681 G4Exception("LCDD hype not currently implemented in BDSIM", "-1", FatalException, "");
00682 }
00683 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"intersection")))
00684 {
00685 G4Exception("LCDD intersection not currently implemented in BDSIM", "-1", FatalException, "");
00686 }
00687 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"orb")))
00688 {
00689 G4Exception("LCDD orb not currently implemented in BDSIM", "-1", FatalException, "");
00690 }
00691 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"sphere")))
00692 {
00693 G4Exception("LCDD sphere not currently implemented in BDSIM", "-1", FatalException, "");
00694 }
00695 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"trap")))
00696 {
00697 G4Exception("LCDD trap not currently implemented in BDSIM", "-1", FatalException, "");
00698 }
00699 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"subtraction")))
00700 BuildSubtraction(cur);
00701
00702 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"torus")))
00703 {
00704 G4Exception("LCDD torus not currently implemented in BDSIM", "-1", FatalException, "");
00705 }
00706 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"union")))
00707 {
00708 G4Exception("LCDD union not currently implemented in BDSIM", "-1", FatalException, "");
00709 }
00710
00711 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"polycone")))
00712 BuildPolycone(cur);
00713
00714 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"polyhedra")))
00715 {
00716 BuildPolyhedra(cur);
00717 }
00718
00719 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"trd")))
00720 {
00721 BuildTrd(cur);
00722 }
00723 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"tessellated")))
00724 {
00725 BuildTessellated(cur);
00726 }
00727 cur = cur->next;
00728 }
00729
00730 return;
00731 }
00732
00733 void BDSGeometryLCDD::parseVOLUME(xmlNodePtr cur)
00734 {
00735 G4String volume_name = parseStrChar(xmlGetProp(cur,(const xmlChar*)"name"));
00736 cur = cur->xmlChildrenNode;
00737
00738 G4String materialref;
00739 G4String solidref;
00740 G4String visref;
00741 xmlNodePtr origcur = cur;
00742 while (cur != NULL)
00743 {
00744 if ((!xmlStrcmp(cur->name, (const xmlChar *)"materialref")))
00745 {
00746 materialref = parseStrChar(xmlGetProp(cur,(const xmlChar*)"ref"));
00747 #ifdef BDSDEBUG
00748 G4cout << "BDSGeometryLCDD> materialref = " << materialref << G4endl;
00749 #endif
00750 }
00751 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"solidref")))
00752 {
00753 solidref = parseStrChar(xmlGetProp(cur,(const xmlChar*)"ref"));
00754 #ifdef BDSDEBUG
00755 G4cout << "BDSGeometryLCDD> solidref = " << solidref << G4endl;
00756 #endif
00757 }
00758 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"visref")))
00759 {
00760 visref = parseStrChar(xmlGetProp(cur,(const xmlChar*)"ref"));
00761 #ifdef BDSDEBUG
00762 G4cout << "BDSGeometryLCDD> visref = " << visref << G4endl;
00763 #endif
00764 }
00765
00766 cur = cur->next;
00767 }
00768
00769 if(materialref!="" && solidref!="")
00770 {
00771 G4LogicalVolume* alogvol = new G4LogicalVolume(GetSolidByName(solidref),
00772 BDSMaterials::Instance()->GetMaterial(materialref),
00773 volume_name);
00774 #ifndef NOUSERLIMITS
00775 alogvol->SetUserLimits(itsUserLimits);
00776 #endif
00777
00778 SensitiveComponents.push_back(alogvol);
00779 LOGVOL_LIST.push_back(alogvol);
00780
00781 if(visref==""){
00782 G4VisAttributes* VisAtt =
00783 new G4VisAttributes(G4Colour(1., 1., 1.));
00784 VisAtt->SetForceWireframe(true);
00785 alogvol->SetVisAttributes(VisAtt);
00786 }
00787 else{
00788 alogvol->SetVisAttributes(GetVisByName(visref));
00789 }
00790
00791 while(origcur!=NULL)
00792 {
00793 if ((!xmlStrcmp(origcur->name, (const xmlChar *)"physvol")))
00794 {
00795 parsePHYSVOL(origcur, volume_name);
00796 }
00797 origcur = origcur->next;
00798 }
00799 }
00800
00801 else
00802 {
00803 G4cout << "Can't build" << volume_name << " : " << solidref << G4endl;
00804 G4Exception("Can't build volume","-1", FatalException, "");
00805 }
00806
00807
00808
00809 return;
00810 }
00811
00812 void BDSGeometryLCDD::parsePHYSVOL(xmlNodePtr cur, G4String volume_name)
00813 {
00814 cur = cur->xmlChildrenNode;
00815
00816 G4String volumeref;
00817
00818 G4RotationMatrix* componentRotation = NULL;
00819
00820 G4ThreeVector PlacementPoint;
00821
00822
00823 while (cur != NULL)
00824 {
00825 if ((!xmlStrcmp(cur->name, (const xmlChar *)"volumeref")))
00826 volumeref = parseStrChar(xmlGetProp(cur,(const xmlChar*)"ref"));
00827
00828 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"positionref")))
00829 PlacementPoint = GetPosition(parseStrChar(xmlGetProp(cur,(const xmlChar*)"ref")));
00830
00831 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"position")))
00832 PlacementPoint = GetPosition(cur);
00833
00834 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"rotationref")))
00835 componentRotation = GetRotation(parseStrChar(xmlGetProp(cur,(const xmlChar*)"ref")));
00836
00837 else if ((!xmlStrcmp(cur->name, (const xmlChar *)"rotation")))
00838 componentRotation = GetRotation(cur);
00839
00840 cur = cur->next;
00841 }
00842
00843 G4LogicalVolume* currentVol = GetLogVolByName(volumeref);
00844 G4LogicalVolume* parentVol = GetLogVolByName(volume_name);
00845
00846 new G4PVPlacement(componentRotation,
00847 PlacementPoint,
00848 currentVol,
00849 currentVol->GetName()+"_PhysiComp",
00850 parentVol,
00851 false,
00852 0, BDSGlobalConstants::Instance()->GetCheckOverlaps());
00853
00854
00855 return;
00856 }
00857
00858 G4RotationMatrix* BDSGeometryLCDD::RotateComponent(G4ThreeVector rotvalues)
00859 {
00860 G4RotationMatrix *rotateComponent = new G4RotationMatrix;
00861
00862
00863
00864 rotateComponent->rotateX(rotvalues.x());
00865 rotateComponent->rotateY(rotvalues.y());
00866 rotateComponent->rotateZ(rotvalues.z());
00867
00868
00869 return rotateComponent;
00870 }
00871
00872 #endif