TShieldGeometry.cxx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // -------------------------------------------------------------------------
  2. // ----- TShieldGeometry source file -----
  3. // ----- Created by D. Sosnov -----
  4. // -------------------------------------------------------------------------
  5. #include "TShieldGeometry.h"
  6. bool operator<(const tgeanttoshield::zoneElement z1, const tgeanttoshield::zoneElement z2) {
  7. if (z1.first != z2.first) {
  8. return (z1.first > z2.first);
  9. }
  10. if (z1.second.type != z2.second.type) {
  11. return (z1.second.type < z2.second.type);
  12. }
  13. for (int k = 0; k < 36; ++k) {
  14. if (tgeanttoshield::doubleNE(z1.second.parameters[k], z2.second.parameters[k])) {
  15. return (z1.second.parameters[k] < z2.second.parameters[k]);
  16. }
  17. }
  18. return false;
  19. }
  20. Geant4ShieldData getDataAtPoint(TGeoManager *geoMan, Double_t x, Double_t y, Double_t z, Double_t vx, Double_t vy, Double_t vz) {
  21. using namespace tgeanttoshield;
  22. TGeoNavigator *nav = geoMan->GetCurrentNavigator();
  23. nav->DoBackupState();
  24. nav->CdTop();
  25. nav->SetCurrentDirection(vx, vy, vz);
  26. zoneData outputData;
  27. static double s = TGeoShape::Tolerance();
  28. zoneData zone;
  29. zone = getZonesAtPoint(nav, x + vx * s, y + vy * s, z + vz * s);
  30. outputData.insert(outputData.end(), zone.begin(), zone.end());
  31. zone = getZonesAtPoint(nav, x - vx * s, y - vy * s, z - vz * s);
  32. outputData.insert(outputData.end(), zone.begin(), zone.end());
  33. nav->DoRestoreState();
  34. return zoneDataToShield(outputData);
  35. }
  36. namespace tgeanttoshield {
  37. zoneData getZonesAtPoint(TGeoNavigator* nav, Double_t x, Double_t y, Double_t z) {
  38. TGeoNode *node = nav->FindNode(x, y, z);
  39. // Now, current position is deepest volume with point (x,y,z)
  40. nav->Safety(); //Set correct fBoundary and fOutside values
  41. zoneData outputData;
  42. if (!nav->IsOutside() && node) {
  43. outputData = getCurrentZone(nav);
  44. } else {
  45. //Is outer vacuum needed or return empty data?
  46. nav->CdTop();
  47. outputData.push_back(addOuterVacuum(nav->GetCurrentNode()));
  48. // outputData.push_back(addOuterVacuum(geoMan->GetTopNode()));
  49. }
  50. return outputData;
  51. }
  52. }
  53. namespace tgeanttoshield {
  54. zoneData getCurrentZone(TGeoNavigator* nav){
  55. zoneData outputData;
  56. int countOfDaughters = nav->GetCurrentNode()->GetNdaughters();
  57. TGeoVolume *volume = nav->GetCurrentVolume();
  58. TGeoHMatrix currTransformation = *(nav->GetCurrentMatrix()); //getGlobalMatrix(nav);
  59. zoneList internalVolume = (getZoneFromShape(volume->GetShape(), currTransformation)).first;
  60. TGeoNode *daughter;
  61. zoneList daughterOuterZones;
  62. for (int i = 0; i < countOfDaughters; ++i) {
  63. daughter = volume->GetNode(i);
  64. daughterOuterZones = getZoneFromBody(daughter, currTransformation).second;
  65. internalVolume = andZone(internalVolume, notZone(daughterOuterZones)); //Only outel shell of body.
  66. }
  67. outputData.push_back(std::make_pair(internalVolume, getMedium(nav->GetCurrentNode())));
  68. return outputData;
  69. }
  70. Geant4ShieldData zoneDataToShield(zoneData data) {
  71. Geant4ShieldData out;
  72. Geant4ShieldElement tmpElement;
  73. std::pair<zoneList, MediumData> currentPair;
  74. std::vector<SGeoBody> bodyVector;
  75. std::vector<int> zoneVector;
  76. std::set<std::vector<zoneElement> > geoData; //Converting to set for removing duplicates.
  77. std::set <zoneElement> curSet; //Set have only unique keys.
  78. for (unsigned int kk = 0; kk < data.size(); ++kk) {
  79. bodyVector.clear();
  80. zoneVector.clear();
  81. currentPair = data.at(kk); // This is data for one volume
  82. geoData = std::set<std::vector<zoneElement> >(currentPair.first.begin(), currentPair.first.end());
  83. for (std::set<std::vector<zoneElement> >::const_iterator k = geoData.begin(); k != geoData.end(); ++k) {
  84. curSet = std::set<zoneElement>((std::vector<zoneElement>::const_iterator)k->begin(), (std::vector<zoneElement>::const_iterator)k->end()); //As fact, removing duplicates of zoneElements
  85. for (std::set<zoneElement>::const_iterator i = curSet.begin(); i != curSet.end(); ++i) {
  86. zoneVector.push_back(i->first);
  87. bodyVector.push_back(i->second);
  88. }
  89. zoneVector.push_back(0);
  90. }
  91. zoneVector.pop_back(); // Removing of tail '0' element.
  92. tmpElement.medium = currentPair.second;
  93. tmpElement.zoneVector = zoneVector;
  94. tmpElement.bodyVector = bodyVector;
  95. out.push_back(tmpElement);
  96. }
  97. return out;
  98. }
  99. std::pair<zoneList, MediumData> addOuterVacuum(TGeoNode *world) {
  100. zoneList out = getZoneFromBody(world, TGeoHMatrix(), 1.5 * getDefaultScale()).second;
  101. zoneList outerWorld = getZoneFromBody(world, TGeoHMatrix()).second;
  102. MediumData medium = {0, 0, 0, {}};
  103. return std::make_pair(andZone(out, notZone(outerWorld)), medium);
  104. }
  105. }
  106. //Obsolete versions:
  107. Geant4ShieldData convertTGeantToShield(TGeoManager *geoMan) {
  108. printf("TShieldGeometry: using obsolete convertTGeantToShield function!\n");
  109. using namespace tgeanttoshield;
  110. TGeoNode *world = geoMan->GetTopNode();
  111. zoneData zoneWorld = convertBodyRecursive(world);
  112. // zoneWorld.push_back(addOuterVacuum(world));
  113. return zoneDataToShield(zoneWorld);
  114. }
  115. namespace tgeanttoshield {
  116. zoneData convertBodyRecursive(TGeoNode *node) {
  117. return convertBodyRecursive(node, TGeoHMatrix()).first;
  118. }
  119. std::pair<zoneData, zoneList> convertBodyRecursive(TGeoNode *node, TGeoHMatrix oldTransformation) {
  120. zoneData out;
  121. std::pair<zoneList, zoneList> tmp = getZoneFromBody(node, oldTransformation);
  122. TGeoHMatrix newTransformation = *(node->GetMatrix());
  123. TGeoHMatrix currMatrix = oldTransformation * newTransformation;
  124. zoneList internalVolume = tmp.first;
  125. zoneList outerVolume = tmp.second;
  126. TGeoVolume *volume = node->GetVolume();
  127. int countOfDaughters = volume->GetNdaughters();
  128. TGeoNode *daughter;
  129. std::pair<zoneData, zoneList > daughterZones;
  130. for (int i = 0; i < countOfDaughters; ++i) {
  131. daughter = volume->GetNode(i);
  132. daughterZones = convertBodyRecursive(daughter, currMatrix);
  133. out.insert(out.end(), daughterZones.first.begin(), daughterZones.first.end()); //Insert daughter zones to output zones
  134. internalVolume = andZone(internalVolume, notZone(daughterZones.second)); //Only outel shell of body.
  135. }
  136. // out.push_back(std::make_pair(internalVolume, getMedium(node)));
  137. out.insert(out.begin(), std::make_pair(internalVolume, getMedium(node))); //Add internalVolume to first place at output.
  138. return std::make_pair(out, outerVolume);
  139. }
  140. }