00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "G4tgbGeometryDumper.hh"
00038
00039 #include "G4tgrMessenger.hh"
00040
00041 #include "G4SystemOfUnits.hh"
00042 #include "G4UIcommand.hh"
00043 #include "G4Material.hh"
00044 #include "G4Element.hh"
00045 #include "G4VSolid.hh"
00046 #include "G4Box.hh"
00047 #include "G4Tubs.hh"
00048 #include "G4Cons.hh"
00049 #include "G4Trap.hh"
00050 #include "G4Sphere.hh"
00051 #include "G4Orb.hh"
00052 #include "G4Trd.hh"
00053 #include "G4Para.hh"
00054 #include "G4Torus.hh"
00055 #include "G4Hype.hh"
00056 #include "G4Polycone.hh"
00057 #include "G4Polyhedra.hh"
00058 #include "G4EllipticalTube.hh"
00059 #include "G4Ellipsoid.hh"
00060 #include "G4EllipticalCone.hh"
00061 #include "G4Hype.hh"
00062 #include "G4Tet.hh"
00063 #include "G4TwistedBox.hh"
00064 #include "G4TwistedTrap.hh"
00065 #include "G4TwistedTrd.hh"
00066 #include "G4TwistedTubs.hh"
00067 #include "G4PVPlacement.hh"
00068 #include "G4PVParameterised.hh"
00069 #include "G4PVReplica.hh"
00070 #include "G4BooleanSolid.hh"
00071 #include "G4ReflectionFactory.hh"
00072 #include "G4ReflectedSolid.hh"
00073 #include "G4LogicalVolumeStore.hh"
00074 #include "G4PhysicalVolumeStore.hh"
00075 #include "G4GeometryTolerance.hh"
00076 #include "G4VPVParameterisation.hh"
00077 #include <iomanip>
00078
00079
00080 G4tgbGeometryDumper* G4tgbGeometryDumper::theInstance = 0;
00081
00082
00083 G4tgbGeometryDumper::G4tgbGeometryDumper()
00084 : theFile(0), theRotationNumber(0)
00085 {
00086 }
00087
00088
00089 G4tgbGeometryDumper* G4tgbGeometryDumper::GetInstance()
00090 {
00091 if( theInstance == 0 ){
00092 theInstance = new G4tgbGeometryDumper;
00093 }
00094
00095 return theInstance;
00096
00097 }
00098
00099
00100 void G4tgbGeometryDumper::DumpGeometry( const G4String& fname )
00101 {
00102 theFile = new std::ofstream(fname);
00103
00104 G4VPhysicalVolume* pv = GetTopPhysVol();
00105 DumpPhysVol( pv );
00106 }
00107
00108
00109 G4VPhysicalVolume* G4tgbGeometryDumper::GetTopPhysVol()
00110 {
00111 G4PhysicalVolumeStore* pvstore = G4PhysicalVolumeStore::GetInstance();
00112 G4PhysicalVolumeStore::const_iterator ite;
00113 G4VPhysicalVolume* pv = *(pvstore->begin());
00114 for( ;; )
00115 {
00116 G4LogicalVolume* lv = pv->GetMotherLogical();
00117 if( lv == 0 ) { break; }
00118
00119
00120 for( ite = pvstore->begin(); ite != pvstore->end(); ite++ )
00121 {
00122 pv = (*ite);
00123 if( pv->GetLogicalVolume() == lv )
00124 {
00125 break;
00126 }
00127 }
00128 }
00129
00130 return pv;
00131 }
00132
00133
00134
00135 G4tgbGeometryDumper::~G4tgbGeometryDumper()
00136 {
00137 }
00138
00139
00140 void G4tgbGeometryDumper::DumpPhysVol( G4VPhysicalVolume* pv )
00141 {
00142
00143
00144 G4LogicalVolume* lv = pv->GetLogicalVolume();
00145
00146 G4ReflectionFactory* reffact = G4ReflectionFactory::Instance();
00147
00148
00149
00150
00151
00152 if( reffact->IsReflected( lv )
00153 && reffact->IsReflected( pv->GetMotherLogical() ) ) { return; }
00154
00155
00156 G4bool bVolExists = CheckIfLogVolExists( lv->GetName(), lv );
00157
00158
00159 if( pv->GetMotherLogical() != 0 )
00160 {
00161 if( !pv->IsReplicated() )
00162 {
00163 G4String lvName = lv->GetName();
00164 if( !bVolExists )
00165 {
00166 lvName = DumpLogVol( lv );
00167 }
00168 DumpPVPlacement( pv, lvName );
00169 }
00170 else if( pv->IsParameterised() )
00171 {
00172 G4PVParameterised* pvparam = (G4PVParameterised*)(pv);
00173 DumpPVParameterised( pvparam );
00174 }
00175 else
00176 {
00177 G4String lvName = lv->GetName();
00178 if( !bVolExists )
00179 {
00180 lvName = DumpLogVol( lv );
00181 }
00182 G4PVReplica* pvrepl = (G4PVReplica*)(pv);
00183 DumpPVReplica( pvrepl, lvName );
00184 }
00185
00186 }
00187 else
00188 {
00189 DumpLogVol( lv );
00190 }
00191
00192 if( !bVolExists )
00193 {
00194
00195 std::vector<G4VPhysicalVolume*> pvChildren = GetPVChildren( lv );
00196 std::vector<G4VPhysicalVolume*>::const_iterator ite;
00197 for( ite = pvChildren.begin(); ite != pvChildren.end(); ite++ )
00198 {
00199 DumpPhysVol( *ite );
00200 }
00201 }
00202 }
00203
00204
00205 void
00206 G4tgbGeometryDumper::DumpPVPlacement( G4VPhysicalVolume* pv,
00207 const G4String& lvName, G4int copyNo )
00208 {
00209 G4String pvName = pv->GetName();
00210
00211 G4RotationMatrix* rotMat = pv->GetRotation();
00212 if( !rotMat ) rotMat = new G4RotationMatrix();
00213
00214
00215 G4ReflectionFactory* reffact = G4ReflectionFactory::Instance();
00216 G4LogicalVolume* lv = pv->GetLogicalVolume();
00217 if( reffact->IsReflected( lv ) )
00218 {
00219 #ifdef G4VERBOSE
00220 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
00221 {
00222 G4cout << " G4tgbGeometryDumper::DumpPVPlacement() - Reflected volume: "
00223 << pv->GetName() << G4endl;
00224 }
00225 #endif
00226 G4ThreeVector colx = rotMat->colX();
00227 G4ThreeVector coly = rotMat->colY();
00228 G4ThreeVector colz = rotMat->colZ();
00229
00230
00231 colz *= -1.;
00232 G4Rep3x3 rottemp(colx.x(),coly.x(),colz.x(),
00233 colx.y(),coly.y(),colz.y(),
00234 colx.z(),coly.z(),colz.z());
00235
00236 *rotMat = G4RotationMatrix(rottemp);
00237 *rotMat = (*rotMat).inverse();
00238 pvName += "_refl";
00239 }
00240 G4String rotName = DumpRotationMatrix( rotMat );
00241 G4ThreeVector pos = pv->GetTranslation();
00242
00243 if( copyNo == -999 )
00244 {
00245 copyNo = pv->GetCopyNo();
00246 }
00247
00248 G4String fullname = pvName
00249 +"#"+G4UIcommand::ConvertToString(copyNo)
00250 +"/"+pv->GetMotherLogical()->GetName();
00251
00252 if( !CheckIfPhysVolExists(fullname, pv ))
00253 {
00254 (*theFile)
00255 << ":PLACE "
00256 << SubstituteRefl(AddQuotes(lvName))
00257 << " " << copyNo << " "
00258 << SubstituteRefl(AddQuotes(pv->GetMotherLogical()->GetName()))
00259 << " " << AddQuotes(rotName) << " "
00260 << pos.x() << " " << pos.y() << " " << pos.z() << G4endl;
00261
00262 thePhysVols[fullname] = pv;
00263 }
00264 }
00265
00266
00267
00268 void G4tgbGeometryDumper::DumpPVParameterised( G4PVParameterised* pv )
00269 {
00270 G4String pvName = pv->GetName();
00271
00272 EAxis axis;
00273 G4int nReplicas;
00274 G4double width;
00275 G4double offset;
00276 G4bool consuming;
00277 pv->GetReplicationData(axis, nReplicas, width, offset, consuming);
00278
00279 G4VPVParameterisation* param = pv->GetParameterisation();
00280
00281 G4LogicalVolume* lv = pv->GetLogicalVolume();
00282 G4VSolid* solid1st = param->ComputeSolid(0, pv);
00283 G4Material* mate1st = param->ComputeMaterial(0, pv );
00284 std::vector<G4double> params1st = GetSolidParams( solid1st );
00285 std::vector<G4double> newParams;
00286 G4VSolid* newSolid = solid1st;
00287 G4String lvName;
00288
00289 for( G4int ii = 0; ii < nReplicas; ii++ )
00290 {
00291 G4Material* newMate = param->ComputeMaterial(ii, pv );
00292 if( solid1st->GetEntityType() == "G4Box")
00293 {
00294 G4Box* box = (G4Box*)(solid1st);
00295 param->ComputeDimensions(*box, ii, pv );
00296 newParams = GetSolidParams( box );
00297 newSolid = (G4VSolid*)box;
00298 }
00299 else if( solid1st->GetEntityType() == "G4Tubs")
00300 {
00301 G4Tubs* tubs = (G4Tubs*)(solid1st);
00302 param->ComputeDimensions(*tubs, ii, pv );
00303 newParams = GetSolidParams( tubs );
00304 newSolid = (G4VSolid*)tubs;
00305 }
00306 else if( solid1st->GetEntityType() == "G4Trd")
00307 {
00308 G4Trd* trd = (G4Trd*)(solid1st);
00309 param->ComputeDimensions(*trd, ii, pv );
00310 newParams = GetSolidParams( trd );
00311 newSolid = (G4VSolid*)trd;
00312 }
00313 else if( solid1st->GetEntityType() == "G4Trap")
00314 {
00315 G4Trap* trap = (G4Trap*)(solid1st);
00316 param->ComputeDimensions(*trap, ii, pv );
00317 newParams = GetSolidParams( trap );
00318 newSolid = (G4VSolid*)trap;
00319 }
00320 else if( solid1st->GetEntityType() == "G4Cons")
00321 {
00322 G4Cons* cons = (G4Cons*)(solid1st);
00323 param->ComputeDimensions(*cons, ii, pv );
00324 newParams = GetSolidParams( cons );
00325 newSolid = (G4VSolid*)cons;
00326 }
00327 else if( solid1st->GetEntityType() == "G4Sphere")
00328 {
00329 G4Sphere* sphere = (G4Sphere*)(solid1st);
00330 param->ComputeDimensions(*sphere, ii, pv );
00331 newParams = GetSolidParams( sphere );
00332 newSolid = (G4VSolid*)sphere;
00333 }
00334 else if( solid1st->GetEntityType() == "G4Orb")
00335 {
00336 G4Orb* orb = (G4Orb*)(solid1st);
00337 param->ComputeDimensions(*orb, ii, pv );
00338 newParams = GetSolidParams( orb );
00339 newSolid = (G4VSolid*)orb;
00340 }
00341 else if( solid1st->GetEntityType() == "G4Torus")
00342 {
00343 G4Torus* torus = (G4Torus*)(solid1st);
00344 param->ComputeDimensions(*torus, ii, pv );
00345 newParams = GetSolidParams( torus );
00346 newSolid = (G4VSolid*)torus;
00347 }
00348 else if( solid1st->GetEntityType() == "G4Para")
00349 {
00350 G4Para* para = (G4Para*)(solid1st);
00351 param->ComputeDimensions(*para, ii, pv );
00352 newParams = GetSolidParams( para );
00353 newSolid = (G4VSolid*)para;
00354 }
00355 else if( solid1st->GetEntityType() == "G4Polycone")
00356 {
00357 G4Polycone* polycone = (G4Polycone*)(solid1st);
00358 param->ComputeDimensions(*polycone, ii, pv );
00359 newParams = GetSolidParams( polycone );
00360 newSolid = (G4VSolid*)polycone;
00361 }
00362 else if( solid1st->GetEntityType() == "G4Polyhedra")
00363 {
00364 G4Polyhedra* polyhedra = (G4Polyhedra*)(solid1st);
00365 param->ComputeDimensions(*polyhedra, ii, pv );
00366 newParams = GetSolidParams( polyhedra );
00367 newSolid = (G4VSolid*)polyhedra;
00368 }
00369 else if( solid1st->GetEntityType() == "G4Hype")
00370 {
00371 G4Hype* hype = (G4Hype*)(solid1st);
00372 param->ComputeDimensions(*hype, ii, pv );
00373 newParams = GetSolidParams( hype );
00374 newSolid = (G4VSolid*)hype;
00375 }
00376 if( ii == 0 || mate1st != newMate || params1st[0] != newParams[0] )
00377 {
00378 G4String extraName = "";
00379 if( ii != 0 )
00380 {
00381 extraName= "#"+G4UIcommand::ConvertToString(ii)
00382 +"/"+pv->GetMotherLogical()->GetName();
00383 }
00384 lvName = DumpLogVol( lv, extraName, newSolid, newMate );
00385 }
00386
00387 param->ComputeTransformation(ii, pv);
00388 DumpPVPlacement( pv, lvName, ii );
00389 }
00390 }
00391
00392
00393
00394 void G4tgbGeometryDumper::DumpPVReplica( G4PVReplica* pv,
00395 const G4String& lvName )
00396 {
00397 EAxis axis;
00398 G4int nReplicas;
00399 G4double width;
00400 G4double offset;
00401 G4bool consuming;
00402 pv->GetReplicationData(axis, nReplicas, width, offset, consuming);
00403 G4String axisName;
00404 switch (axis )
00405 {
00406 case kXAxis:
00407 axisName = "X";
00408 break;
00409 case kYAxis:
00410 axisName = "Y";
00411 break;
00412 case kZAxis:
00413 axisName = "Z";
00414 break;
00415 case kRho:
00416 axisName = "R";
00417 break;
00418 case kPhi:
00419 axisName = "PHI";
00420 break;
00421 case kRadial3D:
00422 case kUndefined:
00423 G4String ErrMessage = "Unknown axis of replication for volume"
00424 + pv->GetName();
00425 G4Exception("G4tgbGeometryDumper::DumpPVReplica",
00426 "Wrong axis ", FatalException, ErrMessage);
00427 break;
00428 }
00429
00430 G4String fullname = lvName
00431 +"/"+pv->GetMotherLogical()->GetName();
00432
00433 if( !CheckIfPhysVolExists(fullname, pv ))
00434 {
00435 (*theFile)
00436 << ":REPL "
00437 << SubstituteRefl(AddQuotes(lvName))
00438 << " " << SubstituteRefl(AddQuotes(pv->GetMotherLogical()->GetName()))
00439 << " " << axisName
00440 << " " << nReplicas;
00441 if( axis != kPhi )
00442 {
00443 (*theFile)
00444 << " " << width
00445 << " " << offset << G4endl;
00446 }
00447 else
00448 {
00449 (*theFile)
00450 << " " << width/deg << "*deg"
00451 << " " << offset/deg << "*deg" << G4endl;
00452 }
00453
00454 thePhysVols[fullname] = pv;
00455 }
00456 }
00457
00458
00459
00460 G4String
00461 G4tgbGeometryDumper::DumpLogVol( G4LogicalVolume* lv, G4String extraName,
00462 G4VSolid* solid, G4Material* mate )
00463 {
00464 G4String lvName;
00465
00466 if( extraName == "" )
00467 {
00468 lvName = GetObjectName(lv,theLogVols);
00469 }
00470 else
00471 {
00472 lvName = lv->GetName()+extraName;
00473 }
00474
00475 if( theLogVols.find( lvName ) != theLogVols.end() )
00476 {
00477 return lvName;
00478 }
00479
00480 if( !solid ) { solid = lv->GetSolid(); }
00481
00482
00483 G4String solidName = DumpSolid( solid, extraName );
00484
00485
00486 if( !mate ) { mate = lv->GetMaterial(); }
00487 G4String mateName = DumpMaterial( mate );
00488
00489
00490 (*theFile) << ":VOLU " << SubstituteRefl(AddQuotes(lvName)) << " "
00491 << SupressRefl(AddQuotes(solidName))
00492 << " " << AddQuotes(mateName) << G4endl;
00493
00494 theLogVols[lvName] = lv;
00495
00496 return lvName;
00497 }
00498
00499
00500
00501 G4String G4tgbGeometryDumper::DumpMaterial( G4Material* mat )
00502 {
00503 G4String mateName = GetObjectName(mat,theMaterials);
00504 if( theMaterials.find( mateName ) != theMaterials.end() )
00505 {
00506 return mateName;
00507 }
00508
00509 size_t numElements = mat->GetNumberOfElements();
00510 G4double density = mat->GetDensity()/g*cm3;
00511
00512
00513
00514
00515 if (numElements == 1)
00516 {
00517 (*theFile) << ":MATE " << AddQuotes(mateName) << " "
00518 << mat->GetZ() << " " << mat->GetA()/(g/mole) << " "
00519 << density << G4endl;
00520 }
00521 else
00522 {
00523 const G4ElementVector* elems = mat->GetElementVector();
00524 const G4double* fractions = mat->GetFractionVector();
00525 for (size_t ii = 0; ii < numElements; ii++)
00526 {
00527 DumpElement( (*elems)[ii] );
00528 }
00529
00530 (*theFile) << ":MIXT "<< AddQuotes(mateName) << " "
00531 << density << " " << numElements << G4endl;
00532
00533 for (size_t ii = 0; ii < numElements; ii++)
00534 {
00535 (*theFile) << " "
00536 << AddQuotes(GetObjectName((*elems)[ii],theElements)) << " "
00537 << fractions[ii] << G4endl;
00538 }
00539
00540 }
00541
00542 (*theFile) << ":MATE_MEE " << AddQuotes(mateName) << " "
00543 << mat->GetIonisation()->GetMeanExcitationEnergy()/eV
00544 << "*eV" << G4endl;
00545
00546 (*theFile) << ":MATE_TEMPERATURE " << AddQuotes(mateName) << " "
00547 << mat->GetTemperature()/kelvin << "*kelvin" << G4endl;
00548
00549 (*theFile) << ":MATE_PRESSURE " << AddQuotes(mateName) << " "
00550 << mat->GetPressure()/atmosphere << "*atmosphere" << G4endl;
00551
00552 G4State state = mat->GetState();
00553 G4String stateStr;
00554 switch (state) {
00555 case kStateUndefined:
00556 stateStr = "Undefined";
00557 break;
00558 case kStateSolid:
00559 stateStr = "Solid";
00560 break;
00561 case kStateLiquid:
00562 stateStr = "Liquid";
00563 break;
00564 case kStateGas:
00565 stateStr = "Gas";
00566 break;
00567 }
00568
00569 (*theFile) << ":MATE_STATE " << AddQuotes(mateName) << " "
00570 << stateStr << G4endl;
00571
00572 theMaterials[mateName] = mat;
00573
00574 return mateName;
00575 }
00576
00577
00578
00579 void G4tgbGeometryDumper::DumpElement( G4Element* ele)
00580 {
00581 G4String elemName = GetObjectName(ele,theElements);
00582
00583 if( theElements.find( elemName ) != theElements.end() )
00584 {
00585 return;
00586 }
00587
00588
00589
00590
00591 G4String symbol = ele->GetSymbol();
00592 if( symbol == "" || symbol == " " )
00593 {
00594 symbol = elemName;
00595 }
00596
00597 if( ele->GetNumberOfIsotopes() == 0 )
00598 {
00599 (*theFile) << ":ELEM " << AddQuotes(elemName) << " "
00600 << AddQuotes(symbol) << " " << ele->GetZ() << " "
00601 << ele->GetA()/(g/mole) << " " << G4endl;
00602 }
00603 else
00604 {
00605 const G4IsotopeVector* isots = ele->GetIsotopeVector();
00606 for (size_t ii = 0; ii < ele->GetNumberOfIsotopes(); ii++)
00607 {
00608 DumpIsotope( (*isots)[ii] );
00609 }
00610
00611 (*theFile) << ":ELEM_FROM_ISOT " << AddQuotes(elemName) << " "
00612 << AddQuotes(symbol) << " " << ele->GetNumberOfIsotopes()
00613 << G4endl;
00614 const G4double* fractions = ele->GetRelativeAbundanceVector();
00615 for (size_t ii = 0; ii < ele->GetNumberOfIsotopes(); ii++)
00616 {
00617 (*theFile) << " "
00618 << AddQuotes(GetObjectName((*isots)[ii],theIsotopes)) << " "
00619 << fractions[ii] << G4endl;
00620 }
00621 }
00622 theElements[elemName] = ele;
00623 }
00624
00625
00626
00627 void G4tgbGeometryDumper::DumpIsotope( G4Isotope* isot)
00628 {
00629 G4String isotName = GetObjectName(isot,theIsotopes);
00630 if( theIsotopes.find( isotName ) != theIsotopes.end() )
00631 {
00632 return;
00633 }
00634
00635 (*theFile) << ":ISOT " << AddQuotes(isotName) << " "
00636 << isot->GetZ() << " " << isot->GetN() << " "
00637 << isot->GetA()/(g/mole) << " " << G4endl;
00638
00639 theIsotopes[isotName] = isot;
00640 }
00641
00642
00643
00644 G4String G4tgbGeometryDumper::DumpSolid( G4VSolid* solid,
00645 const G4String& extraName )
00646 {
00647 G4String solidName;
00648 if( extraName == "" )
00649 {
00650 solidName = GetObjectName(solid,theSolids);
00651 }
00652 else
00653 {
00654 solidName = solid->GetName()+extraName;
00655 }
00656
00657 if( theSolids.find( solidName ) != theSolids.end() )
00658 {
00659 return solidName;
00660 }
00661
00662 G4String solidType = solid->GetEntityType();
00663 solidType = GetTGSolidType( solidType );
00664
00665 if (solidType == "UNIONSOLID")
00666 {
00667 DumpBooleanVolume( "UNION", solid );
00668
00669 } else if (solidType == "SUBTRACTIONSOLID") {
00670 DumpBooleanVolume( "SUBTRACTION", solid );
00671
00672 } else if (solidType == "INTERSECTIONSOLID") {
00673 DumpBooleanVolume( "INTERSECTION", solid );
00674
00675 } else if (solidType == "REFLECTEDSOLID") {
00676 G4ReflectedSolid* solidrefl = dynamic_cast<G4ReflectedSolid*>(solid);
00677 if (!solidrefl)
00678 {
00679 G4Exception("G4tgbGeometryDumper::DumpSolid()",
00680 "InvalidType", FatalException, "Invalid reflected solid!");
00681 return solidName;
00682 }
00683 G4VSolid* solidori = solidrefl->GetConstituentMovedSolid();
00684 DumpSolid( solidori );
00685 }
00686 else
00687 {
00688 (*theFile) << ":SOLID " << AddQuotes(solidName) << " ";
00689 (*theFile) << AddQuotes(solidType) << " ";
00690 DumpSolidParams( solid );
00691 theSolids[solidName] = solid;
00692 }
00693
00694 return solidName;
00695 }
00696
00697
00698
00699 void G4tgbGeometryDumper::DumpBooleanVolume( const G4String& solidType,
00700 G4VSolid* so )
00701 {
00702 G4BooleanSolid * bso = dynamic_cast < G4BooleanSolid * > (so);
00703 if (!bso) { return; }
00704 G4VSolid* solid0 = bso->GetConstituentSolid( 0 );
00705 G4VSolid* solid1 = bso->GetConstituentSolid( 1 );
00706 G4DisplacedSolid* solid1Disp = 0;
00707 G4bool displaced = dynamic_cast<G4DisplacedSolid*>(solid1);
00708 if( displaced )
00709 {
00710 solid1Disp = dynamic_cast<G4DisplacedSolid*>(solid1);
00711 if (solid1Disp) { solid1 = solid1Disp->GetConstituentMovedSolid(); }
00712 }
00713 DumpSolid( solid0 );
00714 DumpSolid( solid1 );
00715
00716 G4String rotName;
00717 G4ThreeVector pos;
00718 if( displaced )
00719 {
00720 pos = solid1Disp->GetObjectTranslation();
00721 rotName = DumpRotationMatrix( new G4RotationMatrix( (solid1Disp->
00722 GetTransform().NetRotation()).inverse() ) );
00723 }
00724 else
00725 {
00726 rotName = DumpRotationMatrix( new G4RotationMatrix );
00727 pos = G4ThreeVector();
00728 }
00729
00730 G4String bsoName = GetObjectName(so,theSolids);
00731 if( theSolids.find( bsoName ) != theSolids.end() ) return;
00732 G4String solid0Name = FindSolidName( solid0 );
00733 G4String solid1Name = FindSolidName( solid1 );
00734
00735 (*theFile) << ":SOLID "
00736 << AddQuotes(bsoName) << " "
00737 << AddQuotes(solidType) << " "
00738 << AddQuotes(solid0Name) << " "
00739 << AddQuotes(solid1Name) << " "
00740 << AddQuotes(rotName) << " "
00741 << approxTo0(pos.x()) << " "
00742 << approxTo0(pos.y()) << " "
00743 << approxTo0(pos.z()) << " " << G4endl;
00744
00745 theSolids[bsoName] = bso;
00746 }
00747
00748
00749
00750 void G4tgbGeometryDumper::DumpSolidParams( G4VSolid * so)
00751 {
00752 std::vector<G4double> params = GetSolidParams( so );
00753 for( size_t ii = 0 ; ii < params.size(); ii++ )
00754 {
00755 (*theFile) << params[ii] << " " ;
00756 }
00757 (*theFile) << G4endl;
00758 }
00759
00760
00761
00762 std::vector<G4double> G4tgbGeometryDumper::GetSolidParams( const G4VSolid * so)
00763 {
00764 std::vector<G4double> params;
00765
00766 G4String solidType = so->GetEntityType();
00767 solidType = GetTGSolidType( solidType );
00768
00769 if (solidType == "BOX") {
00770 const G4Box * sb = dynamic_cast < const G4Box*>(so);
00771 if (sb) {
00772 params.push_back( sb->GetXHalfLength() );
00773 params.push_back( sb->GetYHalfLength() );
00774 params.push_back( sb->GetZHalfLength() );
00775 }
00776 } else if (solidType == "TUBS") {
00777 const G4Tubs * tu = dynamic_cast < const G4Tubs * > (so);
00778 if (tu) {
00779 params.push_back( tu->GetInnerRadius() );
00780 params.push_back( tu->GetOuterRadius() );
00781 params.push_back( tu->GetZHalfLength() );
00782 params.push_back( tu->GetStartPhiAngle()/deg );
00783 params.push_back( tu->GetDeltaPhiAngle()/deg );
00784 }
00785 } else if (solidType == "TRAP") {
00786 const G4Trap * trp = dynamic_cast < const G4Trap * > (so);
00787 if (trp) {
00788 G4ThreeVector symAxis(trp->GetSymAxis());
00789 G4double theta = symAxis.theta()/deg;
00790 G4double phi = symAxis.phi()/deg;
00791 params.push_back( trp->GetZHalfLength() );
00792 params.push_back( theta );
00793 params.push_back( phi);
00794 params.push_back( trp->GetYHalfLength1() );
00795 params.push_back( trp->GetXHalfLength1() );
00796 params.push_back( trp->GetXHalfLength2() );
00797 params.push_back( std::atan(trp->GetTanAlpha1())/deg );
00798 params.push_back( trp->GetYHalfLength2() );
00799 params.push_back( trp->GetXHalfLength3() );
00800 params.push_back( trp->GetXHalfLength4() );
00801 params.push_back( std::atan(trp->GetTanAlpha2())/deg );
00802 }
00803 } else if (solidType == "TRD") {
00804 const G4Trd * tr = dynamic_cast < const G4Trd * > (so);
00805 if (tr) {
00806 params.push_back( tr->GetXHalfLength1() );
00807 params.push_back( tr->GetXHalfLength2() );
00808 params.push_back( tr->GetYHalfLength1() );
00809 params.push_back( tr->GetYHalfLength2() );
00810 params.push_back( tr->GetZHalfLength());
00811 }
00812 } else if (solidType == "PARA") {
00813 const G4Para * para = dynamic_cast < const G4Para * > (so);
00814 if (para) {
00815 G4double phi = 0.;
00816 if(para->GetSymAxis().z()!=1.0)
00817 { phi = std::atan(para->GetSymAxis().y()/para->GetSymAxis().x()); }
00818 params.push_back( para->GetXHalfLength());
00819 params.push_back( para->GetYHalfLength());
00820 params.push_back( para->GetZHalfLength());
00821 params.push_back( std::atan(para->GetTanAlpha())/deg);
00822 params.push_back( std::acos(para->GetSymAxis().z())/deg);
00823 params.push_back( phi/deg);
00824 }
00825 } else if (solidType == "CONS") {
00826 const G4Cons * cn = dynamic_cast < const G4Cons * > (so);
00827 if (cn) {
00828 params.push_back( cn->GetInnerRadiusMinusZ() );
00829 params.push_back( cn->GetOuterRadiusMinusZ() );
00830 params.push_back( cn->GetInnerRadiusPlusZ() );
00831 params.push_back( cn->GetOuterRadiusPlusZ() );
00832 params.push_back( cn->GetZHalfLength() );
00833 params.push_back( cn->GetStartPhiAngle()/deg );
00834 params.push_back( cn->GetDeltaPhiAngle()/deg );
00835 }
00836 } else if (solidType == "SPHERE") {
00837 const G4Sphere * sphere = dynamic_cast < const G4Sphere * > (so);
00838 if (sphere) {
00839 params.push_back( sphere->GetInnerRadius());
00840 params.push_back( sphere->GetOuterRadius());
00841 params.push_back( sphere->GetStartPhiAngle()/deg);
00842 params.push_back( sphere->GetDeltaPhiAngle()/deg);
00843 params.push_back( sphere->GetStartThetaAngle()/deg);
00844 params.push_back( sphere->GetDeltaThetaAngle()/deg);
00845 }
00846 } else if (solidType == "ORB") {
00847 const G4Orb * orb = dynamic_cast < const G4Orb * > (so);
00848 if (orb) {
00849 params.push_back( orb->GetRadius());
00850 }
00851 } else if (solidType == "TORUS") {
00852 const G4Torus * torus = dynamic_cast < const G4Torus * > (so);
00853 if (torus) {
00854 params.push_back( torus->GetRmin());
00855 params.push_back( torus->GetRmax());
00856 params.push_back( torus->GetRtor());
00857 params.push_back( torus->GetSPhi()/deg);
00858 params.push_back( torus->GetDPhi()/deg);
00859 }
00860 } else if (solidType == "POLYCONE") {
00861
00862
00863 const G4Polycone * plc = dynamic_cast < const G4Polycone * > (so);
00864 if (plc) {
00865 G4double angphi = plc->GetStartPhi()/deg;
00866 if( angphi > 180*deg ) { angphi -= 360*deg; }
00867 G4int ncor = plc->GetNumRZCorner();
00868 params.push_back( angphi );
00869 params.push_back( plc->GetOriginalParameters()->Opening_angle/deg );
00870 params.push_back( ncor );
00871
00872 for( G4int ii = 0; ii < ncor; ii++ )
00873 {
00874 params.push_back( plc->GetCorner(ii).r );
00875 params.push_back( plc->GetCorner(ii).z );
00876 }
00877 }
00878 } else if (solidType == "POLYHEDRA") {
00879
00880
00881 const G4Polyhedra * ph = (dynamic_cast < const G4Polyhedra * > (so));
00882 if (ph) {
00883 G4double angphi = ph->GetStartPhi()/deg;
00884 if( angphi > 180*deg ) angphi -= 360*deg;
00885
00886 G4int ncor = ph->GetNumRZCorner();
00887
00888 params.push_back( angphi );
00889 params.push_back( ph->GetOriginalParameters()->Opening_angle/deg );
00890 params.push_back( ph->GetNumSide() );
00891 params.push_back( ncor );
00892
00893 for( G4int ii = 0; ii < ncor; ii++ )
00894 {
00895 params.push_back( ph->GetCorner(ii).r );
00896 params.push_back( ph->GetCorner(ii).z );
00897 }
00898 }
00899 } else if (solidType == "ELLIPTICALTUBE") {
00900 const G4EllipticalTube * eltu =
00901 dynamic_cast < const G4EllipticalTube * > (so);
00902 if (eltu) {
00903 params.push_back( eltu->GetDx());
00904 params.push_back( eltu->GetDy());
00905 params.push_back( eltu->GetDz());
00906 }
00907 } else if (solidType == "ELLIPSOID" ){
00908 const G4Ellipsoid* dso = dynamic_cast < const G4Ellipsoid * > (so);
00909 if (dso) {
00910 params.push_back( dso->GetSemiAxisMax(0) );
00911 params.push_back( dso->GetSemiAxisMax(1) );
00912 params.push_back( dso->GetSemiAxisMax(2) );
00913 params.push_back( dso->GetZBottomCut() );
00914 params.push_back( dso->GetZTopCut() );
00915 }
00916 } else if (solidType == "ELLIPTICAL_CONE") {
00917 const G4EllipticalCone * elco =
00918 dynamic_cast < const G4EllipticalCone * > (so);
00919 if (elco) {
00920 params.push_back( elco-> GetSemiAxisX() );
00921 params.push_back( elco-> GetSemiAxisY() );
00922 params.push_back( elco-> GetZMax() );
00923 params.push_back( elco-> GetZTopCut() );
00924 }
00925 } else if (solidType == "HYPE") {
00926 const G4Hype* hype = dynamic_cast < const G4Hype * > (so);
00927 if (hype) {
00928 params.push_back( hype->GetInnerRadius());
00929 params.push_back( hype->GetOuterRadius());
00930 params.push_back( hype->GetInnerStereo()/deg);
00931 params.push_back( hype->GetOuterStereo()/deg);
00932 params.push_back( 2*hype->GetZHalfLength());
00933 }
00934
00935
00936 } else if( solidType == "TWISTEDBOX" ) {
00937 const G4TwistedBox* tbox = dynamic_cast < const G4TwistedBox * > (so);
00938 if (tbox) {
00939 params.push_back( tbox->GetPhiTwist()/deg );
00940 params.push_back( tbox->GetXHalfLength() );
00941 params.push_back( tbox->GetYHalfLength() );
00942 params.push_back( tbox->GetZHalfLength() );
00943 }
00944 } else if( solidType == "TWISTEDTRAP" ) {
00945 const G4TwistedTrap * ttrap = dynamic_cast < const G4TwistedTrap * > (so);
00946 if (ttrap) {
00947 params.push_back( ttrap->GetPhiTwist()/deg );
00948 params.push_back( ttrap->GetZHalfLength() );
00949 params.push_back( ttrap->GetPolarAngleTheta()/deg );
00950 params.push_back( ttrap->GetAzimuthalAnglePhi()/deg );
00951 params.push_back( ttrap->GetY1HalfLength() );
00952 params.push_back( ttrap->GetX1HalfLength() );
00953 params.push_back( ttrap->GetX2HalfLength() );
00954 params.push_back( ttrap->GetY2HalfLength() );
00955 params.push_back( ttrap->GetX3HalfLength() );
00956 params.push_back( ttrap->GetX4HalfLength() );
00957 params.push_back( ttrap->GetTiltAngleAlpha()/deg );
00958 }
00959 } else if( solidType == "TWISTEDTRD" ) {
00960 const G4TwistedTrd * ttrd = dynamic_cast < const G4TwistedTrd * > (so);
00961 if (ttrd) {
00962 params.push_back( ttrd->GetX1HalfLength());
00963 params.push_back( ttrd->GetX2HalfLength() );
00964 params.push_back( ttrd->GetY1HalfLength() );
00965 params.push_back( ttrd->GetY2HalfLength() );
00966 params.push_back( ttrd->GetZHalfLength() );
00967 params.push_back( ttrd->GetPhiTwist()/deg );
00968 }
00969 } else if( solidType == "TWISTEDTUBS" ) {
00970 const G4TwistedTubs * ttub = dynamic_cast < const G4TwistedTubs * > (so);
00971 if (ttub) {
00972 params.push_back( ttub->GetInnerRadius() );
00973 params.push_back( ttub->GetOuterRadius() );
00974 params.push_back( ttub->GetZHalfLength() );
00975 params.push_back( ttub->GetDPhi()/deg );
00976 params.push_back( ttub->GetPhiTwist()/deg );
00977 }
00978 }
00979 else
00980 {
00981 G4String ErrMessage = "Solid type not supported, sorry... " + solidType;
00982 G4Exception("G4tgbGeometryDumpe::DumpSolidParams()",
00983 "NotImplemented", FatalException, ErrMessage);
00984 }
00985
00986 return params;
00987 }
00988
00989
00990
00991 G4String G4tgbGeometryDumper::DumpRotationMatrix( G4RotationMatrix* rotm )
00992 {
00993 if (!rotm) { rotm = new G4RotationMatrix(); }
00994
00995 G4double de = MatDeterminant(rotm);
00996 G4String rotName = LookForExistingRotation( rotm );
00997 if( rotName != "" ) { return rotName; }
00998
00999 G4ThreeVector v(1.,1.,1.);
01000 if (de < -0.9 )
01001 {
01002 (*theFile) << ":ROTM ";
01003 rotName = "RRM";
01004 rotName += G4UIcommand::ConvertToString(theRotationNumber++);
01005
01006 (*theFile) << AddQuotes(rotName) << std::setprecision(9) << " "
01007 << approxTo0(rotm->xx()) << " "
01008 << approxTo0(rotm->yx()) << " "
01009 << approxTo0(rotm->zx()) << " "
01010 << approxTo0(rotm->xy()) << " "
01011 << approxTo0(rotm->yy()) << " "
01012 << approxTo0(rotm->zy()) << " "
01013 << approxTo0(rotm->xz()) << " "
01014 << approxTo0(rotm->yz()) << " "
01015 << approxTo0(rotm->zz()) << G4endl;
01016 }
01017 else if(de > 0.9 )
01018 {
01019 (*theFile) << ":ROTM ";
01020 rotName = "RM";
01021 rotName += G4UIcommand::ConvertToString(theRotationNumber++);
01022
01023 (*theFile) << AddQuotes(rotName) << " "
01024 << approxTo0(rotm->thetaX()/deg) << " "
01025 << approxTo0(rotm->phiX()/deg) << " "
01026 << approxTo0(rotm->thetaY()/deg) << " "
01027 << approxTo0(rotm->phiY()/deg) << " "
01028 << approxTo0(rotm->thetaZ()/deg) << " "
01029 << approxTo0(rotm->phiZ()/deg) << G4endl;
01030 }
01031
01032 theRotMats[rotName] = rotm;
01033
01034 return rotName;
01035 }
01036
01037
01038
01039 std::vector<G4VPhysicalVolume*>
01040 G4tgbGeometryDumper::GetPVChildren( G4LogicalVolume* lv )
01041 {
01042 G4PhysicalVolumeStore* pvstore = G4PhysicalVolumeStore::GetInstance();
01043 G4PhysicalVolumeStore::const_iterator ite;
01044 std::vector<G4VPhysicalVolume*> children;
01045 for( ite = pvstore->begin(); ite != pvstore->end(); ite++ )
01046 {
01047 if( (*ite)->GetMotherLogical() == lv )
01048 {
01049 children.push_back( *ite );
01050 #ifdef G4VERBOSE
01051 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
01052 {
01053 G4cout << " G4tgbGeometryDumper::GetPVChildren() - adding children: "
01054 << (*ite)->GetName() << " of " << lv->GetName() << G4endl;
01055 }
01056 #endif
01057 }
01058 }
01059
01060 return children;
01061 }
01062
01063
01064
01065 G4String G4tgbGeometryDumper::GetTGSolidType( const G4String& solidType )
01066 {
01067 G4String newsolidType = solidType.substr(2,solidType.length() );
01068 for( size_t ii = 0; ii < newsolidType.length(); ii++ )
01069 {
01070 newsolidType[ii] = toupper(newsolidType[ii] );
01071 }
01072 return newsolidType;
01073 }
01074
01075
01076
01077 G4double G4tgbGeometryDumper::MatDeterminant(G4RotationMatrix * ro)
01078 {
01079 G4Rep3x3 r = ro->rep3x3();
01080 return r.xx_*(r.yy_*r.zz_ - r.zy_*r.yz_)
01081 - r.yx_*(r.xy_*r.zz_ - r.zy_*r.xz_)
01082 + r.zx_*(r.xy_*r.yz_ - r.yy_*r.xz_);
01083 }
01084
01085
01086
01087 G4double G4tgbGeometryDumper::approxTo0( G4double val )
01088 {
01089 G4double precision = G4GeometryTolerance::GetInstance()
01090 ->GetSurfaceTolerance();
01091
01092 if( std::fabs(val) < precision ) { val = 0; }
01093 return val;
01094 }
01095
01096
01097
01098 G4String G4tgbGeometryDumper::AddQuotes( const G4String& str )
01099 {
01100
01101
01102 G4bool bBlank = FALSE;
01103 size_t siz = str.length();
01104 for( size_t ii = 0; ii < siz; ii++ )
01105 {
01106 if( str.substr(ii,1) == " " )
01107 {
01108 bBlank = TRUE;
01109 break;
01110 }
01111 }
01112 G4String str2 = str;
01113 if( bBlank )
01114 {
01115 str2 = G4String("\"") + str2 + G4String("\"");
01116 }
01117 return str2;
01118 }
01119
01120
01121
01122 G4String G4tgbGeometryDumper::SupressRefl( G4String name )
01123 {
01124 G4int irefl = name.rfind("_refl");
01125 if( irefl != -1 )
01126 {
01127 name = name.substr( 0, irefl );
01128 }
01129 return name;
01130 }
01131
01132
01133 G4String G4tgbGeometryDumper::SubstituteRefl( G4String name )
01134 {
01135 G4int irefl = name.rfind("_refl");
01136 if( irefl != -1 )
01137 {
01138 name = name.substr( 0, irefl ) + "_REFL";
01139 }
01140 return name;
01141 }
01142
01143
01144
01145 G4String G4tgbGeometryDumper::GetIsotopeName( G4Isotope* isot )
01146 {
01147 G4String isotName = isot->GetName();
01148
01149
01150
01151 std::map<G4String,G4Isotope*>::const_iterator ite;
01152 for( ite = theIsotopes.begin(); ite != theIsotopes.end(); ite++ )
01153 {
01154 if( isot == (*ite).second ) { return (*ite).first; }
01155 }
01156
01157
01158
01159
01160 ite = theIsotopes.find( isotName );
01161 if( ite != theIsotopes.end() )
01162 {
01163 G4Isotope* isotold = (*ite).second;
01164 if( isot != isotold )
01165 {
01166 if( !Same2G4Isotopes(isot, isotold))
01167 {
01168 G4int ii = 2;
01169
01170 for(;;ii++)
01171 {
01172 G4String newIsotName = isotName + "_"
01173 + G4UIcommand::ConvertToString(ii);
01174 std::map<G4String,G4Isotope*>::const_iterator ite2 =
01175 theIsotopes.find( newIsotName );
01176 if( ite2 == theIsotopes.end() )
01177 {
01178 isotName = newIsotName;
01179 break;
01180 }
01181 else
01182 {
01183 if( Same2G4Isotopes( isot, (*ite2).second ) )
01184 {
01185 isotName = newIsotName;
01186 break;
01187 }
01188 }
01189 }
01190 }
01191 }
01192 }
01193 return isotName;
01194 }
01195
01196
01197
01198 template< class TYP > G4String G4tgbGeometryDumper::
01199 GetObjectName( TYP* obj, std::map<G4String,TYP*> objectsDumped )
01200 {
01201 G4String objName = obj->GetName();
01202
01203
01204
01205
01206 typename std::map<G4String,TYP*>::const_iterator ite;
01207 for( ite = objectsDumped.begin(); ite != objectsDumped.end(); ite++ )
01208 {
01209 if( obj == (*ite).second ) { return (*ite).first; }
01210 }
01211
01212
01213
01214
01215 ite = objectsDumped.find( objName );
01216
01217 if( ite != objectsDumped.end() )
01218 {
01219 TYP* objold = (*ite).second;
01220 if( obj != objold )
01221 {
01222 G4int ii = 2;
01223 for(;;ii++)
01224 {
01225 G4String newObjName = objName + "_" + G4UIcommand::ConvertToString(ii);
01226 typename std::map<G4String,TYP*>::const_iterator ite2 =
01227 objectsDumped.find( newObjName );
01228 if( ite2 == objectsDumped.end() )
01229 {
01230 objName = newObjName;
01231 break;
01232 }
01233 }
01234 }
01235 }
01236 return objName;
01237 }
01238
01239
01240
01241 G4bool G4tgbGeometryDumper::CheckIfLogVolExists( const G4String& name,
01242 G4LogicalVolume* pt )
01243 {
01244 if( theLogVols.find( name ) != theLogVols.end() )
01245 {
01246 G4LogicalVolume* lvnew = (*(theLogVols.find(name))).second;
01247 if( lvnew != pt )
01248 {
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260 }
01261 return 1;
01262 }
01263 else
01264 {
01265 return 0;
01266 }
01267 }
01268
01269
01270
01271 G4bool G4tgbGeometryDumper::CheckIfPhysVolExists( const G4String& name,
01272 G4VPhysicalVolume* pt )
01273 {
01274 #ifdef G4VERBOSE
01275 if( G4tgrMessenger::GetVerboseLevel() >= 1 )
01276 {
01277 G4cout << " G4tgbGeometryDumper::CheckIfPhysVolExists() - "
01278 << name << G4endl;
01279 }
01280 #endif
01281 if( thePhysVols.find( name ) != thePhysVols.end() )
01282 {
01283 if( (*(thePhysVols.find(name))).second != pt )
01284 {
01285
01286
01287
01288
01289 G4cerr << " G4tgbGeometryDumper::CheckIfPhysVolExists () -"
01290 << " Placement found but not same as before : " << name << G4endl;
01291 }
01292 return 1;
01293 }
01294 else
01295 {
01296 return 0;
01297 }
01298 }
01299
01300
01301
01302 G4String
01303 G4tgbGeometryDumper::LookForExistingRotation( const G4RotationMatrix* rotm )
01304 {
01305 G4String rmName = "";
01306
01307 std::map<G4String,G4RotationMatrix*>::const_iterator ite;
01308 for( ite = theRotMats.begin(); ite != theRotMats.end(); ite++ )
01309 {
01310 if( (*ite).second->isNear( *rotm ) )
01311 {
01312 rmName = (*ite).first;
01313 break;
01314 }
01315 }
01316 return rmName;
01317 }
01318
01319
01320
01321 G4bool
01322 G4tgbGeometryDumper::Same2G4Isotopes( G4Isotope* isot1, G4Isotope* isot2 )
01323 {
01324 if ( (isot1->GetZ() != isot2->GetZ())
01325 || (isot1->GetN() != isot2->GetN())
01326 || (isot1->GetA() != isot2->GetA()) )
01327 {
01328 return 0;
01329 }
01330 else
01331 {
01332 return 1;
01333 }
01334 }
01335
01336
01337
01338 const G4String& G4tgbGeometryDumper::FindSolidName( G4VSolid* solid )
01339 {
01340 std::map<G4String,G4VSolid*>::const_iterator ite;
01341 for( ite = theSolids.begin(); ite != theSolids.end(); ite++ )
01342 {
01343 if( solid == (*ite).second ) { return (*ite).first; }
01344 }
01345
01346 if( ite == theSolids.end() )
01347 {
01348 G4Exception("G4tgbGeometryDumper::FindSolidName()", "ReadError",
01349 FatalException, "Programming error.");
01350 }
01351 return (*ite).first;
01352 }