MpdFemtoPair.cxx 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277
  1. //
  2. // Holds information about pair of particles
  3. //
  4. // MpdFemtoMaker headers
  5. #include "MpdFemtoPair.h"
  6. // ROOT headers
  7. #include "TMath.h"
  8. // C++ headers
  9. #include <iostream>
  10. float MpdFemtoPair::mMaxDuInner = 0.8f;
  11. float MpdFemtoPair::mMaxDzInner = 3.0f;
  12. float MpdFemtoPair::mMaxDuOuter = 1.4f;
  13. float MpdFemtoPair::mMaxDzOuter = 3.2f;
  14. float MpdFemtoPair::mTpcRadiusMin = 34.f; //[cm]
  15. float MpdFemtoPair::mTpcRadiusMax = 163.f; //[cm]
  16. //_________________
  17. MpdFemtoPair::MpdFemtoPair() :
  18. mTrack1(nullptr),
  19. mTrack2(nullptr),
  20. mNonIdParNotCalculated(0),
  21. mDKSide(0),
  22. mDKOut(0),
  23. mDKLong(0),
  24. mCVK(0),
  25. mKStarCalc(0),
  26. mNonIdParNotCalculatedGlobal(0),
  27. mDKSideGlobal(0),
  28. mDKOutGlobal(0),
  29. mDKLongGlobal(0),
  30. mKStarCalcGlobal(0),
  31. mCVKGlobal(0),
  32. mMergingParNotCalculated(0),
  33. mWeightedAvSep(0),
  34. mFracOfMergedRow(0),
  35. mClosestRowAtDCA(0),
  36. mMergingParNotCalculatedTrkV0Pos(0),
  37. mFracOfMergedRowTrkV0Pos(0),
  38. mClosestRowAtDCATrkV0Pos(0),
  39. mMergingParNotCalculatedTrkV0Neg(0),
  40. mFracOfMergedRowTrkV0Neg(0),
  41. mClosestRowAtDCATrkV0Neg(0),
  42. mMergingParNotCalculatedV0PosV0Neg(0),
  43. mFracOfMergedRowV0PosV0Neg(0),
  44. mClosestRowAtDCAV0PosV0Neg(0),
  45. mMergingParNotCalculatedV0NegV0Pos(0),
  46. mFracOfMergedRowV0NegV0Pos(0),
  47. mClosestRowAtDCAV0NegV0Pos(0),
  48. mMergingParNotCalculatedV0PosV0Pos(0),
  49. mFracOfMergedRowV0PosV0Pos(0),
  50. mClosestRowAtDCAV0PosV0Pos(0),
  51. mMergingParNotCalculatedV0NegV0Neg(0),
  52. mFracOfMergedRowV0NegV0Neg(0),
  53. mClosestRowAtDCAV0NegV0Neg(0) {
  54. // Default constructor
  55. setDefaultHalfFieldMergingPar();
  56. }
  57. //_________________
  58. MpdFemtoPair::MpdFemtoPair(MpdFemtoParticle* a, MpdFemtoParticle* b) :
  59. mTrack1(a),
  60. mTrack2(b),
  61. mNonIdParNotCalculated(0),
  62. mDKSide(0),
  63. mDKOut(0),
  64. mDKLong(0),
  65. mCVK(0),
  66. mKStarCalc(0),
  67. mNonIdParNotCalculatedGlobal(0),
  68. mDKSideGlobal(0),
  69. mDKOutGlobal(0),
  70. mDKLongGlobal(0),
  71. mKStarCalcGlobal(0),
  72. mCVKGlobal(0),
  73. mMergingParNotCalculated(0),
  74. mWeightedAvSep(0),
  75. mFracOfMergedRow(0),
  76. mClosestRowAtDCA(0),
  77. mMergingParNotCalculatedTrkV0Pos(0),
  78. mFracOfMergedRowTrkV0Pos(0),
  79. mClosestRowAtDCATrkV0Pos(0),
  80. mMergingParNotCalculatedTrkV0Neg(0),
  81. mFracOfMergedRowTrkV0Neg(0),
  82. mClosestRowAtDCATrkV0Neg(0),
  83. mMergingParNotCalculatedV0PosV0Neg(0),
  84. mFracOfMergedRowV0PosV0Neg(0),
  85. mClosestRowAtDCAV0PosV0Neg(0),
  86. mMergingParNotCalculatedV0NegV0Pos(0),
  87. mFracOfMergedRowV0NegV0Pos(0),
  88. mClosestRowAtDCAV0NegV0Pos(0),
  89. mMergingParNotCalculatedV0PosV0Pos(0),
  90. mFracOfMergedRowV0PosV0Pos(0),
  91. mClosestRowAtDCAV0PosV0Pos(0),
  92. mMergingParNotCalculatedV0NegV0Neg(0),
  93. mFracOfMergedRowV0NegV0Neg(0),
  94. mClosestRowAtDCAV0NegV0Neg(0) {
  95. // Construct pair from two particles
  96. setDefaultHalfFieldMergingPar();
  97. }
  98. //_________________
  99. MpdFemtoPair::MpdFemtoPair(const MpdFemtoPair& pair) :
  100. mTrack1(pair.mTrack1),
  101. mTrack2(pair.mTrack2),
  102. mNonIdParNotCalculated(pair.mNonIdParNotCalculated),
  103. mDKSide(pair.mDKSide),
  104. mDKOut(pair.mDKOut),
  105. mDKLong(pair.mDKLong),
  106. mCVK(pair.mCVK),
  107. mKStarCalc(pair.mKStarCalc),
  108. mNonIdParNotCalculatedGlobal(pair.mNonIdParNotCalculatedGlobal),
  109. mDKSideGlobal(pair.mDKSideGlobal),
  110. mDKOutGlobal(pair.mDKOutGlobal),
  111. mDKLongGlobal(pair.mDKLongGlobal),
  112. mKStarCalcGlobal(pair.mKStarCalcGlobal),
  113. mCVKGlobal(pair.mCVKGlobal),
  114. mMergingParNotCalculated(pair.mMergingParNotCalculated),
  115. mWeightedAvSep(pair.mWeightedAvSep),
  116. mFracOfMergedRow(pair.mFracOfMergedRow),
  117. mClosestRowAtDCA(pair.mClosestRowAtDCA),
  118. mMergingParNotCalculatedTrkV0Pos(pair.mMergingParNotCalculatedTrkV0Pos),
  119. mFracOfMergedRowTrkV0Pos(pair.mFracOfMergedRowTrkV0Pos),
  120. mClosestRowAtDCATrkV0Pos(pair.mClosestRowAtDCATrkV0Pos),
  121. mMergingParNotCalculatedTrkV0Neg(pair.mMergingParNotCalculatedTrkV0Neg),
  122. mFracOfMergedRowTrkV0Neg(pair.mFracOfMergedRowTrkV0Neg),
  123. mClosestRowAtDCATrkV0Neg(pair.mClosestRowAtDCATrkV0Neg),
  124. mMergingParNotCalculatedV0PosV0Neg(pair.mMergingParNotCalculatedV0PosV0Neg),
  125. mFracOfMergedRowV0PosV0Neg(pair.mFracOfMergedRowV0PosV0Neg),
  126. mClosestRowAtDCAV0PosV0Neg(pair.mClosestRowAtDCAV0PosV0Neg),
  127. mMergingParNotCalculatedV0NegV0Pos(pair.mMergingParNotCalculatedV0NegV0Pos),
  128. mFracOfMergedRowV0NegV0Pos(pair.mFracOfMergedRowV0NegV0Pos),
  129. mClosestRowAtDCAV0NegV0Pos(pair.mClosestRowAtDCAV0NegV0Pos),
  130. mMergingParNotCalculatedV0PosV0Pos(pair.mMergingParNotCalculatedV0PosV0Pos),
  131. mFracOfMergedRowV0PosV0Pos(pair.mFracOfMergedRowV0PosV0Pos),
  132. mClosestRowAtDCAV0PosV0Pos(pair.mClosestRowAtDCAV0PosV0Pos),
  133. mMergingParNotCalculatedV0NegV0Neg(pair.mMergingParNotCalculatedV0NegV0Neg),
  134. mFracOfMergedRowV0NegV0Neg(pair.mFracOfMergedRowV0NegV0Neg),
  135. mClosestRowAtDCAV0NegV0Neg(pair.mClosestRowAtDCAV0NegV0Neg) {
  136. // Copy constructor
  137. /* empty */
  138. }
  139. //_________________
  140. MpdFemtoPair& MpdFemtoPair::operator=(const MpdFemtoPair& pair) {
  141. // Assignment operator
  142. if (this != &pair) {
  143. mTrack1 = pair.mTrack1;
  144. mTrack2 = pair.mTrack2;
  145. mNonIdParNotCalculated = pair.mNonIdParNotCalculated;
  146. mDKSide = pair.mDKSide;
  147. mDKOut = pair.mDKOut;
  148. mDKLong = pair.mDKLong;
  149. mCVK = pair.mCVK;
  150. mKStarCalc = pair.mKStarCalc;
  151. mNonIdParNotCalculatedGlobal = pair.mNonIdParNotCalculatedGlobal;
  152. mDKSideGlobal = pair.mDKSideGlobal;
  153. mDKOutGlobal = pair.mDKOutGlobal;
  154. mDKLongGlobal = pair.mDKLongGlobal;
  155. mKStarCalcGlobal = pair.mKStarCalcGlobal;
  156. mCVKGlobal = pair.mCVKGlobal;
  157. mMergingParNotCalculated = pair.mMergingParNotCalculated;
  158. mWeightedAvSep = pair.mWeightedAvSep;
  159. mFracOfMergedRow = pair.mFracOfMergedRow;
  160. mClosestRowAtDCA = pair.mClosestRowAtDCA;
  161. mMergingParNotCalculatedTrkV0Pos = pair.mMergingParNotCalculatedTrkV0Pos;
  162. mFracOfMergedRowTrkV0Pos = pair.mFracOfMergedRowTrkV0Pos;
  163. mClosestRowAtDCATrkV0Pos = pair.mClosestRowAtDCATrkV0Pos;
  164. mMergingParNotCalculatedTrkV0Neg = pair.mMergingParNotCalculatedTrkV0Neg;
  165. mFracOfMergedRowTrkV0Neg = pair.mFracOfMergedRowTrkV0Neg;
  166. mClosestRowAtDCATrkV0Neg = pair.mClosestRowAtDCATrkV0Neg;
  167. mMergingParNotCalculatedV0PosV0Neg = pair.mMergingParNotCalculatedV0PosV0Neg;
  168. mFracOfMergedRowV0PosV0Neg = pair.mFracOfMergedRowV0PosV0Neg;
  169. mClosestRowAtDCAV0PosV0Neg = pair.mClosestRowAtDCAV0PosV0Neg;
  170. mMergingParNotCalculatedV0NegV0Pos = pair.mMergingParNotCalculatedV0NegV0Pos;
  171. mFracOfMergedRowV0NegV0Pos = pair.mFracOfMergedRowV0NegV0Pos;
  172. mClosestRowAtDCAV0NegV0Pos = pair.mClosestRowAtDCAV0NegV0Pos;
  173. mMergingParNotCalculatedV0PosV0Pos = pair.mMergingParNotCalculatedV0PosV0Pos;
  174. mFracOfMergedRowV0PosV0Pos = pair.mFracOfMergedRowV0PosV0Pos;
  175. mClosestRowAtDCAV0PosV0Pos = pair.mClosestRowAtDCAV0PosV0Pos;
  176. mMergingParNotCalculatedV0NegV0Neg = pair.mMergingParNotCalculatedV0NegV0Neg;
  177. mFracOfMergedRowV0NegV0Neg = pair.mFracOfMergedRowV0NegV0Neg;
  178. mClosestRowAtDCAV0NegV0Neg = pair.mClosestRowAtDCAV0NegV0Neg;
  179. }
  180. return *this;
  181. }
  182. //_________________
  183. MpdFemtoPair::~MpdFemtoPair() {
  184. /* empty */
  185. }
  186. //_________________
  187. void MpdFemtoPair::setDefaultHalfFieldMergingPar() {
  188. // Cluster sizes, described in the dimension of TPC sector local coordinates
  189. mMaxDuInner = 3;
  190. mMaxDzInner = 4.;
  191. mMaxDuOuter = 4.;
  192. mMaxDzOuter = 6.;
  193. }
  194. //_________________
  195. void MpdFemtoPair::setDefaultFullFieldMergingPar() {
  196. // Cluster sizes, described in the dimension of TPC sector local coordinates
  197. mMaxDuInner = 0.8;
  198. mMaxDzInner = 3.;
  199. mMaxDuOuter = 1.4;
  200. mMaxDzOuter = 3.2;
  201. }
  202. //_________________
  203. void MpdFemtoPair::setMergingPar(float aMaxDuInner, float aMaxDzInner,
  204. float aMaxDuOuter, float aMaxDzOuter) {
  205. // Cluster sizes, described in the dimension of TPC sector local coordinates
  206. mMaxDuInner = aMaxDuInner;
  207. mMaxDzInner = aMaxDzInner;
  208. mMaxDuOuter = aMaxDuOuter;
  209. mMaxDzOuter = aMaxDzOuter;
  210. }
  211. //_________________
  212. double MpdFemtoPair::emissionAngle() const {
  213. double angle = TMath::ATan2(py(), px()) * TMath::RadToDeg();
  214. if (angle < 0) {
  215. angle += 360.0;
  216. }
  217. return angle;
  218. }
  219. //_________________
  220. void MpdFemtoPair::qYKPCMS(double& qP, double& qT, double& q0) const {
  221. // Yano-Koonin-Podgoretskii Parametrisation in CMS
  222. // Calculate momentum difference in source rest frame (= lab frame)
  223. // Random ordering of the particles
  224. TLorentzVector l = ((rand() / (double) RAND_MAX) > 0.50 ?
  225. (mTrack1->fourMomentum() - mTrack2->fourMomentum()) :
  226. (mTrack2->fourMomentum() - mTrack1->fourMomentum()));
  227. // Fill momentum differences into return variables
  228. qP = l.Pz();
  229. qT = l.Vect().Perp();
  230. q0 = l.Energy();
  231. }
  232. //_________________
  233. void MpdFemtoPair::qYKPLCMS(double& qP, double& qT, double& q0) const {
  234. // Yano-Koonin-Podgoretskii Parametrisation in LCMS
  235. // Calculate momentum difference in LCMS : frame where pz1 + pz2 = 0
  236. TLorentzVector l1 = mTrack1->fourMomentum();
  237. TLorentzVector l2 = mTrack2->fourMomentum();
  238. // Determine beta to LCMS
  239. double betaZ = fourMomentumSum().Pz() / fourMomentumSum().Energy();
  240. // Boost in the correct direction
  241. if (betaZ > 0) {
  242. betaZ = -betaZ;
  243. }
  244. // Boost particles along the beam into a frame with velocity beta
  245. l1.Boost(0., 0., betaZ);
  246. l2.Boost(0., 0., betaZ);
  247. // Caculate the momentum difference with random ordering of the particle
  248. TLorentzVector l = ((rand() / (double) RAND_MAX) > 0.5 ?
  249. (l1 - l2) : (l2 - l1));
  250. // Fill momentum differences into return variables
  251. qP = l.Z();
  252. qT = l.Vect().Perp();
  253. q0 = l.Energy();
  254. }
  255. //_________________
  256. void MpdFemtoPair::qYKPPF(double& qP, double& qT, double& q0) const {
  257. // Yano-Koonin-Podgoretskii Parametrisation in pair rest fram
  258. // Calculate momentum difference in pair rest frame :
  259. // frame where (pz1 + pz2, py1 + py2, px1 + px2) = (0,0,0)
  260. TLorentzVector l1 = mTrack1->fourMomentum();
  261. TLorentzVector l2 = mTrack2->fourMomentum();
  262. // Calculate beta in each direction
  263. double betaX = -fourMomentumSum().Px() / fourMomentumSum().Energy();
  264. double betaY = -fourMomentumSum().Py() / fourMomentumSum().Energy();
  265. double betaZ = -fourMomentumSum().Pz() / fourMomentumSum().Energy();
  266. // Boost particles
  267. l1.Boost(betaX, betaY, betaZ);
  268. l2.Boost(betaX, betaY, betaZ);
  269. // Caculate the momentum difference with random ordering of the particle
  270. TLorentzVector l = ((rand() / (double) RAND_MAX) > 0.50 ?
  271. (l1 - l2) : (l2 - l1));
  272. // Fill momentum differences into return variables
  273. qP = l.Z();
  274. qT = l.Vect().Perp();
  275. q0 = l.Energy();
  276. }
  277. //_________________
  278. double MpdFemtoPair::qOutCMS() const {
  279. // Relative momentum out component in the lab frame
  280. double dx = mTrack1->px() - mTrack2->px();
  281. double xt = mTrack1->px() + mTrack2->px();
  282. double dy = mTrack1->py() - mTrack2->py();
  283. double yt = mTrack1->py() + mTrack2->py();
  284. double k1 = TMath::Sqrt(xt * xt + yt * yt);
  285. double k2 = dx * xt + dy*yt;
  286. return (k1 != 0) ? (k2 / k1) : 0.;
  287. }
  288. //_________________
  289. double MpdFemtoPair::qSideCMS() const {
  290. // Relative momentum side component in the lab frame
  291. double x1 = mTrack1->px();
  292. double y1 = mTrack1->py();
  293. double x2 = mTrack2->px();
  294. double y2 = mTrack2->py();
  295. double xt = x1 + x2;
  296. double yt = y1 + y2;
  297. double k1 = TMath::Sqrt(xt * xt + yt * yt);
  298. return ( (k1 != 0) ? (2.0 * (x2 * y1 - x1 * y2) / k1) : 0.);
  299. }
  300. //_________________
  301. double MpdFemtoPair::qLongCMS() const {
  302. // Relative momentum long component in the lab frame
  303. double dz = mTrack1->pz() - mTrack2->pz();
  304. double zz = mTrack1->pz() + mTrack2->pz();
  305. double dt = mTrack1->t() - mTrack2->t();
  306. double tt = mTrack1->t() + mTrack2->t();
  307. double beta = zz / tt;
  308. double gamma = 1.0 / TMath::Sqrt(1.0 - beta * beta);
  309. return ( gamma * (dz - beta * dt));
  310. }
  311. //_________________
  312. double MpdFemtoPair::qOutPf() const {
  313. // Relative momentum out component in the pair frame
  314. double dt = mTrack1->t() - mTrack2->t();
  315. double tt = mTrack1->t() + mTrack2->t();
  316. double xt = mTrack1->px() + mTrack2->px();
  317. double yt = mTrack1->py() + mTrack2->py();
  318. double k1 = TMath::Sqrt(xt * xt + yt * yt);
  319. double bOut = k1 / tt;
  320. double gOut = 1.0 / TMath::Sqrt(1.0 - bOut * bOut);
  321. return ( gOut * (this->qOutCMS() - bOut * dt));
  322. }
  323. //_________________
  324. double MpdFemtoPair::qSidePf() const {
  325. // Relative momentum side component in the pair frame
  326. return ( this->qSideCMS());
  327. }
  328. //_________________
  329. double MpdFemtoPair::qLongPf() const {
  330. // Relative momentum long component in the pair frame
  331. return ( this->qLongCMS());
  332. }
  333. //_________________
  334. double MpdFemtoPair::qOutBf(double /* beta */) const {
  335. // Relative momentum long component in the boosted frame
  336. return ( this->qOutCMS());
  337. }
  338. //_________________
  339. double MpdFemtoPair::qSideBf(double /* beta */) const {
  340. // Relative momentum long component in the boosted frame
  341. return ( this->qSideCMS());
  342. }
  343. //_________________
  344. double MpdFemtoPair::qLongBf(double beta) const {
  345. // Relative momentum long component in the boosted frame
  346. double dz = mTrack1->pz() - mTrack2->pz();
  347. double dt = mTrack1->t() + mTrack2->t();
  348. double gamma = 1.0 / TMath::Sqrt(1.0 - beta * beta);
  349. return ( gamma * (dz - beta * dt));
  350. }
  351. //_________________
  352. double MpdFemtoPair::quality() const {
  353. // Estimation of track splitting
  354. ULong_t hitMap1 = mTrack1->topologyMap();
  355. ULong_t hitMap2 = mTrack2->topologyMap();
  356. std::vector <Int_t> hitsOnPadrowTrack1;
  357. std::vector <Int_t> hitsOnPadrowTrack2;
  358. for (Int_t iRow = 0; iRow < MpdFemtoParticle::mNumberOfPadrows; iRow++) {
  359. ULong64_t bit1 = hitMap1 & (1UL << iRow);
  360. ULong64_t bit2 = hitMap2 & (1UL << iRow);
  361. if (bit1 != 0)
  362. hitsOnPadrowTrack1.push_back(iRow);
  363. if (bit2 != 0)
  364. hitsOnPadrowTrack2.push_back(iRow);
  365. }
  366. Int_t quality = 0;
  367. for (Int_t iPadrow = 0; iPadrow < MpdFemtoParticle::mNumberOfPadrows; iPadrow++) {
  368. auto hit1 = std::find(hitsOnPadrowTrack1.begin(), hitsOnPadrowTrack1.end(), iPadrow);
  369. auto hit2 = std::find(hitsOnPadrowTrack2.begin(), hitsOnPadrowTrack2.end(), iPadrow);
  370. if (hit1 != hitsOnPadrowTrack1.end() && hit2 != hitsOnPadrowTrack2.end()) {
  371. // Both tracks leave a hit on padrow ...
  372. quality--;
  373. }
  374. else if (hit1 != hitsOnPadrowTrack1.end() || hit2 != hitsOnPadrowTrack2.end()) {
  375. // Neither track leaves a hit on padrow ...
  376. quality++;
  377. }
  378. }
  379. // unsigned long mapMask0 = 0xFFFFFF00;
  380. // unsigned long mapMask1 = 0x1FFFFF;
  381. // unsigned long padRow1To24Track1 = mTrack1->topologyMap(0) & mapMask0;
  382. // unsigned long padRow25To45Track1 = mTrack1->topologyMap(1) & mapMask1;
  383. // unsigned long padRow1To24Track2 = mTrack2->topologyMap(0) & mapMask0;
  384. // unsigned long padRow25To45Track2 = mTrack2->topologyMap(1) & mapMask1;
  385. // // AND logic
  386. // unsigned long bothPads1To24 = padRow1To24Track1 & padRow1To24Track2;
  387. // unsigned long bothPads25To45 = padRow25To45Track1 & padRow25To45Track2;
  388. // // XOR logic
  389. // unsigned long onePad1To24 = padRow1To24Track1 ^ padRow1To24Track2;
  390. // unsigned long onePad25To45 = padRow25To45Track1 ^ padRow25To45Track2;
  391. // unsigned long bitI;
  392. // int ibits;
  393. // int Quality = 0;
  394. // for (ibits = 8; ibits <= 31; ibits++) {
  395. // bitI = 0;
  396. // bitI |= 1UL << (ibits);
  397. // if (onePad1To24 & bitI) {
  398. // Quality++;
  399. // continue;
  400. // }// if ( onePad1To24 & bitI )
  401. // else {
  402. // if (bothPads1To24 & bitI) Quality--;
  403. // } //else {
  404. // } //for (ibits=8;ibits<=31;ibits++)
  405. // for (ibits = 0; ibits <= 20; ibits++) {
  406. // bitI = 0;
  407. // bitI |= 1UL << (ibits);
  408. // if (onePad25To45 & bitI) {
  409. // Quality++;
  410. // continue;
  411. // }//if ( onePad25To45 & bitI )
  412. // else {
  413. // if (bothPads25To45 & bitI) {
  414. // Quality--;
  415. // } //if ( bothPads25To45 & bitI )
  416. // } //else {
  417. // } //for (ibits=0;ibits<=20;ibits++)
  418. return ( (double) quality / ((double) (mTrack1->nHits() + mTrack2->nHits())));
  419. }
  420. //_________________
  421. double MpdFemtoPair::quality2() const {
  422. // unsigned long mapMask0 = 0xFFFFFF00;
  423. // unsigned long mapMask1 = 0x1FFFFF;
  424. // unsigned long padRow1To24Track1 = mTrack1->topologyMap(0) & mapMask0;
  425. // unsigned long padRow25To45Track1 = mTrack1->topologyMap(1) & mapMask1;
  426. // unsigned long padRow1To24Track2 = mTrack2->topologyMap(0) & mapMask0;
  427. // unsigned long padRow25To45Track2 = mTrack2->topologyMap(1) & mapMask1;
  428. // // AND logic
  429. // //unsigned long bothPads1To24 = padRow1To24Track1 & padRow1To24Track2;
  430. // //unsigned long bothPads25To45 = padRow25To45Track1 & padRow25To45Track2;
  431. // // XOR logic
  432. // unsigned long onePad1To24 = padRow1To24Track1 ^ padRow1To24Track2;
  433. // unsigned long onePad25To45 = padRow25To45Track1 ^ padRow25To45Track2;
  434. // unsigned long bitI;
  435. // int ibits;
  436. int Quality = 0;
  437. // for (ibits = 8; ibits <= 31; ibits++) {
  438. // bitI = 0;
  439. // bitI |= 1UL << (ibits);
  440. // if (onePad1To24 & bitI) {
  441. // Quality++;
  442. // continue;
  443. // }
  444. // //else{
  445. // //if ( bothPads1To24 & bitI ) Quality--;
  446. // //}
  447. // }
  448. // for (ibits = 0; ibits <= 20; ibits++) {
  449. // bitI = 0;
  450. // bitI |= 1UL << (ibits);
  451. // if (onePad25To45 & bitI) {
  452. // Quality++;
  453. // continue;
  454. // }
  455. // //else{
  456. // //if ( bothPads25To45 & bitI ) Quality--;
  457. // //}
  458. // }
  459. return ( (double) Quality / ((double) (mTrack1->nHits() + mTrack2->nHits())));
  460. }
  461. //_________________
  462. double MpdFemtoPair::nominalTpcExitSeparation() const {
  463. // Distance between tracks at nominal exit point
  464. return ( mTrack1->nominalTpcExitPoint() -
  465. mTrack2->nominalTpcExitPoint()).Mag();
  466. }
  467. //_________________
  468. double MpdFemtoPair::nominalTpcEntranceSeparation() const {
  469. // Distance between tracks at nominal entrance point
  470. return ( mTrack1->nominalTpcEntrancePoint() -
  471. mTrack2->nominalTpcEntrancePoint()).Mag();
  472. }
  473. //_________________
  474. double MpdFemtoPair::nominalTpcAverageSeparation() const {
  475. double AveSep = 0.0;
  476. int ipt = 0;
  477. if (mTrack1->nominalPosSampleX() && mTrack2->nominalPosSampleX() &&
  478. mTrack1->nominalPosSampleY() && mTrack2->nominalPosSampleY() &&
  479. mTrack1->nominalPosSampleZ() && mTrack2->nominalPosSampleZ()) {
  480. while (ipt < mTrack1->mNumberOfPoints &&
  481. TMath::Abs(mTrack1->nominalPosSampleX()[ipt]) < 9999. &&
  482. TMath::Abs(mTrack1->nominalPosSampleY()[ipt]) < 9999. &&
  483. TMath::Abs(mTrack1->nominalPosSampleZ()[ipt]) < 9999. &&
  484. TMath::Abs(mTrack2->nominalPosSampleX()[ipt]) < 9999. &&
  485. TMath::Abs(mTrack2->nominalPosSampleY()[ipt]) < 9999. &&
  486. TMath::Abs(mTrack2->nominalPosSampleZ()[ipt]) < 9999.) {
  487. AveSep += (mTrack1->nominalPosSample(ipt) - mTrack2->nominalPosSample(ipt)).Mag();
  488. ipt++;
  489. }
  490. AveSep = AveSep / (ipt + 1.);
  491. } else {
  492. AveSep = -1.;
  493. }
  494. return AveSep;
  495. }
  496. //_________________
  497. double MpdFemtoPair::kStarFlipped() const {
  498. // Estimation of kStar with the flipped sign
  499. TLorentzVector tP1 = mTrack1->fourMomentum();
  500. // Flip the sign
  501. TVector3 qwe = mTrack1->p();
  502. qwe *= -1.; // flip it
  503. tP1.SetVect(qwe);
  504. TLorentzVector tSum = (tP1 + mTrack2->fourMomentum());
  505. TVector3 tGammaBeta = (1. / tSum.M()) * tSum.Vect();
  506. double tGamma = tSum.E() / tSum.M();
  507. TVector3 tLongMom = ((tP1.Vect() * tGammaBeta) /
  508. (tGammaBeta * tGammaBeta)) * tGammaBeta;
  509. // Constructor TLorentzVector( TVector3, double )
  510. TLorentzVector tK((tP1.Vect() + (tGamma - 1.) * tLongMom - tP1.E() * tGammaBeta),
  511. (tGamma * tP1.E() - tP1.Vect() * tGammaBeta));
  512. return tK.Vect().Mag();
  513. }
  514. //_________________
  515. double MpdFemtoPair::cvkFlipped() const {
  516. // CVK with sign flipped
  517. TLorentzVector tP1 = mTrack1->fourMomentum();
  518. TVector3 qwe = tP1.Vect();
  519. qwe *= -1.; // flip it
  520. tP1.SetVect(qwe);
  521. TLorentzVector tSum = (tP1 + mTrack2->fourMomentum());
  522. TVector3 tGammaBeta = (1. / tSum.M()) * tSum.Vect();
  523. double tGamma = tSum.E() / tSum.M();
  524. TVector3 tLongMom = ((tP1.Vect() * tGammaBeta) /
  525. (tGammaBeta * tGammaBeta)) * tGammaBeta;
  526. TLorentzVector tK((tP1.Vect() + (tGamma - 1.) * tLongMom - tP1.E() * tGammaBeta),
  527. (tGamma * tP1.E() - tP1.Vect() * tGammaBeta));
  528. return ( tGammaBeta * (1. / tGamma) * tK.Vect());
  529. }
  530. //_________________
  531. double MpdFemtoPair::pInv() const {
  532. // Invariant total momentum
  533. TLorentzVector tP1 = mTrack1->fourMomentum();
  534. TLorentzVector tP2 = mTrack2->fourMomentum();
  535. double tP = (tP1.Px() + tP2.Px()) * (tP1.Px() + tP2.Px())+
  536. (tP1.Py() + tP2.Py()) * (tP1.Py() + tP2.Py())+
  537. (tP1.Pz() + tP2.Pz()) * (tP1.Pz() + tP2.Pz())-
  538. (tP1.E() - tP2.E()) * (tP1.E() - tP2.E());
  539. return TMath::Sqrt(TMath::Abs(tP));
  540. }
  541. //_________________
  542. double MpdFemtoPair::qInvFlippedXY() const {
  543. // qInv with X and Y flipped of one of the track from pair
  544. TLorentzVector tP1 = mTrack1->fourMomentum();
  545. tP1.SetX(-1. * tP1.X());
  546. tP1.SetY(-1. * tP1.Y());
  547. return ( -1. * (tP1 - mTrack2->fourMomentum()).M());
  548. }
  549. //_________________
  550. double MpdFemtoPair::qInvRandomFlippedXY() const {
  551. // qInv with X and Y flipped of one of the track from pair.
  552. // The track is randomly selected.
  553. TLorentzVector tP1 = mTrack1->fourMomentum();
  554. TLorentzVector tP2 = mTrack1->fourMomentum();
  555. if (rand() / (double) RAND_MAX > 0.50) {
  556. tP1.SetX(-1. * tP1.X());
  557. tP1.SetY(-1. * tP1.Y());
  558. } else {
  559. tP2.SetX(-1. * tP2.X());
  560. tP2.SetY(-1. * tP2.Y());
  561. }
  562. return ( -1. * (tP1 - tP2).M());
  563. }
  564. //_________________
  565. double MpdFemtoPair::qInvFlippedXYZ() const {
  566. // qInv with X, Y and Z flipped of one of the track from pair
  567. TLorentzVector tP1 = mTrack1->fourMomentum();
  568. tP1.SetX(-1. * tP1.X());
  569. tP1.SetY(-1. * tP1.Y());
  570. tP1.SetZ(-1. * tP1.Z());
  571. return ( -1. * (tP1 - mTrack2->fourMomentum()).M());
  572. }
  573. //_________________
  574. double MpdFemtoPair::qInvRandomFlippedXYZ() const {
  575. // qInv with X, Y and Z flipped of one of the track from pair.
  576. // The track is randomly selected.
  577. TLorentzVector tP1 = mTrack1->fourMomentum();
  578. TLorentzVector tP2 = mTrack2->fourMomentum();
  579. if (rand() / (double) RAND_MAX > 0.50) {
  580. tP1.SetX(-1. * tP1.X());
  581. tP1.SetY(-1. * tP1.Y());
  582. tP1.SetZ(-1. * tP1.Z());
  583. } else {
  584. tP2.SetX(-1. * tP2.X());
  585. tP2.SetY(-1. * tP2.Y());
  586. tP2.SetZ(-1. * tP2.Z());
  587. }
  588. return ( -1. * (tP1 - tP2).M());
  589. }
  590. //_________________
  591. void MpdFemtoPair::calcNonIdPar() const {
  592. // Calculate generalized relative mometum
  593. // Use this instead of qXYZ() function when calculating
  594. // anything for non-identical particles
  595. mNonIdParNotCalculated = 0;
  596. double px1 = mTrack1->px();
  597. double py1 = mTrack1->py();
  598. double pz1 = mTrack1->pz();
  599. double pE1 = mTrack1->e();
  600. double Particle1Mass = 0;
  601. if ((pE1 * pE1 - px1 * px1 - py1 * py1 - pz1 * pz1) > 0) {
  602. Particle1Mass = TMath::Sqrt(pE1 * pE1 - px1 * px1 - py1 * py1 - pz1 * pz1);
  603. }
  604. double px2 = mTrack2->px();
  605. double py2 = mTrack2->py();
  606. double pz2 = mTrack2->pz();
  607. double pE2 = mTrack2->e();
  608. double Particle2Mass = 0;
  609. if ((pE1 * pE1 - px1 * px1 - py1 * py1 - pz1 * pz1) > 0) {
  610. Particle2Mass = TMath::Sqrt(pE2 * pE2 - px2 * px2 - py2 * py2 - pz2 * pz2);
  611. }
  612. double Px = px1 + px2;
  613. double Py = py1 + py2;
  614. double Pz = pz1 + pz2;
  615. double PE = pE1 + pE2;
  616. double Ptrans = Px * Px + Py*Py;
  617. double Mtrans = PE * PE - Pz*Pz;
  618. double Pinv = TMath::Sqrt(Mtrans - Ptrans);
  619. Mtrans = TMath::Sqrt(Mtrans);
  620. Ptrans = TMath::Sqrt(Ptrans);
  621. double QinvL = ((pE1 - pE2) * (pE1 - pE2) - (px1 - px2) * (px1 - px2) -
  622. (py1 - py2) * (py1 - py2) - (pz1 - pz2) * (pz1 - pz2));
  623. double Q = (Particle1Mass * Particle1Mass -
  624. Particle2Mass * Particle2Mass) / Pinv;
  625. Q = sqrt(Q * Q - QinvL);
  626. mKStarCalc = Q / 2;
  627. /// ad 1) go to LCMS
  628. double beta = Pz / PE;
  629. double gamma = PE / Mtrans;
  630. double pz1L = gamma * (pz1 - beta * pE1);
  631. double pE1L = gamma * (pE1 - beta * pz1);
  632. // fill histogram for beam projection ( z - axis )
  633. mDKLong = pz1L;
  634. // ad 2) rotation px -> Pt
  635. double px1R = (px1 * Px + py1 * Py) / Ptrans;
  636. double py1R = (-px1 * Py + py1 * Px) / Ptrans;
  637. // fill histograms for side projection ( y - axis )
  638. mDKSide = py1R;
  639. // ad 3) go from LCMS to CMS
  640. beta = Ptrans / Mtrans;
  641. gamma = Mtrans / Pinv;
  642. double px1C = gamma * (px1R - beta * pE1L);
  643. // fill histogram for out projection ( x - axis )
  644. mDKOut = px1C;
  645. mCVK = ((mDKOut * Ptrans + mDKLong * Pz) /
  646. mKStarCalc / TMath::Sqrt(Ptrans * Ptrans + Pz * Pz));
  647. }
  648. //_________________
  649. void MpdFemtoPair::calcNonIdParGlobal() const {
  650. // Calculate generalized relative mometum
  651. // Use this instead of qXYZ() function when calculating
  652. // anything for non-identical particles
  653. mNonIdParNotCalculatedGlobal = 0;
  654. double px1 = mTrack1->track()->gMom().X();
  655. double py1 = mTrack1->track()->gMom().Y();
  656. double pz1 = mTrack1->track()->gMom().Z();
  657. double Particle1Mass = mTrack1->fourMomentum().M2();
  658. double pE1 = TMath::Sqrt(Particle1Mass + px1 * px1 + py1 * py1 + pz1 * pz1);
  659. Particle1Mass = TMath::Sqrt(Particle1Mass);
  660. double px2 = mTrack2->track()->gMom().X();
  661. double py2 = mTrack2->track()->gMom().Y();
  662. double pz2 = mTrack2->track()->gMom().Z();
  663. double Particle2Mass = mTrack2->fourMomentum().M2();
  664. double pE2 = TMath::Sqrt(Particle2Mass + px2 * px2 + py2 * py2 + pz2 * pz2);
  665. Particle2Mass = TMath::Sqrt(Particle2Mass);
  666. double Px = px1 + px2;
  667. double Py = py1 + py2;
  668. double Pz = pz1 + pz2;
  669. double PE = pE1 + pE2;
  670. double Ptrans = Px * Px + Py * Py;
  671. double Mtrans = PE * PE - Pz * Pz;
  672. double Pinv = TMath::Sqrt(Mtrans - Ptrans);
  673. Mtrans = TMath::Sqrt(Mtrans);
  674. Ptrans = TMath::Sqrt(Ptrans);
  675. double QinvL = ((pE1 - pE2) * (pE1 - pE2) - (px1 - px2) * (px1 - px2) -
  676. (py1 - py2) * (py1 - py2) - (pz1 - pz2) * (pz1 - pz2));
  677. double Q = (Particle1Mass * Particle1Mass - Particle2Mass * Particle2Mass) / Pinv;
  678. Q = TMath::Sqrt(Q * Q - QinvL);
  679. mKStarCalcGlobal = Q / 2;
  680. /// ad 1) go to LCMS
  681. double beta = Pz / PE;
  682. double gamma = PE / Mtrans;
  683. double pz1L = gamma * (pz1 - beta * pE1);
  684. double pE1L = gamma * (pE1 - beta * pz1);
  685. // fill histogram for beam projection ( z - axis )
  686. mDKLongGlobal = pz1L;
  687. // ad 2) rotation px -> Pt
  688. double px1R = (px1 * Px + py1 * Py) / Ptrans;
  689. double py1R = (-px1 * Py + py1 * Px) / Ptrans;
  690. // fill histograms for side projection ( y - axis )
  691. mDKSideGlobal = py1R;
  692. // ad 3) go from LCMS to CMS
  693. beta = Ptrans / Mtrans;
  694. gamma = Mtrans / Pinv;
  695. double px1C = gamma * (px1R - beta * pE1L);
  696. // fill histogram for out projection ( x - axis )
  697. mDKOutGlobal = px1C;
  698. mCVKGlobal = ((mDKOutGlobal * Ptrans + mDKLongGlobal * Pz) /
  699. mKStarCalcGlobal / TMath::Sqrt(Ptrans * Ptrans + Pz * Pz));
  700. }
  701. //_________________
  702. double MpdFemtoPair::dcaInsideTpc() const {
  703. // DCA inside TPC
  704. double tMinDist = nominalTpcEntranceSeparation();
  705. double tExit = nominalTpcExitSeparation();
  706. tMinDist = (tExit > tMinDist) ? tMinDist : tExit;
  707. double tInsideDist;
  708. //tMinDist = 999.;
  709. double rMin = mTpcRadiusMin;
  710. double rMax = mTpcRadiusMax;
  711. MpdFemtoPhysicalHelix tHelix1 = mTrack1->helix();
  712. MpdFemtoPhysicalHelix tHelix2 = mTrack2->helix();
  713. // --- One is a line and other one a helix
  714. //if (tHelix1.mSingularity != tHelix2.mSingularity) return -999.;
  715. // --- 2 lines : don't care right now
  716. //if (tHelix1.mSingularity) return -999.;
  717. // --- 2 helix
  718. double dx = tHelix2.xcenter() - tHelix1.xcenter();
  719. double dy = tHelix2.ycenter() - tHelix1.ycenter();
  720. double dd = TMath::Sqrt(dx * dx + dy * dy);
  721. double r1 = 1 / tHelix1.curvature();
  722. double r2 = 1 / tHelix2.curvature();
  723. double cosAlpha = (r1 * r1 + dd * dd - r2 * r2) / (2 * r1 * dd);
  724. double x, y, r;
  725. double s;
  726. if (TMath::Abs(cosAlpha) < 1.) {
  727. // Two solutions
  728. double sinAlpha = TMath::Sin(TMath::ACos(cosAlpha));
  729. x = tHelix1.xcenter() + r1 * (cosAlpha * dx - sinAlpha * dy) / dd;
  730. y = tHelix1.ycenter() + r1 * (sinAlpha * dx + cosAlpha * dy) / dd;
  731. r = TMath::Sqrt(x * x + y * y);
  732. if ((r > rMin) && (r < rMax) &&
  733. TMath::Abs(TMath::ATan2(y, x) -
  734. mTrack1->nominalTpcEntrancePoint().Phi()) < 0.5) {
  735. // first solution inside
  736. s = tHelix1.pathLength(x, y);
  737. tInsideDist = tHelix2.distance(tHelix1.at(s));
  738. if (tInsideDist < tMinDist) {
  739. tMinDist = tInsideDist;
  740. }
  741. } else {
  742. x = tHelix1.xcenter() + r1 * (cosAlpha * dx + sinAlpha * dy) / dd;
  743. y = tHelix1.ycenter() + r1 * (cosAlpha * dy - sinAlpha * dx) / dd;
  744. r = TMath::Sqrt(x * x + y * y);
  745. if ((r > rMin) && (r < rMax) &&
  746. TMath::Abs(TMath::ATan2(y, x) -
  747. mTrack1->nominalTpcEntrancePoint().Phi()) < 0.5) {
  748. // second solution inside
  749. s = tHelix1.pathLength(x, y);
  750. tInsideDist = tHelix2.distance(tHelix1.at(s));
  751. if (tInsideDist < tMinDist) {
  752. tMinDist = tInsideDist;
  753. }
  754. }
  755. } //else
  756. } //if ( TMath::Abs( cosAlpha ) < 1. )
  757. return tMinDist;
  758. }
  759. //_________________
  760. void MpdFemtoPair::calcMergingPar() const {
  761. // Calculate merging factor for the pair in STAR TPC
  762. mMergingParNotCalculated = 0;
  763. double tDu, tDz;
  764. int tN = 0;
  765. mFracOfMergedRow = 0.;
  766. mWeightedAvSep = 0.;
  767. double tDist;
  768. double tDistMax = mTpcRadiusMax;
  769. for (int ti = 0; ti < mTrack1->mNumberOfPadrows; ti++) {
  770. if ((mTrack1->sect()[ti] == mTrack2->sect()[ti]) &&
  771. mTrack1->sect()[ti] != -1) {
  772. tDu = TMath::Abs(mTrack1->u()[ti] - mTrack2->u()[ti]);
  773. tDz = TMath::Abs(mTrack1->z()[ti] - mTrack2->z()[ti]);
  774. tN++;
  775. if (ti < 13) {
  776. mFracOfMergedRow += (tDu < mMaxDuInner && tDz < mMaxDzInner);
  777. tDist = TMath::Sqrt(tDu * tDu / mMaxDuInner / mMaxDuInner +
  778. tDz * tDz / mMaxDzInner / mMaxDzInner);
  779. //mFracOfMergedRow += (tDu<mMaxDuInner && tDz<mMaxDzInner);
  780. } else {
  781. mFracOfMergedRow += (tDu < mMaxDuOuter && tDz < mMaxDzOuter);
  782. tDist = TMath::Sqrt(tDu * tDu / mMaxDuOuter / mMaxDuOuter +
  783. tDz * tDz / mMaxDzOuter / mMaxDzOuter);
  784. //mFracOfMergedRow += (tDu<mMaxDuOuter && tDz<mMaxDzOuter);
  785. }
  786. if (tDist < tDistMax) {
  787. mClosestRowAtDCA = ti + 1;
  788. tDistMax = tDist;
  789. }
  790. mWeightedAvSep += tDist;
  791. }
  792. } // for ( int ti=0; ti < mTrack1->mNumberOfPadrows ; ti++ )
  793. if (tN > 0) {
  794. mWeightedAvSep /= tN;
  795. mFracOfMergedRow /= tN;
  796. } else {
  797. mClosestRowAtDCA = -1;
  798. mFracOfMergedRow = -1.;
  799. mWeightedAvSep = -1.;
  800. }
  801. }
  802. //________________V0 daughters exit/entrance/average separation calc.
  803. //_______1st part is a track 2nd is a V0 considering Pos daughter
  804. double MpdFemtoPair::tpcAverageSeparationTrackV0Pos() const {
  805. double AveSep = 0.0;
  806. int ipt = 0;
  807. if (mTrack1->nominalPosSampleX() && mTrack2->nominalPosSampleX() &&
  808. mTrack1->nominalPosSampleY() && mTrack2->nominalPosSampleY() &&
  809. mTrack1->nominalPosSampleZ() && mTrack2->nominalPosSampleZ()) {
  810. while (ipt < mTrack1->mNumberOfPoints &&
  811. TMath::Abs(mTrack1->nominalPosSampleX()[ipt]) < 9999. &&
  812. TMath::Abs(mTrack1->nominalPosSampleY()[ipt]) < 9999. &&
  813. TMath::Abs(mTrack1->nominalPosSampleZ()[ipt]) < 9999. &&
  814. TMath::Abs(mTrack2->nominalPosSampleX()[ipt]) < 9999. &&
  815. TMath::Abs(mTrack2->nominalPosSampleY()[ipt]) < 9999. &&
  816. TMath::Abs(mTrack2->nominalPosSampleZ()[ipt]) < 9999.) {
  817. AveSep += (mTrack1->nominalPosSample(ipt) - mTrack2->nominalPosSample(ipt)).Mag();
  818. ipt++;
  819. }
  820. AveSep = AveSep / (ipt + 1.);
  821. } else {
  822. AveSep = -1.;
  823. }
  824. return AveSep;
  825. }
  826. //_________________
  827. double MpdFemtoPair::tpcAverageSeparationTrackV0Neg() const {
  828. double AveSep = 0.0;
  829. int ipt = 0;
  830. if (mTrack1->nominalPosSampleX() && mTrack2->tpcV0NegPosSampleX() &&
  831. mTrack1->nominalPosSampleY() && mTrack2->tpcV0NegPosSampleY() &&
  832. mTrack1->nominalPosSampleZ() && mTrack2->tpcV0NegPosSampleZ()) {
  833. while (ipt < mTrack1->mNumberOfPoints &&
  834. TMath::Abs(mTrack1->nominalPosSampleX()[ipt]) < 9999. &&
  835. TMath::Abs(mTrack1->nominalPosSampleY()[ipt]) < 9999. &&
  836. TMath::Abs(mTrack1->nominalPosSampleZ()[ipt]) < 9999. &&
  837. TMath::Abs(mTrack2->nominalPosSampleX()[ipt]) < 9999. &&
  838. TMath::Abs(mTrack2->nominalPosSampleY()[ipt]) < 9999. &&
  839. TMath::Abs(mTrack2->nominalPosSampleZ()[ipt]) < 9999.) {
  840. AveSep = (mTrack1->nominalPosSample(ipt) - mTrack2->tpcV0NegPosSample(ipt)).Mag();
  841. ipt++;
  842. }
  843. AveSep = AveSep / (ipt + 1.);
  844. } else {
  845. AveSep = -1;
  846. }
  847. return AveSep;
  848. }
  849. //_________________
  850. double MpdFemtoPair::tpcAverageSeparationV0PosV0Pos() const {
  851. double AveSep = 0.0;
  852. int ipt = 0;
  853. if (mTrack1->nominalPosSampleX() && mTrack2->nominalPosSampleX() &&
  854. mTrack1->nominalPosSampleY() && mTrack2->nominalPosSampleY() &&
  855. mTrack1->nominalPosSampleZ() && mTrack2->nominalPosSampleZ()) {
  856. while (ipt < mTrack1->mNumberOfPoints &&
  857. TMath::Abs(mTrack1->nominalPosSampleX()[ipt]) < 9999. &&
  858. TMath::Abs(mTrack1->nominalPosSampleY()[ipt]) < 9999. &&
  859. TMath::Abs(mTrack1->nominalPosSampleZ()[ipt]) < 9999. &&
  860. TMath::Abs(mTrack2->nominalPosSampleX()[ipt]) < 9999. &&
  861. TMath::Abs(mTrack2->nominalPosSampleY()[ipt]) < 9999. &&
  862. TMath::Abs(mTrack2->nominalPosSampleZ()[ipt]) < 9999.) {
  863. AveSep += (mTrack1->nominalPosSample(ipt) - mTrack2->nominalPosSample(ipt)).Mag();
  864. ipt++;
  865. }
  866. AveSep = AveSep / (ipt + 1);
  867. } else {
  868. AveSep = -1;
  869. }
  870. return AveSep;
  871. }
  872. //_________________
  873. double MpdFemtoPair::tpcAverageSeparationV0PosV0Neg() const {
  874. double AveSep = 0.0;
  875. int ipt = 0;
  876. if (mTrack1->nominalPosSampleX() && mTrack2->tpcV0NegPosSampleX() &&
  877. mTrack1->nominalPosSampleY() && mTrack2->tpcV0NegPosSampleY() &&
  878. mTrack1->nominalPosSampleZ() && mTrack2->tpcV0NegPosSampleZ()) {
  879. while (ipt < mTrack1->mNumberOfPoints &&
  880. TMath::Abs(mTrack1->nominalPosSampleX()[ipt]) < 9999. &&
  881. TMath::Abs(mTrack1->nominalPosSampleY()[ipt]) < 9999. &&
  882. TMath::Abs(mTrack1->nominalPosSampleZ()[ipt]) < 9999. &&
  883. TMath::Abs(mTrack2->tpcV0NegPosSampleX()[ipt]) < 9999. &&
  884. TMath::Abs(mTrack2->tpcV0NegPosSampleY()[ipt]) < 9999. &&
  885. TMath::Abs(mTrack2->tpcV0NegPosSampleZ()[ipt]) < 9999.) {
  886. AveSep += (mTrack1->nominalPosSample(ipt) - mTrack2->tpcV0NegPosSample(ipt)).Mag();
  887. ipt++;
  888. }
  889. AveSep = AveSep / (ipt + 1.);
  890. } else {
  891. AveSep = -1;
  892. }
  893. return AveSep;
  894. }
  895. //_________________
  896. double MpdFemtoPair::tpcAverageSeparationV0NegV0Pos() const {
  897. double AveSep = 0.0;
  898. int ipt = 0;
  899. if (mTrack1->tpcV0NegPosSampleX() && mTrack2->nominalPosSampleX() &&
  900. mTrack1->tpcV0NegPosSampleY() && mTrack2->nominalPosSampleY() &&
  901. mTrack1->tpcV0NegPosSampleZ() && mTrack2->nominalPosSampleZ()) {
  902. while (ipt < mTrack1->mNumberOfPoints &&
  903. TMath::Abs(mTrack1->tpcV0NegPosSampleX()[ipt]) < 9999. &&
  904. TMath::Abs(mTrack1->tpcV0NegPosSampleY()[ipt]) < 9999. &&
  905. TMath::Abs(mTrack1->tpcV0NegPosSampleZ()[ipt]) < 9999. &&
  906. TMath::Abs(mTrack2->nominalPosSampleX()[ipt]) < 9999. &&
  907. TMath::Abs(mTrack2->nominalPosSampleY()[ipt]) < 9999. &&
  908. TMath::Abs(mTrack2->nominalPosSampleZ()[ipt]) < 9999.) {
  909. AveSep += (mTrack1->tpcV0NegPosSample(ipt) - mTrack2->nominalPosSample(ipt)).Mag();
  910. ipt++;
  911. }
  912. AveSep = AveSep / (ipt + 1);
  913. } else {
  914. AveSep = -1;
  915. }
  916. return AveSep;
  917. }
  918. //_________________
  919. double MpdFemtoPair::tpcAverageSeparationV0NegV0Neg() const {
  920. double AveSep = 0.0;
  921. int ipt = 0;
  922. if (mTrack1->tpcV0NegPosSampleX() && mTrack2->tpcV0NegPosSampleX() &&
  923. mTrack1->tpcV0NegPosSampleY() && mTrack2->tpcV0NegPosSampleY() &&
  924. mTrack1->tpcV0NegPosSampleZ() && mTrack2->tpcV0NegPosSampleZ()) {
  925. while (ipt < mTrack1->mNumberOfPoints &&
  926. TMath::Abs(mTrack1->tpcV0NegPosSampleX()[ipt]) < 9999. &&
  927. TMath::Abs(mTrack1->tpcV0NegPosSampleY()[ipt]) < 9999. &&
  928. TMath::Abs(mTrack1->tpcV0NegPosSampleZ()[ipt]) < 9999. &&
  929. TMath::Abs(mTrack2->tpcV0NegPosSampleX()[ipt]) < 9999. &&
  930. TMath::Abs(mTrack2->tpcV0NegPosSampleY()[ipt]) < 9999. &&
  931. TMath::Abs(mTrack2->tpcV0NegPosSampleZ()[ipt]) < 9999.) {
  932. AveSep += (mTrack1->tpcV0NegPosSample(ipt) - mTrack2->tpcV0NegPosSample(ipt)).Mag();
  933. ipt++;
  934. }
  935. AveSep = AveSep / (ipt + 1);
  936. } else {
  937. AveSep = -1;
  938. }
  939. return AveSep;
  940. }
  941. //_________________ End V0 daughters exit/entrance/average separation calc.
  942. void MpdFemtoPair::calcMergingParFctn(short* tmpMergingParNotCalculatedFctn,
  943. float* tmpZ1, float* tmpU1,
  944. float* tmpZ2, float* tmpU2,
  945. int *tmpSect1, int *tmpSect2,
  946. float* tmpFracOfMergedRow,
  947. float* tmpClosestRowAtDCA) const {
  948. tmpMergingParNotCalculatedFctn = 0;
  949. double tDu, tDz;
  950. int tN = 0;
  951. *tmpFracOfMergedRow = 0.;
  952. *tmpClosestRowAtDCA = 0.;
  953. double tDist;
  954. double tDistMax = 100000000.;
  955. // Loop over padrows
  956. for (int ti = 0; ti < mTrack1->mNumberOfPadrows; ti++) {
  957. if (tmpSect1[ti] == tmpSect2[ti] && tmpSect1[ti] != -1) {
  958. tDu = fabs(tmpU1[ti] - tmpU2[ti]);
  959. tDz = fabs(tmpZ1[ti] - tmpZ2[ti]);
  960. tN++;
  961. if (ti < 13) {
  962. *tmpFracOfMergedRow += (tDu < mMaxDuInner && tDz < mMaxDzInner);
  963. tDist = TMath::Sqrt(tDu * tDu / mMaxDuInner / mMaxDuInner +
  964. tDz * tDz / mMaxDzInner / mMaxDzInner);
  965. } else {
  966. *tmpFracOfMergedRow += (tDu < mMaxDuOuter && tDz < mMaxDzOuter);
  967. tDist = TMath::Sqrt(tDu * tDu / mMaxDuOuter / mMaxDuOuter +
  968. tDz * tDz / mMaxDzOuter / mMaxDzOuter);
  969. }
  970. if (tDist < tDistMax) {
  971. mClosestRowAtDCA = ti + 1;
  972. tDistMax = tDist;
  973. }
  974. //mWeightedAvSep += tDist; // now, wrong but not used
  975. }
  976. } // for(int ti=0 ; ti<mTrack1->mNumberOfPadrows ; ti++)
  977. if (tN > 0) {
  978. //mWeightedAvSep /= tN;
  979. *tmpFracOfMergedRow /= tN;
  980. } else {
  981. *tmpClosestRowAtDCA = -1;
  982. *tmpFracOfMergedRow = -1.;
  983. //mWeightedAvSep = -1.;
  984. }
  985. }
  986. //_________________
  987. double MpdFemtoPair::calculateDPhiStarMin(const TVector3& p_a,
  988. const short& charge_a,
  989. const TVector3& p_b,
  990. const short& charge_b,
  991. const double& rad_step_in_meters,
  992. const double& rad_min_in_meters,
  993. const double& rad_max_in_meters,
  994. const double& magnetic_field) {
  995. // Estimate minimal value of azimuthal angle disctance between two tracks
  996. // over a set of radial positions from rad_min to rad_max with_rad_step
  997. if (rad_max_in_meters > rad_max_in_meters) {
  998. std::cout << "[WARNING] double MpdFemtoDPhiStarDEtaEstimator::calculateDPhiStarMin - "
  999. << "Mimal radial distance is larger then maximal one" << std::endl;
  1000. return 0;
  1001. }
  1002. // Estimate DPhiStar at all requested radial distances
  1003. std::vector<double> dPhiStarValues = calculateDPhiStarValues(p_a, charge_a,
  1004. p_b, charge_b,
  1005. rad_step_in_meters,
  1006. rad_min_in_meters,
  1007. rad_max_in_meters,
  1008. magnetic_field);
  1009. // Check that vector is not empty
  1010. if (dPhiStarValues.empty()) {
  1011. return 0;
  1012. }
  1013. // STL vector that stores DPhiStar values estimated for requested radial positions
  1014. double minValue = 99999.;
  1015. double currentValue = 0.;
  1016. // Loop over radial positions
  1017. for (unsigned short iDist = 0; iDist < dPhiStarValues.size(); iDist++) {
  1018. currentValue = dPhiStarValues.at(iDist);
  1019. if (currentValue < minValue) {
  1020. minValue = currentValue;
  1021. }
  1022. } //for ( unsigned short iDist=0; iDist<nSteps; iDist++ )
  1023. return minValue;
  1024. }
  1025. //_________________
  1026. std::vector<double> MpdFemtoPair::calculateDPhiStarValues(const TVector3& p_a,
  1027. const short& charge_a,
  1028. const TVector3& p_b,
  1029. const short& charge_b,
  1030. const double& rad_step_in_meters,
  1031. const double& rad_min_in_meters,
  1032. const double& rad_max_in_meters,
  1033. const double& magnetic_field) {
  1034. // Estimate minimal value of azimuthal angle disctance between two tracks
  1035. // over a set of radial positions from rad_min to rad_max with_rad_step
  1036. // STL vector that stores DPhiStar values estimated for requested radial positions
  1037. std::vector<double> dPhiStar;
  1038. if (rad_min_in_meters > rad_max_in_meters) {
  1039. std::cout << "[WARNING] double MpdFemtoDPhiStarDEtaEstimator::calculateDPhiStarMin - "
  1040. << "Mimal radial distance is larger then maximal one" << std::endl;
  1041. return dPhiStar;
  1042. }
  1043. // Estimate number of calculations
  1044. unsigned short nSteps = (rad_max_in_meters - rad_min_in_meters) / rad_step_in_meters;
  1045. // Loop over radial positions
  1046. for (unsigned short iStep = 0; iStep <= nSteps; iStep++) {
  1047. dPhiStar.push_back(calculateDPhiStar(p_a, charge_a,
  1048. p_b, charge_b,
  1049. (rad_min_in_meters + iStep * rad_step_in_meters),
  1050. magnetic_field));
  1051. } //for ( unsigned short iStep=0; iStep<nSteps; iStep++ )
  1052. return dPhiStar;
  1053. }
  1054. //_________________
  1055. double MpdFemtoPair::calculateDPhi(const TVector3& p_a, const TVector3& p_b) {
  1056. // Calculate dPhi between two tracks
  1057. return ( p_a.Phi() - p_b.Phi());
  1058. }
  1059. //_________________
  1060. double MpdFemtoPair::calculateDPhiStar(const TVector3& p_a,
  1061. const short& charge_a,
  1062. const TVector3& p_b,
  1063. const short& charge_b,
  1064. const double& radius_in_meters,
  1065. const double& magnetic_field) {
  1066. // phi shift at radius R in magnetic field B, with charge and momentum q & p_T is:
  1067. // φ = arcsin( q * B * R / 2 p_T )
  1068. //
  1069. // Unit analysis:
  1070. // q * B * R : [Coulomb][Tesla][Meter] = 1.60218e-19 [e][Tesla][Meter]
  1071. // p_T : [Joule][Second]/[Meter] = 1.60218e-10 [GeV][Second]/[Meter] = 1.60218e-10 / c [GeV/c]
  1072. //
  1073. // q * B * R / p_T = (1.60218e-19 * c / 1.60218e-10) [e] [Tesla] [Meters] / [GeV/c]
  1074. // ~ 0.3 [e] [Tesla] [Meters] / [GeV/c]
  1075. //
  1076. // The difference in phi is calculated by examining the tracks' azimuthal angle
  1077. // at a particular radius of all tracks.
  1078. //
  1079. // \Delta \phi* = \phi_1 - \phi_2
  1080. // + arcsin \left( \frac{ charge_1 \cdot B_z \cdot R}{2 p_{T1}} \right)
  1081. // - arcsin \left( \frac{ charge_2 \cdot B_z \cdot R}{2 p_{T2}} \right)
  1082. double UNIT_FACTOR = 0.299792458;
  1083. double prefix = -0.5 * UNIT_FACTOR * magnetic_field * radius_in_meters;
  1084. double shift_a = TMath::ASin(prefix * charge_a / p_a.Perp());
  1085. double shift_b = TMath::ASin(prefix * charge_b / p_b.Perp());
  1086. return ( (p_b.Phi() + shift_b) - (p_a.Phi() + shift_a));
  1087. }
  1088. //_________________
  1089. double MpdFemtoPair::calculateDEta(const TVector3& a, const TVector3& b) {
  1090. // Calculate dEta between two tracks
  1091. return ( a.Eta() - b.Eta());
  1092. }
  1093. //_________________
  1094. double MpdFemtoPair::calculateDEtaStar(const TVector3& a, const TVector3& b,
  1095. const double& radius_in_meters) {
  1096. // Calculate dEta* (dEta at a given radius)
  1097. double RADIUS_CM = radius_in_meters * 100.0;
  1098. double thetas1 = TMath::Pi() / 2.0 - TMath::ATan(a.Z() / RADIUS_CM);
  1099. double thetas2 = TMath::Pi() / 2.0 - TMath::ATan(b.Z() / RADIUS_CM);
  1100. double etas1 = -TMath::Log(TMath::Tan(thetas1 / 2.0));
  1101. double etas2 = -TMath::Log(TMath::Tan(thetas2 / 2.0));
  1102. return TMath::Abs(etas1 - etas2);
  1103. }
  1104. ClassImp(MpdFemtoPair)