TShieldGeometryConvert.cxx 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. // -------------------------------------------------------------------------
  2. // ----- TShieldGeometry source file -----
  3. // ----- Created by D. Sosnov -----
  4. // -------------------------------------------------------------------------
  5. #include "TShieldGeometry.h"
  6. namespace tgeanttoshield {
  7. std::pair<zoneList, zoneList> getZoneFromBody(TGeoNode *node, TGeoHMatrix oldTransformation, double scale) {
  8. TGeoHMatrix newTransformation = *(node->GetMatrix());
  9. TGeoHMatrix currTransformation = oldTransformation * newTransformation;
  10. TGeoShape *shape = node->GetVolume()->GetShape();
  11. return getZoneFromShape(shape, currTransformation, scale);
  12. }
  13. std::pair<zoneList, zoneList> getZoneFromShape(TGeoShape *shape, TGeoHMatrix currTransformation, double scale) {
  14. std::pair<zoneList, zoneList> zonePair;
  15. if (dynamic_cast<TGeoTubeSeg *>(shape) != nullptr) {
  16. zonePair = tubeSegToZones((TGeoTubeSeg *)shape, currTransformation, scale);
  17. } else if (dynamic_cast<TGeoTube *>(shape) != nullptr) {
  18. zonePair = tubeToZones((TGeoTube *)shape, currTransformation, scale);
  19. } else if (dynamic_cast<TGeoCtub *>(shape) != nullptr) { //TODO
  20. printf("TGeoCtub not implemented yet\n");
  21. } else if (dynamic_cast<TGeoConeSeg *>(shape) != nullptr) {
  22. zonePair = coneSegToZones((TGeoConeSeg *)shape, currTransformation, scale);
  23. } else if (dynamic_cast<TGeoCone *>(shape) != nullptr) {
  24. zonePair = coneToZones((TGeoCone *)shape, currTransformation, scale);
  25. } else if (dynamic_cast<TGeoPara *>(shape) != nullptr) { //TODO
  26. printf("TGeoPara not implemented yet\n");
  27. } else if (dynamic_cast<TGeoTrd1 *>(shape) != nullptr) {
  28. zonePair = trd1ToZones((TGeoTrd1 *)shape, currTransformation, scale);
  29. } else if (dynamic_cast<TGeoTrd2 *>(shape) != nullptr) {
  30. zonePair = trd2ToZones((TGeoTrd2 *)shape, currTransformation, scale);
  31. } else if (dynamic_cast<TGeoTrap *>(shape) != nullptr) {
  32. zonePair = trapToZones((TGeoTrap *)shape, currTransformation, scale);
  33. } else if (dynamic_cast<TGeoSphere *>(shape) != nullptr) {
  34. zonePair = sphereToZones((TGeoSphere *)shape, currTransformation, scale);
  35. } else if (dynamic_cast<TGeoPgon *>(shape) != nullptr) {
  36. zonePair = polyhedraToZones((TGeoPgon *)shape, currTransformation, scale);
  37. } else if (dynamic_cast<TGeoPcon *>(shape) != nullptr) {
  38. zonePair = polyconeToZones((TGeoPcon *)shape, currTransformation, scale);
  39. } else if (dynamic_cast<TGeoEltu *>(shape) != nullptr) {
  40. zonePair = ellipticalTubeToZones((TGeoEltu *)shape, currTransformation, scale);
  41. } else if (dynamic_cast<TGeoArb8 *>(shape) != nullptr) {
  42. zonePair = arb8ToZones((TGeoArb8 *)shape, currTransformation, scale);
  43. } else if (dynamic_cast<TGeoGtra *>(shape) != nullptr) { //TODO
  44. printf("TGeoGtra not implemented yet\n");
  45. } else if (dynamic_cast<TGeoHype *>(shape) != nullptr) { //TODO
  46. printf("TGeoHype not implemented yet\n");
  47. } else if (dynamic_cast<TGeoTorus *>(shape) != nullptr) { //TODO
  48. printf("TGeoTorus not implemented yet\n");
  49. } else if (dynamic_cast<TGeoParaboloid *>(shape) != nullptr) { //TODO
  50. printf("TGeoParaboloid not implemented yet\n");
  51. } else if (dynamic_cast<TGeoXtru *>(shape) != nullptr) { //TODO
  52. printf("TGeoXtru not implemented yet\n");
  53. } else if (dynamic_cast<TGeoHalfSpace *>(shape) != nullptr) { //TODO
  54. printf("TGeoHalfSpace not implemented yet\n");
  55. } else if (dynamic_cast<TGeoCompositeShape *>(shape) != nullptr) { //TODO
  56. printf("TGeoCompositeShape not implemented yet\n");
  57. } else if (dynamic_cast<TGeoBBox *>(shape) != nullptr) { //All of this shapes in subclasses of TGeoBBox
  58. zonePair = boxToZones((TGeoBBox *)shape, currTransformation, scale);
  59. } else {
  60. printf("ELSE");
  61. }
  62. return zonePair;
  63. }
  64. SGeoBody createCone(TGeoTranslation startPoint, TGeoTranslation vectorToEnd, double rStart, double rEnd) {
  65. SGeoBody outBody;
  66. if (doubleEQ(rStart, rEnd)) {
  67. outBody.type = 5;
  68. outBody.parameters[0] = 0; outBody.parameters[1] = 0; outBody.parameters[2] = 0; outBody.parameters[3] = 0;
  69. outBody.parameters[4] = 0; outBody.parameters[5] = 0; outBody.parameters[6] = rStart;
  70. addVectorToElement(outBody, 0, startPoint);
  71. addVectorToElement(outBody, 3, vectorToEnd);
  72. } else {
  73. if(rStart <= rEnd)
  74. startPoint = startPoint + vectorToEnd;
  75. if(rStart <= rEnd)
  76. vectorToEnd = vectorToEnd.Inverse();
  77. double rMax = (rStart > rEnd) ? rStart : rEnd;
  78. double rMin = (rStart > rEnd) ? rEnd : rStart;
  79. outBody.type = 7;
  80. outBody.parameters[0] = 0; outBody.parameters[1] = 0; outBody.parameters[2] = 0; outBody.parameters[3] = 0;
  81. outBody.parameters[4] = 0; outBody.parameters[5] = 0; outBody.parameters[6] = rMax; outBody.parameters[7] = rMin;
  82. addVectorToElement(outBody, 0, startPoint);
  83. addVectorToElement(outBody, 3, vectorToEnd);
  84. }
  85. return outBody;
  86. }
  87. zoneList cutByPhi(TGeoHMatrix currTransformation,
  88. double sPhi, double dPhi, double halfX, double halfY, double halfZ) {
  89. TGeoHMatrix currRotation = TGeoHMatrix(currTransformation); currRotation.SetTranslation(kNullVector);
  90. TGeoTranslation currTranslation = TGeoTranslation(currTransformation);
  91. double ePhi = sPhi + dPhi;
  92. if (doubleGE(dPhi, 360)) return zoneList();
  93. TGeoHMatrix tmp = TGeoHMatrix(); tmp.RotateZ(sPhi);
  94. TGeoHMatrix innerRot = currRotation * tmp;
  95. TGeoTranslation startFirstBox = currTranslation + TGeoTranslation(innerRot * TGeoTranslation(-halfX, 0, -halfZ));
  96. TGeoTranslation vec11 = TGeoTranslation(innerRot * TGeoTranslation(2 * halfX, 0, 0));
  97. TGeoTranslation vec12 = TGeoTranslation(innerRot * TGeoTranslation(0, -halfY, 0));
  98. TGeoTranslation vec13 = TGeoTranslation(innerRot * TGeoTranslation(0, 0, 2 * halfZ));
  99. SGeoBody box1 = {3, {}};
  100. addVectorToElement(box1, 0, startFirstBox);
  101. addVectorToElement(box1, 3, vec11);
  102. addVectorToElement(box1, 6, vec12);
  103. addVectorToElement(box1, 9, vec13);
  104. tmp = TGeoHMatrix(); tmp.RotateZ(ePhi);
  105. TGeoHMatrix outerRot = currRotation * tmp;
  106. TGeoTranslation startSecondBox = currTranslation + TGeoTranslation(outerRot * TGeoTranslation(halfX, 0, -halfZ));
  107. TGeoTranslation vec21 = TGeoTranslation(outerRot * TGeoTranslation(-2 * halfX, 0, 0));
  108. TGeoTranslation vec22 = TGeoTranslation(outerRot * TGeoTranslation(0, halfY, 0));
  109. TGeoTranslation vec23 = TGeoTranslation(outerRot * TGeoTranslation(0, 0, 2 * halfZ));
  110. SGeoBody box2 = {3, {}};
  111. addVectorToElement(box2, 0, startSecondBox);
  112. addVectorToElement(box2, 3, vec21);
  113. addVectorToElement(box2, 6, vec22);
  114. addVectorToElement(box2, 9, vec23);
  115. zoneList outList;
  116. if (doubleLE(dPhi, 180)) {
  117. std::vector<zoneElement> vec_el;
  118. vec_el.push_back(std::make_pair(-1, box1)); vec_el.push_back(std::make_pair(-1, box2));
  119. outList.push_back(vec_el);
  120. } else {
  121. outList.push_back(std::vector<zoneElement>(1, std::make_pair(-1, box1)));
  122. outList.push_back(std::vector<zoneElement>(1, std::make_pair(-1, box2)));
  123. }
  124. return outList;
  125. }
  126. inline std::pair<zoneList, zoneList> boxToZones(TGeoBBox *box, TGeoHMatrix currTransformation, double scale) {
  127. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  128. TGeoHMatrix currRotation = TGeoHMatrix(currTransformation); currRotation.SetTranslation(kNullVector);
  129. double x = (double) box->GetDX() * scale;
  130. double y = (double) box->GetDY() * scale;
  131. double z = (double) box->GetDZ() * scale;
  132. TGeoTranslation startVector = TGeoTranslation(currTransformation * TGeoTranslation(-x, -y, -z));
  133. TGeoTranslation vec1 = TGeoTranslation(currRotation * TGeoTranslation(2 * x, 0, 0));
  134. TGeoTranslation vec2 = TGeoTranslation(currRotation * TGeoTranslation(0, 2 * y, 0));
  135. TGeoTranslation vec3 = TGeoTranslation(currRotation * TGeoTranslation(0, 0, 2 * z));
  136. SGeoBody tmp = {3, {}};
  137. addVectorToElement(tmp, 0, startVector);
  138. addVectorToElement(tmp, 3, vec1);
  139. addVectorToElement(tmp, 6, vec2);
  140. addVectorToElement(tmp, 9, vec3);
  141. out.push_back(std::vector<zoneElement>(1, std::make_pair(1, tmp)));
  142. outerShell = out;
  143. return std::make_pair(out, outerShell);
  144. }
  145. inline std::pair<zoneList, zoneList> tubeSegToZones(TGeoTubeSeg *tube, TGeoHMatrix currTransformation, double scale) {
  146. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  147. std::pair<zoneList, zoneList> tubeOut = tubeToZones(tube, currTransformation, scale);
  148. double sPhi = (double) tube->GetPhi1(); // As I understand, in gedrees
  149. double dPhi = (double) tube->GetPhi2() - sPhi;
  150. double rOut = (double) tube->GetRmax() * scale;
  151. double z = (double) tube->GetDz() * scale;
  152. zoneList phiZone = cutByPhi(currTransformation, sPhi, dPhi, rOut, rOut, z);
  153. out = andZone(tubeOut.first, phiZone);
  154. outerShell = andZone(tubeOut.second, phiZone);
  155. return std::make_pair(out, outerShell);
  156. }
  157. inline std::pair<zoneList, zoneList> tubeToZones(TGeoTube *tube, TGeoHMatrix currTransformation, double scale) {
  158. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  159. TGeoHMatrix currRotation = TGeoHMatrix(currTransformation); currRotation.SetTranslation(kNullVector);
  160. double rIn = (double) tube->GetRmin() * scale;
  161. double rOut = (double) tube->GetRmax() * scale;
  162. double z = (double) tube->GetDz() * scale;
  163. TGeoTranslation startTube = TGeoTranslation(currTransformation * TGeoTranslation(0, 0, -z));
  164. TGeoTranslation endTubeVec = TGeoTranslation(currRotation * TGeoTranslation(0, 0, 2 * z));
  165. SGeoBody innerTube = {5, {}};
  166. addVectorToElement(innerTube, 0, startTube);
  167. addVectorToElement(innerTube, 3, endTubeVec);
  168. innerTube.parameters[6] = rIn;
  169. SGeoBody outerTube = {5, {}};
  170. addVectorToElement(outerTube, 0, startTube);
  171. addVectorToElement(outerTube, 3, endTubeVec);
  172. outerTube.parameters[6] = rOut;
  173. out.push_back(std::vector<zoneElement>(1, std::make_pair(1, outerTube)));
  174. outerShell = out;
  175. if (doubleNE(rIn, 0)) {
  176. out = andZone(out, zoneList(1, std::vector<zoneElement>(1, std::make_pair(-1, innerTube))));
  177. }
  178. return std::make_pair(out, outerShell);
  179. }
  180. inline std::pair<zoneList, zoneList> coneSegToZones(TGeoConeSeg *cone, TGeoHMatrix currTransformation, double scale) {
  181. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  182. double rMax1 = (double)cone->GetRmax1() * scale;
  183. double rMax2 = (double)cone->GetRmax2() * scale;
  184. double z = (double)cone->GetDz() * scale;
  185. double sPhi = (double) cone->GetPhi1(); // As I understand, in gedrees
  186. double dPhi = (double) cone->GetPhi2() - sPhi;
  187. std::pair<zoneList, zoneList> coneOut = coneToZones(cone, currTransformation, scale);
  188. double rOut = (rMax1 > rMax2) ? rMax1 : rMax2;
  189. zoneList phiZone = cutByPhi(currTransformation, sPhi, dPhi, rOut, rOut, z);
  190. out = andZone(coneOut.first, phiZone);
  191. outerShell = andZone(coneOut.second, phiZone);
  192. return std::make_pair(out, outerShell);
  193. }
  194. inline std::pair<zoneList, zoneList> coneToZones(TGeoCone *cone, TGeoHMatrix currTransformation, double scale) {
  195. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  196. TGeoHMatrix currRotation = TGeoHMatrix(currTransformation); currRotation.SetTranslation(kNullVector);
  197. double rMin1 = (double)cone->GetRmin1() * scale;
  198. double rMin2 = (double)cone->GetRmin2() * scale;
  199. double rMax1 = (double)cone->GetRmax1() * scale;
  200. double rMax2 = (double)cone->GetRmax2() * scale;
  201. double z = (double)cone->GetDz() * scale;
  202. TGeoTranslation startTubeVector = TGeoTranslation(currTransformation * TGeoTranslation(0, 0, -z));
  203. TGeoTranslation endTubeVec = TGeoTranslation(currRotation * TGeoTranslation(0, 0, 2 * z));
  204. SGeoBody outerCone = createCone(startTubeVector, endTubeVec, rMax1, rMax2);
  205. SGeoBody innerCone = createCone(startTubeVector, endTubeVec, rMin1, rMin2);
  206. out.push_back(std::vector<zoneElement>(1, std::make_pair(1, outerCone)));
  207. outerShell = out;
  208. if (doubleNE(rMin1, 0) || doubleNE(rMin2, 0)) {
  209. out = andZone(out, zoneList(1, std::vector<zoneElement>(1, std::make_pair(-1, innerCone))));
  210. }
  211. return std::make_pair(out, outerShell);
  212. }
  213. inline std::pair<zoneList, zoneList> trd1ToZones(TGeoTrd1 *trd, TGeoHMatrix currTransformation, double scale) {
  214. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  215. double dz = (double) trd->GetDz() * scale;
  216. double dx1 = (double) trd->GetDx1() * scale;
  217. double dy1 = (double) trd->GetDy() * scale;
  218. double dx2 = (double) trd->GetDx2() * scale;
  219. double dy2 = (double) trd->GetDy() * scale;
  220. TGeoTranslation v1 = TGeoTranslation(currTransformation * TGeoTranslation(-dx1, -dy1, -dz));
  221. TGeoTranslation v2 = TGeoTranslation(currTransformation * TGeoTranslation(-dx1, dy1, -dz));
  222. TGeoTranslation v3 = TGeoTranslation(currTransformation * TGeoTranslation(dx1, dy1, -dz));
  223. TGeoTranslation v4 = TGeoTranslation(currTransformation * TGeoTranslation(dx1, -dy1, -dz));
  224. TGeoTranslation v5 = TGeoTranslation(currTransformation * TGeoTranslation(-dx2, -dy2, dz));
  225. TGeoTranslation v6 = TGeoTranslation(currTransformation * TGeoTranslation(-dx2, dy2, dz));
  226. TGeoTranslation v7 = TGeoTranslation(currTransformation * TGeoTranslation(dx2, dy2, dz));
  227. TGeoTranslation v8 = TGeoTranslation(currTransformation * TGeoTranslation(dx2, -dy2, dz));
  228. SGeoBody tmp = {2, {}};
  229. addVectorToElement(tmp, 0, v1);
  230. addVectorToElement(tmp, 3, v2);
  231. addVectorToElement(tmp, 6, v3);
  232. addVectorToElement(tmp, 9, v4);
  233. addVectorToElement(tmp, 12, v5);
  234. addVectorToElement(tmp, 15, v6);
  235. addVectorToElement(tmp, 18, v7);
  236. addVectorToElement(tmp, 21, v8);
  237. out.push_back(std::vector<zoneElement>(1, std::make_pair(1, tmp)));
  238. outerShell = out;
  239. return std::make_pair(out, outerShell);
  240. }
  241. inline std::pair<zoneList, zoneList> trd2ToZones(TGeoTrd2 *trd, TGeoHMatrix currTransformation, double scale) {
  242. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  243. double dz = (double) trd->GetDz() * scale;
  244. double dx1 = (double) trd->GetDx1() * scale;
  245. double dy1 = (double) trd->GetDy1() * scale;
  246. double dx2 = (double) trd->GetDx2() * scale;
  247. double dy2 = (double) trd->GetDy2() * scale;
  248. TGeoTranslation v1 = TGeoTranslation(currTransformation * TGeoTranslation(-dx1, -dy1, -dz));
  249. TGeoTranslation v2 = TGeoTranslation(currTransformation * TGeoTranslation(-dx1, dy1, -dz));
  250. TGeoTranslation v3 = TGeoTranslation(currTransformation * TGeoTranslation(dx1, dy1, -dz));
  251. TGeoTranslation v4 = TGeoTranslation(currTransformation * TGeoTranslation(dx1, -dy1, -dz));
  252. TGeoTranslation v5 = TGeoTranslation(currTransformation * TGeoTranslation(-dx2, -dy2, dz));
  253. TGeoTranslation v6 = TGeoTranslation(currTransformation * TGeoTranslation(-dx2, dy2, dz));
  254. TGeoTranslation v7 = TGeoTranslation(currTransformation * TGeoTranslation(dx2, dy2, dz));
  255. TGeoTranslation v8 = TGeoTranslation(currTransformation * TGeoTranslation(dx2, -dy2, dz));
  256. SGeoBody tmp = {2, {}};
  257. addVectorToElement(tmp, 0, v1);
  258. addVectorToElement(tmp, 3, v2);
  259. addVectorToElement(tmp, 6, v3);
  260. addVectorToElement(tmp, 9, v4);
  261. addVectorToElement(tmp, 12, v5);
  262. addVectorToElement(tmp, 15, v6);
  263. addVectorToElement(tmp, 18, v7);
  264. addVectorToElement(tmp, 21, v8);
  265. out.push_back(std::vector<zoneElement>(1, std::make_pair(1, tmp)));
  266. outerShell = out;
  267. return std::make_pair(out, outerShell);
  268. }
  269. inline std::pair<zoneList, zoneList> trapToZones(TGeoTrap *trap, TGeoHMatrix currTransformation, double scale) {
  270. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  271. double dz = (double) trap->GetDz() * scale;
  272. double dy1 = (double) trap->GetH1() * scale;
  273. double dy2 = (double) trap->GetH2() * scale;
  274. double bl1 = (double) trap->GetBl1() * scale;
  275. double tl1 = (double) trap->GetTl1() * scale;
  276. double bl2 = (double) trap->GetBl2() * scale;
  277. double tl2 = (double) trap->GetTl2() * scale;
  278. double theta = (double) trap->GetTheta() / (180 / M_PI);
  279. double phi = (double) trap->GetPhi() / (180 / M_PI);
  280. double alpha1 = (double) trap->GetAlpha1() / (180 / M_PI);
  281. double alpha2 = (double) trap->GetAlpha2() / (180 / M_PI);
  282. //double rCenter = dz / cos(theta);
  283. double xC = dz * tan(theta) * cos(phi); //rCenter * sin(theta) * cos(phi);
  284. double yC = dz * tan(theta) * sin(phi); //rCenter * sin(theta) * sin(phi);
  285. double x1 = dy1 * tan(alpha1);
  286. double x2 = dy2 * tan(alpha2);
  287. TGeoTranslation v1 = TGeoTranslation(currTransformation * TGeoTranslation(-xC + x1 - tl1, -yC + dy1, -dz));
  288. TGeoTranslation v2 = TGeoTranslation(currTransformation * TGeoTranslation(-xC + x1 + tl1, -yC + dy1, -dz));
  289. TGeoTranslation v3 = TGeoTranslation(currTransformation * TGeoTranslation(-xC - x1 + bl1, -yC - dy1, -dz));
  290. TGeoTranslation v4 = TGeoTranslation(currTransformation * TGeoTranslation(-xC - x1 - bl1, -yC - dy1, -dz));
  291. TGeoTranslation v5 = TGeoTranslation(currTransformation * TGeoTranslation(xC + x2 - tl2, yC + dy2, dz));
  292. TGeoTranslation v6 = TGeoTranslation(currTransformation * TGeoTranslation(xC + x2 + tl2, yC + dy2, dz));
  293. TGeoTranslation v7 = TGeoTranslation(currTransformation * TGeoTranslation(xC - x2 + bl2, yC - dy2, dz));
  294. TGeoTranslation v8 = TGeoTranslation(currTransformation * TGeoTranslation(xC - x2 - bl2, yC - dy2, dz));
  295. SGeoBody tmp = {2, {}};
  296. addVectorToElement(tmp, 0, v1);
  297. addVectorToElement(tmp, 3, v2);
  298. addVectorToElement(tmp, 6, v3);
  299. addVectorToElement(tmp, 9, v4);
  300. addVectorToElement(tmp, 12, v5);
  301. addVectorToElement(tmp, 15, v6);
  302. addVectorToElement(tmp, 18, v7);
  303. addVectorToElement(tmp, 21, v8);
  304. out.push_back(std::vector<zoneElement>(1, std::make_pair(1, tmp)));
  305. outerShell = out;
  306. return std::make_pair(out, outerShell);
  307. }
  308. inline std::pair<zoneList, zoneList> sphereToZones(TGeoSphere *sphere, TGeoHMatrix currTransformation, double scale) {
  309. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  310. TGeoHMatrix currRotation = TGeoHMatrix(currTransformation); currRotation.SetTranslation(kNullVector);
  311. double rIn = (double) sphere->GetRmin() * scale;
  312. double rOut = (double) sphere->GetRmax() * scale;
  313. double sPhi = (double) sphere->GetPhi1();
  314. double dPhi = (double) sphere->GetPhi2() - sPhi;
  315. double sTheta = (double) sphere->GetTheta1() / (180 / M_PI); //convert to radians becouse cmath functions work with them
  316. double dTheta = (double) sphere->GetTheta2() / (180 / M_PI) - sTheta;
  317. double eTheta = sTheta + dTheta;
  318. SGeoBody innerSphere = {0, {}};
  319. innerSphere.parameters[3] = rIn;
  320. SGeoBody outerSphere = {0, {}};
  321. outerSphere.parameters[3] = rOut;
  322. {
  323. TGeoTranslation currTranslation = TGeoTranslation(currTransformation);
  324. addVectorToElement(innerSphere, 0, currTranslation);
  325. addVectorToElement(outerSphere, 0, currTranslation);
  326. }
  327. out.push_back(std::vector<zoneElement>(1, std::make_pair(1, outerSphere)));
  328. outerShell = out;
  329. if (doubleNE(rIn, 0)) {
  330. out = andZone(out, zoneList(1, std::vector<zoneElement>(1, std::make_pair(-1, innerSphere))));
  331. }
  332. zoneList phiZone = cutByPhi(currTransformation, sPhi, dPhi, rOut, rOut, rOut);
  333. out = andZone(out, phiZone);
  334. outerShell = andZone(outerShell, phiZone);
  335. if (doubleNE(sTheta, 0) && doubleNE(sTheta, M_PI) && doubleNE(sTheta, M_PI / 2.0)) {
  336. TGeoTranslation trc1Start = TGeoTranslation(currTransformation * TGeoTranslation(0, 0, -rOut * cos(sTheta)));
  337. TGeoTranslation trc1Vec = TGeoTranslation(currRotation * TGeoTranslation(0, 0, (rOut - rIn) * cos(sTheta)));
  338. SGeoBody trc1 = {7, {}};
  339. addVectorToElement(trc1, 0, trc1Start);
  340. addVectorToElement(trc1, 3, trc1Start);
  341. trc1.parameters[6] = (double)(rOut * tan(sTheta));
  342. trc1.parameters[7] = (double)(rIn * sin(sTheta));
  343. int mul = (sTheta < (M_PI / 2.0)) ? -1 : 1;
  344. out = andZone(out, zoneList(1, std::vector<zoneElement>(1, std::make_pair(mul, trc1))));
  345. outerShell = andZone(outerShell, zoneList(1, std::vector<zoneElement>(1, std::make_pair(mul, trc1))));
  346. } else if (sTheta == (M_PI / 2.0)) {
  347. TGeoTranslation db1s = TGeoTranslation(currTransformation * TGeoTranslation(-rOut, -rOut, 0));
  348. TGeoTranslation db1v1 = TGeoTranslation(currRotation * TGeoTranslation(2 * rOut, 0, 0));
  349. TGeoTranslation db1v2 = TGeoTranslation(currRotation * TGeoTranslation(0, 2 * rOut, 0));
  350. TGeoTranslation db1v3 = TGeoTranslation(currRotation * TGeoTranslation(0, 0, -rOut));
  351. SGeoBody db1 = {3, {}};
  352. addVectorToElement(db1, 0, db1s);
  353. addVectorToElement(db1, 3, db1v1);
  354. addVectorToElement(db1, 6, db1v2);
  355. addVectorToElement(db1, 9, db1v3);
  356. out = andZone(out, zoneList(1, std::vector<zoneElement>(1, std::make_pair(-1, db1))));
  357. outerShell = andZone(outerShell, zoneList(1, std::vector<zoneElement>(1, std::make_pair(-1, db1))));
  358. }
  359. if (doubleNE(eTheta, 0) && doubleNE(eTheta, M_PI) && doubleNE(eTheta, M_PI / 2.0)) {
  360. TGeoTranslation trc2Start = TGeoTranslation(currTransformation * TGeoTranslation(0, 0, -rOut * cos(eTheta)));
  361. TGeoTranslation trc2Vec = TGeoTranslation(currRotation * TGeoTranslation(0, 0, (rOut - rIn) * cos(eTheta)));
  362. SGeoBody trc2 = {7, {}};
  363. addVectorToElement(trc2, 0, trc2Start);
  364. addVectorToElement(trc2, 3, trc2Start);
  365. trc2.parameters[6] = (double)(rOut * tan(eTheta));
  366. trc2.parameters[7] = (double)(rIn * sin(eTheta));
  367. int mul = (eTheta > (M_PI / 2.0)) ? -1 : 1;
  368. out = andZone(out, zoneList(1, std::vector<zoneElement>(1, std::make_pair(mul, trc2))));
  369. outerShell = andZone(outerShell, zoneList(1, std::vector<zoneElement>(1, std::make_pair(mul, trc2))));
  370. } else if (eTheta == (M_PI / 2.0)) {
  371. TGeoTranslation db2s = TGeoTranslation(currTransformation * TGeoTranslation(-rOut, -rOut, 0));
  372. TGeoTranslation db2v1 = TGeoTranslation(currRotation * TGeoTranslation(2 * rOut, 0, 0));
  373. TGeoTranslation db2v2 = TGeoTranslation(currRotation * TGeoTranslation(0, 2 * rOut, 0));
  374. TGeoTranslation db2v3 = TGeoTranslation(currRotation * TGeoTranslation(0, 0, rOut));
  375. SGeoBody db2 = {3, {}};
  376. addVectorToElement(db2, 0, db2s);
  377. addVectorToElement(db2, 3, db2v1);
  378. addVectorToElement(db2, 6, db2v2);
  379. addVectorToElement(db2, 9, db2v3);
  380. out = andZone(out, zoneList(1, std::vector<zoneElement>(1, std::make_pair(-1, db2))));
  381. outerShell = andZone(outerShell, zoneList(1, std::vector<zoneElement>(1, std::make_pair(-1, db2))));
  382. }
  383. return std::make_pair(out, outerShell);
  384. }
  385. inline std::pair<zoneList, zoneList> polyconeToZones(TGeoPcon *polycone, TGeoHMatrix currTransformation, double scale) {
  386. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  387. TGeoHMatrix currRotation = TGeoHMatrix(currTransformation); currRotation.SetTranslation(kNullVector);
  388. double sPhi = (double)polycone->GetPhi1(); //In Pcon angle converted to degrees, and TMatrixes work with degrees. (?)
  389. double dPhi = (double)polycone->GetDphi();
  390. int nz = polycone->GetNz();
  391. double zCurrent, zPrev, rMaxCurrent, rMaxPrev, rMinCurrent, rMinPrev;
  392. double *zValues = polycone->GetZ();
  393. double *rMinValues = polycone->GetRmin();
  394. double *rMaxValues = polycone->GetRmax();
  395. double zMin = zValues[0] * scale, zMax = zValues[nz - 1] * scale, rMaxMax = rMaxValues[0] * scale;
  396. TGeoTranslation startPoint, endVec;
  397. zoneElement currentOuterCone, currentInnerCone;
  398. double zCenter = (zMax + zMin) / 2.0;
  399. for (int i = 1; i < nz; ++i) {
  400. zPrev = zCenter + (zValues[i - 1] - zCenter) * scale;
  401. zCurrent = zCenter + (zValues[i] - zCenter) * scale;
  402. if (zPrev == zCurrent)continue;
  403. rMaxPrev = rMaxValues[i - 1] * scale;
  404. rMaxCurrent = rMaxValues[i] * scale;
  405. rMinPrev = rMinValues[i - 1] * scale;
  406. rMinCurrent = rMinValues[i] * scale;
  407. startPoint = TGeoTranslation(currTransformation * TGeoTranslation(0, 0, zPrev));
  408. endVec = TGeoTranslation(currRotation * TGeoTranslation(0, 0, zCurrent - zPrev));
  409. rMaxMax = (rMaxCurrent > rMaxMax) ? rMaxCurrent : rMaxMax;
  410. if (doubleNE(rMaxPrev, 0) || doubleNE(rMaxCurrent, 0)) {
  411. currentOuterCone = std::make_pair(1, createCone(startPoint, endVec, rMaxPrev, rMaxCurrent));
  412. outerShell = orZone(outerShell, zoneList(1, std::vector<zoneElement>(1, currentOuterCone)));
  413. }
  414. if (doubleNE(rMinPrev, 0) || doubleNE(rMinCurrent, 0)) {
  415. currentInnerCone = std::make_pair(1, createCone(startPoint, endVec, rMinPrev, rMinCurrent));
  416. out = orZone(out, zoneList(1, std::vector<zoneElement>(1, currentInnerCone)));
  417. }
  418. }
  419. out = andZone(outerShell, notZone(out));
  420. TGeoHMatrix phiTransformation = currTransformation * TGeoTranslation(0, 0, zMin + (zMax - zMin) / 2.0);
  421. zoneList phiZone = cutByPhi(phiTransformation, sPhi, dPhi, rMaxMax, rMaxMax, (zMax - zMin) / 2.0);
  422. // startPoint = TGeoTranslation(currRotation * TGeoTranslation(0, 0, zMin + (zMax - zMin) / 2.0));
  423. // zoneList phiZone = cutByPhi(startPoint, currRotation, sPhi, dPhi, rMaxMax, rMaxMax, (zMax - zMin) / 2.0);
  424. out = andZone(out, phiZone);
  425. outerShell = andZone(outerShell, phiZone);
  426. return std::make_pair(out, outerShell);
  427. }
  428. inline std::pair<zoneList, zoneList> polyhedraToZones(TGeoPgon *polyhedra, TGeoHMatrix currTransformation, double scale) {
  429. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  430. TGeoHMatrix currRotation = TGeoRotation(currTransformation);
  431. double sPhi = (double)polyhedra->GetPhi1(); //In Pcon angle converted to degrees, and TMatrixes work with degrees.
  432. double dPhi = (double)polyhedra->GetDphi();
  433. int numSides = polyhedra->GetNedges();
  434. int nz = polyhedra->GetNz();
  435. double da = dPhi / numSides;
  436. double zCurrent, zPrev, rMaxCurrent, rMaxPrev, rMinCurrent, rMinPrev;
  437. double *zValues = polyhedra->GetZ();
  438. double *rMinValues = polyhedra->GetRmin();
  439. double *rMaxValues = polyhedra->GetRmax();
  440. double zMin = zValues[0] * scale, zMax = zValues[nz - 1] * scale;
  441. TGeoTranslation startZPoint, endZPoint, vert0, vert1, vert2, vert3, vecR, vecL;
  442. TGeoHMatrix phiRotation;
  443. SGeoBody arb;
  444. double zCenter = (zMax + zMin) / 2.0;
  445. for (int i = 1; i < nz; ++i) {
  446. zPrev = zCenter + (zValues[i - 1] - zCenter) * scale;
  447. zCurrent = zCenter + (zValues[i] - zCenter) * scale;
  448. if (doubleEQ(zPrev, zCurrent)) continue;
  449. rMaxPrev = rMaxValues[i - 1] * scale / cos(da / 2 * M_PI / 180); //Convert angle to radians
  450. rMaxCurrent = rMaxValues[i] * scale / cos(da / 2 * M_PI / 180);
  451. rMinPrev = rMinValues[i - 1] * scale / cos(da / 2 * M_PI / 180);
  452. rMinCurrent = rMinValues[i] * scale / cos(da / 2 * M_PI / 180);
  453. startZPoint = TGeoTranslation(currTransformation * TGeoTranslation(0, 0, zPrev));
  454. endZPoint = TGeoTranslation(currTransformation * TGeoTranslation(0, 0, zCurrent));
  455. for (int k = 0; k < numSides; ++k) {
  456. phiRotation = TGeoHMatrix(); phiRotation.RotateZ(sPhi + da * k); phiRotation = currRotation * phiRotation;
  457. vecR = TGeoTranslation(phiRotation * TGeoTranslation(1, 0, 0)); // Vector to right vertex of secctor
  458. phiRotation = TGeoHMatrix(); phiRotation.RotateZ(sPhi + da * (k + 1)); phiRotation = currRotation * phiRotation;
  459. vecL = TGeoTranslation(phiRotation * TGeoTranslation(1, 0, 0)); // Vector to left vertex of secctor
  460. if (doubleNE(rMaxPrev, 0) || doubleNE(rMaxCurrent, 0)) { //Work with external polyhedra
  461. vert0 = startZPoint + vecR * rMaxPrev; // Right bottom vertex
  462. vert1 = startZPoint + vecL * rMaxPrev; // Left bottom vertex
  463. vert2 = endZPoint + vecL * rMaxCurrent; // Left upper vertex
  464. vert3 = endZPoint + vecR * rMaxCurrent; // Right upper vertex
  465. arb.type = 2; // arb is ARB
  466. addVectorToElement(arb, 0, vert0);
  467. addVectorToElement(arb, 3, vert1);
  468. addVectorToElement(arb, 6, vert2);
  469. addVectorToElement(arb, 9, vert3);
  470. addVectorToElement(arb, 12, startZPoint);
  471. addVectorToElement(arb, 15, startZPoint);
  472. addVectorToElement(arb, 18, endZPoint);
  473. addVectorToElement(arb, 21, endZPoint);
  474. outerShell = orZone(outerShell, zoneList(1, std::vector<zoneElement>(1, std::make_pair(1, arb))));
  475. }
  476. if (doubleNE(rMinPrev, 0) || doubleNE(rMinCurrent, 0)) { //Work with internal polyhedra
  477. vert0 = startZPoint + vecR * rMinPrev; // Right bottom vertex
  478. vert1 = startZPoint + vecL * rMinPrev; // Left bottom vertex
  479. vert2 = endZPoint + vecL * rMinCurrent; // Left upper vertex
  480. vert3 = endZPoint + vecR * rMinCurrent; // Right upper vertex
  481. arb.type = 2; // wed is ARB
  482. addVectorToElement(arb, 0, vert0);
  483. addVectorToElement(arb, 3, vert1);
  484. addVectorToElement(arb, 6, vert2);
  485. addVectorToElement(arb, 9, vert3);
  486. addVectorToElement(arb, 12, startZPoint);
  487. addVectorToElement(arb, 15, startZPoint);
  488. addVectorToElement(arb, 18, endZPoint);
  489. addVectorToElement(arb, 21, endZPoint);
  490. out = orZone(out, zoneList(1, std::vector<zoneElement>(1, std::make_pair(1, arb))));
  491. }
  492. }
  493. }
  494. out = andZone(outerShell, notZone(out));
  495. return std::make_pair(out, outerShell);
  496. }
  497. inline std::pair<zoneList, zoneList> ellipticalTubeToZones(TGeoEltu *tube, TGeoHMatrix currTransformation, double scale) {
  498. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  499. TGeoHMatrix currRotation = TGeoHMatrix(currTransformation); currRotation.SetTranslation(kNullVector);
  500. double dx = (double)tube->GetA() * scale;
  501. double dy = (double)tube->GetB() * scale;
  502. double dz = (double)tube->GetDz() * scale;
  503. TGeoTranslation startPoint = TGeoTranslation(currTransformation * TGeoTranslation(0, 0, -dz));
  504. TGeoTranslation endVec = TGeoTranslation(currRotation * TGeoTranslation(0, 0, 2 * dz));
  505. TGeoTranslation xAxis = TGeoTranslation(currRotation * TGeoTranslation(dx, 0, 0));
  506. TGeoTranslation yAxis = TGeoTranslation(currRotation * TGeoTranslation(0, dy, 0));
  507. SGeoBody rec = {6, {}};
  508. addVectorToElement(rec, 0, startPoint);
  509. addVectorToElement(rec, 3, endVec);
  510. addVectorToElement(rec, 6, xAxis);
  511. addVectorToElement(rec, 9, yAxis);
  512. out.push_back(std::vector<zoneElement>(1, std::make_pair(1, rec)));
  513. outerShell = out;
  514. return std::make_pair(out, outerShell);
  515. }
  516. inline std::pair<zoneList, zoneList> arb8ToZones(TGeoArb8 *gtrap, TGeoHMatrix currTransformation, double scale) {
  517. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  518. TGeoHMatrix currRotation = TGeoHMatrix(currTransformation); currRotation.SetTranslation(kNullVector);
  519. double dz = (double)gtrap->GetDz() * scale;
  520. Double_t vertexes [8][2];
  521. Double_t *tmpPointer = gtrap->GetVertices();
  522. memcpy(&vertexes[0][0], tmpPointer, 8 * 2 * sizeof(Double_t));
  523. TGeoTranslation tmp;
  524. double cx, cy, cz;
  525. SGeoBody trap = {2, {}};
  526. for (int i = 0; i < 8; i++) {
  527. cx = vertexes[i][0] * scale;
  528. cy = vertexes[i][1] * scale;
  529. cz = (i < 4) ? -dz : dz;
  530. tmp = TGeoTranslation(currTransformation * TGeoTranslation(cx, cy, cz));
  531. addVectorToElement(trap, i * 3, tmp);
  532. }
  533. out.push_back(std::vector<zoneElement>(1, std::make_pair(1, trap)));
  534. outerShell = out;
  535. return std::make_pair(out, outerShell);
  536. }
  537. std::pair<zoneList, zoneList> compositeShapeToZones(TGeoCompositeShape *shape, TGeoHMatrix currTransformation, double scale) {
  538. zoneList out, outerShell; //outer shell for conjunction at generating mother volume
  539. TGeoBoolNode *boolNode = shape->GetBoolNode();
  540. TGeoMatrix *lm = boolNode->GetLeftMatrix();
  541. TGeoShape *ls = boolNode->GetLeftShape();
  542. TGeoHMatrix ln = (*lm) * currTransformation;
  543. std::pair<zoneList, zoneList> lo = getZoneFromShape(ls, ln, scale);
  544. TGeoMatrix *rm = boolNode->GetRightMatrix();
  545. TGeoShape *rs = boolNode->GetRightShape();
  546. TGeoHMatrix rn = (*rm) * currTransformation;
  547. std::pair<zoneList, zoneList> ro = getZoneFromShape(rs, rn, scale);
  548. switch (boolNode->GetBooleanOperator()) {
  549. case TGeoBoolNode::kGeoUnion:
  550. return std::pair<zoneList, zoneList>(orZone(lo.first, ro.first), orZone(lo.second, ro.second));
  551. break;
  552. case TGeoBoolNode::kGeoIntersection:
  553. return std::pair<zoneList, zoneList>(andZone(lo.first, ro.first), orZone(lo.second, ro.second));
  554. break;
  555. case TGeoBoolNode::kGeoSubtraction:
  556. return std::pair<zoneList, zoneList>(andZone(lo.first, ro.first), notZone(orZone(lo.second, ro.second)));
  557. break;
  558. default:
  559. printf("Something is wrong with Node. Returning subtraction");
  560. return std::pair<zoneList, zoneList>(andZone(lo.first, ro.first), notZone(orZone(lo.second, ro.second)));
  561. }
  562. }
  563. MediumData getMedium(TGeoNode *node) {
  564. double g = 1;
  565. double cm3 = getDefaultScale() * getDefaultScale() * getDefaultScale();
  566. MediumData out = {0, 0, 0, {}};
  567. TGeoMaterial *medium = node->GetMedium()->GetMaterial();
  568. out.nChemEl = medium->GetNelements();
  569. out.nType = (out.nChemEl == 1) ? 1 : 2;
  570. out.Rho = medium->GetDensity() / (g / cm3);
  571. if (out.Rho == 0) {
  572. printf("Is medium a Vacuum?");
  573. out.nType = 1000;
  574. return out;
  575. }
  576. for (int i = 0; i < out.nChemEl; ++i) {
  577. out.Elements[i].Nuclid = medium->GetElement(i)->Z();
  578. out.Elements[i].A = medium->GetElement(i)->N();
  579. out.Elements[i].Z = medium->GetElement(i)->Z();
  580. out.Elements[i].Density = (medium->IsMixture()) ? out.Rho * (((TGeoMixture *)medium)->GetWmixt())[i] : out.Rho;
  581. out.Elements[i].Conc = out.Elements[i].Density / medium->GetElement(i)->A() * TMath::Na() * 1E-27;
  582. // out.Elements[i].Conc = mat->GetVecNbOfAtomsPerVolume()[i] * cm3 * 1E-27; //Correct
  583. // out.Elements[i].ionEv = mat->GetElement(i)->GetIonisation()->GetMeanExcitationEnergy() / eV; //As I unserstand, it is, but it can fill automatically.
  584. for (int k = 0; k < i; ++k) {
  585. if (out.nType != 3 && out.Elements[i].Z == out.Elements[k].Z)
  586. out.nType = 3;
  587. }
  588. }
  589. return out;
  590. }
  591. }