PageRenderTime 29ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Mag/src/ToroidField.cxx

https://gitlab.com/mehrhart/clasdigi
C++ | 349 lines | 163 code | 47 blank | 139 comment | 21 complexity | f27210dc0772b19d1b3ccf5304bd85d7 MD5 | raw file
  1. #include "ToroidField.h"
  2. #include <iomanip>
  3. #include <iostream>
  4. #include <sstream>
  5. #include <fstream>
  6. #include "CLHEP/Units/SystemOfUnits.h"
  7. #include "TMath.h"
  8. #include "ClasDigiConfig.h"
  9. #include "Field.h"
  10. //______________________________________________________________________________
  11. clas12::mag::ToroidField::ToroidField() :
  12. fDelta_phi(30.0/120),
  13. fDelta_r(2.0),
  14. fDelta_z(2.0),
  15. fphi_min(0.0), // deg
  16. fphi_max(30.0), // deg
  17. fr_min(0.0), // cm
  18. fr_max(500.0), // cm
  19. fz_min(100.0), // cm
  20. fz_max(600.0), // cm
  21. fStride_phi(121),
  22. fStride_r(251),
  23. fStride_z(251),
  24. fphi_offset(0.0),
  25. fr_offset(0.0),
  26. fz_offset(-100.0)
  27. {
  28. fMapFileName = ClasDigi_DATA_DIR"/clas12TorusOriginalMap.dat";
  29. //fMapFileName = ClasDigi_DATA_DIR"/clas12TorusOriginalMap.dat";
  30. //clas12SolenoidFieldMap.dat clas12TorusOriginalMap.dat
  31. }
  32. //______________________________________________________________________________
  33. clas12::mag::ToroidField::~ToroidField()
  34. {
  35. }
  36. //______________________________________________________________________________
  37. void clas12::mag::ToroidField::Clear(const char * opt)
  38. {
  39. }
  40. //______________________________________________________________________________
  41. void clas12::mag::ToroidField::Print(const char * opt) const
  42. {
  43. }
  44. //______________________________________________________________________________
  45. void clas12::mag::ToroidField::ReadMap(const char * opt)
  46. {
  47. std::string option = opt;
  48. bool verbose_printing = false;
  49. if( option.find('v') != std::string::npos ){
  50. verbose_printing = true;
  51. }
  52. if( verbose_printing ) {
  53. std::cout << "Reading Toroid Field Map : \n";
  54. std::cout << fMapFileName << std::endl;
  55. }
  56. fMapFile.open(fMapFileName.c_str());
  57. std::string line;
  58. for(int i = 0;i<20;i++) {
  59. std::getline(fMapFile, line);
  60. std::stringstream ss;
  61. ss << line;
  62. std::string temp;
  63. ss >> temp;
  64. if( verbose_printing ) {
  65. std::cout << line << "\n";
  66. }
  67. if( temp == "</mfield>" ) break;
  68. }
  69. double phi = 0.0;
  70. double r = 0.0;
  71. double z = 0.0;
  72. double Bphi = 0.0;
  73. double Br = 0.0;
  74. double Bz = 0.0;
  75. int n_lines = 0;
  76. while(std::getline(fMapFile, line)) {
  77. n_lines++;
  78. std::stringstream ss;
  79. ss << line;
  80. //std::string temp;
  81. //ss >> temp;
  82. //std::cout << line << "\n";
  83. ss >> phi >> r >> z >> Bphi >> Br >> Bz;
  84. fphi.push_back(phi);
  85. fr.push_back(r);
  86. fz.push_back(z);
  87. fBphi.push_back(Bphi);
  88. fBr.push_back(Br);
  89. fBz.push_back(Bz);
  90. //if(n_lines < 50) {
  91. // std::cout << phi << " " << r << " " << z << " " << Bphi << " " << Br << " " << Bz << "\n";
  92. //}
  93. }
  94. if( verbose_printing ) {
  95. std::cout << "ToroidField has " << n_lines << " data points\n";
  96. std::cout << "done reading solenoid field map \n";
  97. std::cout << " n_phi : " << fBphi.size() << std::endl;
  98. std::cout << " n_r : " << fBr.size() << std::endl;
  99. std::cout << " n_z : " << fBz.size() << std::endl;
  100. std::cout << " fStride_phi*fStride_r*fStride_z : " << fStride_phi*fStride_r*fStride_z << std::endl;
  101. }
  102. //fParticles->Clear();
  103. //fNParticles = 0;
  104. fMapFile.close();
  105. }
  106. //______________________________________________________________________________
  107. TVector3 clas12::mag::ToroidField::GetField(const TVector3& v) const
  108. {
  109. return GetField(v.x(), v.y(), v.z());
  110. }
  111. //______________________________________________________________________________
  112. TVector3 clas12::mag::ToroidField::GetField(double x, double y, double z) const
  113. {
  114. double Bx = 0.0;
  115. double By = 0.0;
  116. double Bz = 0.0;
  117. TVector3 thePositionVector(x,y,z);
  118. double phi = thePositionVector.Phi() - 0.0*CLHEP::degree;
  119. double zz = z; // cm
  120. double rr = TMath::Sqrt(x*x + y*y); // cm
  121. double pphi = phi/CLHEP::degree;//(phi + 2.0*CLHEP::pi)/CLHEP::degree;
  122. int nPhi = 0.0;//(int(pphi+30)/60);
  123. if( pphi < 0 ) pphi += 360.0;
  124. while( pphi > 30.0 ){
  125. pphi -= 60.0;
  126. nPhi++;
  127. }
  128. //pphi = pphi - nPhi*60.0;
  129. //nPhi = nPhi%6;
  130. // z -> i,
  131. // r -> j
  132. // phi -> k
  133. double sign = 1.0;
  134. double pp = pphi;
  135. //std::cout << pphi << std::endl;
  136. //std::cout << nPhi << std::endl;
  137. if( (pphi > -fphi_max ) && (pphi <=fphi_max)
  138. && (zz >= fz_min) && (zz < fz_max)
  139. && (rr >= fr_min) && (rr < fr_max) ) {
  140. if( pphi < 0.0 ) {
  141. sign = -1.0;
  142. pp = TMath::Abs(pphi);
  143. }
  144. // Fix the problem when the value is at the upper limit
  145. if( pp == fphi_max ) pp -= 0.000001;
  146. int ii = (int)TMath::Floor((zz + fz_offset)/fDelta_z);
  147. int jj = (int)TMath::Floor((rr + fr_offset)/fDelta_r);
  148. int kk = (int)TMath::Floor((pp + fphi_offset)/fDelta_phi);
  149. // get interpolated Bz value
  150. int k0 = (ii) + fStride_z*jj + fStride_z*fStride_r*kk;
  151. int k1 = (ii+1) + fStride_z*jj + fStride_z*fStride_r*kk;
  152. int k2 = (ii+1) + fStride_z*(jj+1) + fStride_z*fStride_r*kk;
  153. int k3 = (ii) + fStride_z*(jj+1) + fStride_z*fStride_r*kk;
  154. int k4 = (ii) + fStride_z*jj + fStride_z*fStride_r*(kk+1);
  155. int k5 = (ii+1) + fStride_z*jj + fStride_z*fStride_r*(kk+1);
  156. int k6 = (ii+1) + fStride_z*(jj+1) + fStride_z*fStride_r*(kk+1);
  157. int k7 = (ii) + fStride_z*(jj+1) + fStride_z*fStride_r*(kk+1);
  158. //check
  159. //std::cout << fz.at(k0) << " < " << zz << " < " << fz.at(k1) << std::endl;
  160. //std::cout << fr.at(k1) << " < " << rr << " < " << fr.at(k2) << std::endl;
  161. //std::cout << fphi.at(k3) << " < " << pp << " < " << fphi.at(k4) << std::endl;
  162. std::array<double,6> corners = {fz.at(k0), fz.at(k1), fr.at(k1), fr.at(k2), fphi.at(k3), fphi.at(k4)};
  163. std::array<double,8> cornerBz = {fBz.at(k0), fBz.at(k1), fBz.at(k2), fBz.at(k3), fBz.at(k4), fBz.at(k5), fBz.at(k6), fBz.at(k7)};
  164. double interpBz = clas12::mag::TrilinearInterpolation(cornerBz, corners, zz , rr, pp);
  165. std::array<double,8> cornerBr = {fBr.at(k0), fBr.at(k1), fBr.at(k2), fBr.at(k3), fBr.at(k4), fBr.at(k5), fBr.at(k6), fBr.at(k7)};
  166. double interpBr = clas12::mag::TrilinearInterpolation(cornerBr, corners, zz , rr, pp);
  167. std::array<double,8> cornerBphi = {fBphi.at(k0), fBphi.at(k1), fBphi.at(k2), fBphi.at(k3), fBphi.at(k4), fBphi.at(k5), fBphi.at(k6), fBphi.at(k7)};
  168. double interpBphi = clas12::mag::TrilinearInterpolation(cornerBphi, corners, zz , rr, pp);
  169. interpBz *= 0.1; // kG->T
  170. interpBr *= 0.1; // kG->T
  171. interpBphi *= 0.1; // kG->T
  172. double extra_rot = 0.0*CLHEP::degree;
  173. //std::cout << " pp " << pp << "\n";
  174. //std::cout << " pphi " << pphi << "\n";
  175. //std::cout << " phi_k3 " << fphi.at(k3) << "\n";
  176. //std::cout << " phi_k4 " << fphi.at(k4) << "\n";
  177. //TVector3 theField(
  178. // sign*interpBr*TMath::Cos(pp*CLHEP::degree) - interpBphi*TMath::Sin(pp*CLHEP::degree),
  179. // sign*interpBr*TMath::Sin(pp*CLHEP::degree) + interpBphi*TMath::Cos(pp*CLHEP::degree),
  180. // sign*interpBz);
  181. TVector3 theField(
  182. sign*interpBr*TMath::Sin(0.0*CLHEP::degree) + interpBphi*TMath::Cos(0.0*CLHEP::degree),
  183. sign*interpBr*TMath::Cos(0.0*CLHEP::degree) - interpBphi*TMath::Sin(0.0*CLHEP::degree),
  184. sign*interpBz );
  185. if( sign == -1.0 ) {
  186. // //extra_rot = (30.0+pp)*CLHEP::degree;
  187. // //theField.RotateZ(extra_rot);
  188. // extra_rot = 60.0*CLHEP::degree + 2.0*pp*CLHEP::degree;
  189. theField = TVector3(
  190. -1.0*(sign*interpBr*TMath::Sin(0.0*CLHEP::degree) + interpBphi*TMath::Cos(0.0*CLHEP::degree)),
  191. -1.0*(sign*interpBr*TMath::Cos(0.0*CLHEP::degree) - interpBphi*TMath::Sin(0.0*CLHEP::degree)),
  192. -1.0*sign*interpBz );
  193. // theField.SetXYZ(sign*theField.X(),
  194. // theField.Y(),
  195. // sign*theField.Z() );
  196. ////// theField.RotateZ( (30.0+pp)*CLHEP::degree);
  197. }
  198. theField.RotateZ( (double(nPhi))*60.0*CLHEP::degree + extra_rot );
  199. Bx = theField.X();// * fScalingCoefficient;
  200. By = theField.Y();// * fScalingCoefficient;
  201. Bz = theField.Z();// * fScalingCoefficient;
  202. } else {
  203. Bx = 0.0;
  204. By = 0.0;
  205. Bz = 0.0;
  206. }
  207. //std::cout << "x (" << x << ", " << y << ", " << z << ")\n";
  208. //std::cout << "B (" << Bx << ", " << By << ", " << Bz << ")\n";
  209. return TVector3(Bx,By,Bz);
  210. }
  211. //______________________________________________________________________________
  212. //void clas12::mag::ToroidField::ReadLundEvent(std::ifstream& in)
  213. //{
  214. // fEventNumber++;
  215. // Clear();
  216. // int npart = ReadLundHeader(in);
  217. // for(int i = 0; i< npart; i++) {
  218. // ReadLundParticle(in);
  219. // }
  220. //}
  221. ////______________________________________________________________________________
  222. //
  223. //int clas12::mag::ToroidField::ReadLundHeader(std::ifstream& in)
  224. //{
  225. // std::string line;
  226. // std::getline(in, line);
  227. // std::stringstream ss;
  228. // ss << line;
  229. //
  230. // // Lund format reference: https://gemc.jlab.org/gemc/Documentation/Entries/2011/3/18_The_LUND_Format.html
  231. // // Header:
  232. // // Column Quantity
  233. // // 1 Number of particles
  234. // // 2* Number of target nucleons
  235. // // 3* Number of target protons
  236. // // 4* Target Polarization
  237. // // 5 Beam Polarization
  238. // // 6* x
  239. // // 7* y
  240. // // 8* W
  241. // // 9* Q2
  242. // // 10* nu
  243. // int ipart,A,Z;
  244. //
  245. // ss >> ipart;
  246. // ss >> A;
  247. // ss >> Z;
  248. // ss >> fTargetPol;
  249. // ss >> fBeamPol;
  250. // double temp;
  251. // if(ss.eof()){
  252. // std::cout << "error: end of sstream\n";
  253. // }
  254. // for(int i = 5; i<10; i++) {
  255. // ss >> temp;
  256. // }
  257. // //std::cout << "ipart = " << ipart <<std::endl;
  258. // return ipart;
  259. //}
  260. ////______________________________________________________________________________
  261. //
  262. //int clas12::mag::ToroidField::ReadLundParticle(std::ifstream& in)
  263. //{
  264. // std::string line;
  265. // std::getline(in, line);
  266. // std::stringstream ss;
  267. // ss << line;
  268. //
  269. // // Lund format reference: https://gemc.jlab.org/gemc/Documentation/Entries/2011/3/18_The_LUND_Format.html
  270. // // NOTE the vertex is in METERS unlike the website above
  271. // int iLund, charge, type, pdg, parent, daughter;
  272. // double px,py,pz, E, mass, vx,vy,vz;
  273. // TParticle * part = AddParticle();
  274. // //std::cout << fNParticles << " particles\n";
  275. // //std::cout << line << std::endl;
  276. //
  277. // ss >> iLund ;
  278. // ss >> charge;
  279. // ss >> type;
  280. // ss >> pdg;
  281. // ss >> parent;
  282. // ss >> daughter;
  283. // ss >> px;
  284. // ss >> py;
  285. // ss >> pz;
  286. // ss >> E;
  287. // ss >> mass;
  288. // ss >> vx;
  289. // ss >> vy;
  290. // ss >> vz;
  291. // //if(ss.eof()){
  292. // // std::cout << "error: end of sstream\n";
  293. // //}
  294. //
  295. // part->SetPdgCode(pdg);
  296. // part->SetMomentum(px,py,pz,E);
  297. // part->SetProductionVertex(vx,vy,vz,0.0);
  298. // //part->Print();
  299. //
  300. // return iLund;
  301. //}
  302. ////______________________________________________________________________________