You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
8.0 KiB

10 months ago
  1. from parameterisations.utils.parse_regression_coef_to_array import (
  2. parse_regression_coef_to_array,
  3. )
  4. from parameterisations.utils.fit_linear_regression_model import (
  5. fit_linear_regression_model,
  6. )
  7. import uproot
  8. import argparse
  9. from pathlib import Path
  10. def parameterise_track_model(
  11. input_file: str = "data/param_data_selected.root",
  12. tree_name: str = "Selected",
  13. ) -> Path:
  14. """Function that calculates the parameterisations to estimate track model coefficients.
  15. Args:
  16. input_file (str, optional): Defaults to "data/param_data_selected.root".
  17. tree_name (str, optional): Defaults to "Selected".
  18. Returns:
  19. Path: Path to cpp code files containing the found parameters.
  20. """
  21. input_tree = uproot.open({input_file: tree_name})
  22. # this is an event list of dictionaries containing awkward arrays
  23. array = input_tree.arrays()
  24. array["dSlope_fringe"] = array["tx_ref"] - array["tx"]
  25. array["dSlope_fringe_abs"] = abs(array["dSlope_fringe"])
  26. array["yStraightRef"] = array["y"] + array["ty"] * (array["z_ref"] - array["z"])
  27. array["y_ref_straight_diff"] = array["y_ref"] - array["yStraightRef"]
  28. array["ty_ref_straight_diff"] = array["ty_ref"] - array["ty"]
  29. array["dSlope_xEndT"] = array["tx_l11"] - array["tx"]
  30. array["dSlope_yEndT"] = array["ty_l11"] - array["ty"]
  31. array["dSlope_xEndT_abs"] = abs(array["dSlope_xEndT"])
  32. array["dSlope_yEndT_abs"] = abs(array["dSlope_yEndT"])
  33. array["yStraightOut"] = array["y"] + array["ty"] * (array["z_out"] - array["z"])
  34. array["yDiffOut"] = array["y_out"] - array["yStraightOut"]
  35. array["yStraightEndT"] = array["y"] + array["ty"] * (9410.0 - array["z"])
  36. array["yDiffEndT"] = (
  37. array["y_l11"] + array["ty_l11"] * (9410.0 - array["z_l11"])
  38. ) - array["yStraightEndT"]
  39. stereo_layers = [1, 2, 5, 6, 9, 10]
  40. for layer in stereo_layers:
  41. array[f"y_straight_diff_l{layer}"] = (
  42. array[f"y_l{layer}"]
  43. - array["y"]
  44. - array["ty"] * (array[f"z_l{layer}"] - array["z"])
  45. )
  46. model_cx, poly_features_cx = fit_linear_regression_model(
  47. array,
  48. target_feat="CX_ex",
  49. features=["tx", "ty", "dSlope_fringe"],
  50. degree=3,
  51. keep_only_linear_in="dSlope_fringe",
  52. fit_intercept=False,
  53. )
  54. model_dx, poly_features_dx = fit_linear_regression_model(
  55. array,
  56. target_feat="DX_ex",
  57. features=["tx", "ty", "dSlope_fringe"],
  58. degree=3,
  59. keep_only_linear_in="dSlope_fringe",
  60. fit_intercept=False,
  61. )
  62. # this list has been found empirically by C.Hasse
  63. keep_y_corr = [
  64. "ty dSlope_fringe_abs",
  65. "ty tx^2 dSlope_fringe_abs",
  66. "ty^3 dSlope_fringe_abs",
  67. "ty^3 tx^2 dSlope_fringe_abs",
  68. "dSlope_fringe",
  69. "ty tx dSlope_fringe",
  70. "ty tx^3 dSlope_fringe",
  71. "ty^3 tx dSlope_fringe",
  72. ]
  73. model_y_corr_ref, poly_features_y_corr_ref = fit_linear_regression_model(
  74. array,
  75. target_feat="y_ref_straight_diff",
  76. features=["ty", "tx", "dSlope_fringe", "dSlope_fringe_abs"],
  77. keep=keep_y_corr,
  78. degree=6,
  79. fit_intercept=False,
  80. )
  81. rows = []
  82. for layer in stereo_layers:
  83. model_y_corr_l, poly_features_y_corr_l = fit_linear_regression_model(
  84. array,
  85. target_feat=f"y_straight_diff_l{layer}",
  86. features=["ty", "tx", "dSlope_fringe", "dSlope_fringe_abs"],
  87. keep=keep_y_corr,
  88. degree=6,
  89. fit_intercept=False,
  90. )
  91. rows.append(
  92. "{"
  93. + ",".join(
  94. [str(coef) + "f" for coef in model_y_corr_l.coef_ if coef != 0.0],
  95. )
  96. + "}",
  97. )
  98. model_ty_corr_ref, poly_features_ty_corr_ref = fit_linear_regression_model(
  99. array,
  100. target_feat="ty_ref_straight_diff",
  101. features=["ty", "tx", "dSlope_fringe", "dSlope_fringe_abs"],
  102. # this list was found by using Lasso regularisation to drop useless features
  103. keep=[
  104. "ty dSlope_fringe^2",
  105. "ty tx^2 dSlope_fringe_abs",
  106. "ty^3 dSlope_fringe_abs",
  107. "ty^3 tx^2 dSlope_fringe_abs",
  108. "ty tx dSlope_fringe",
  109. "ty tx^3 dSlope_fringe",
  110. ],
  111. degree=6,
  112. fit_intercept=False,
  113. )
  114. model_cy, poly_features_cy = fit_linear_regression_model(
  115. array,
  116. target_feat="CY_ex",
  117. features=["ty", "tx", "dSlope_fringe", "dSlope_fringe_abs"],
  118. # this list was found by using Lasso regularisation to drop useless features
  119. keep=[
  120. "ty dSlope_fringe^2",
  121. "ty dSlope_fringe_abs",
  122. "ty tx^2 dSlope_fringe_abs",
  123. "ty^3 dSlope_fringe_abs",
  124. "ty tx dSlope_fringe",
  125. ],
  126. degree=4,
  127. fit_intercept=False,
  128. )
  129. model_y_match, poly_features_y_match = fit_linear_regression_model(
  130. array,
  131. target_feat="yDiffOut",
  132. features=[
  133. "ty",
  134. "dSlope_xEndT",
  135. "dSlope_yEndT",
  136. ],
  137. keep=[
  138. "ty dSlope_yEndT^2",
  139. "ty dSlope_xEndT^2",
  140. ],
  141. degree=3,
  142. fit_intercept=False,
  143. )
  144. keep_y_match_precise = [
  145. "dSlope_yEndT",
  146. "ty dSlope_xEndT_abs",
  147. "ty dSlope_yEndT_abs",
  148. "ty dSlope_yEndT^2",
  149. "ty dSlope_xEndT^2",
  150. "ty tx dSlope_xEndT",
  151. "tx^2 dSlope_yEndT",
  152. "ty tx^2 dSlope_xEndT_abs",
  153. "ty^3 tx dSlope_xEndT",
  154. ]
  155. model_y_match_precise, poly_features_y_match_precise = fit_linear_regression_model(
  156. array,
  157. "yDiffEndT",
  158. [
  159. "ty",
  160. "tx",
  161. "dSlope_xEndT",
  162. "dSlope_yEndT",
  163. "dSlope_xEndT_abs",
  164. "dSlope_yEndT_abs",
  165. ],
  166. keep=keep_y_match_precise,
  167. degree=5,
  168. )
  169. cpp_cx = parse_regression_coef_to_array(model_cx, poly_features_cx, "cxParams")
  170. cpp_dx = parse_regression_coef_to_array(model_dx, poly_features_dx, "dxParams")
  171. cpp_y_corr_layers = parse_regression_coef_to_array(
  172. model_y_corr_l,
  173. poly_features_y_corr_l,
  174. "yCorrParamsLayers",
  175. rows=rows,
  176. )
  177. cpp_y_corr_ref = parse_regression_coef_to_array(
  178. model_y_corr_ref,
  179. poly_features_y_corr_ref,
  180. "yCorrParamsRef",
  181. )
  182. cpp_ty_corr_ref = parse_regression_coef_to_array(
  183. model_ty_corr_ref,
  184. poly_features_ty_corr_ref,
  185. "tyCorrParamsRef",
  186. )
  187. cpp_cy = parse_regression_coef_to_array(model_cy, poly_features_cy, "cyParams")
  188. cpp_y_match = parse_regression_coef_to_array(
  189. model_y_match,
  190. poly_features_y_match,
  191. "bendYParamsMatch",
  192. )
  193. cpp_y_match_precise = parse_regression_coef_to_array(
  194. model_y_match_precise,
  195. poly_features_y_match_precise,
  196. "bendYParams",
  197. )
  198. outpath = Path("parameterisations/result/track_model_params.hpp")
  199. outpath.parent.mkdir(parents=True, exist_ok=True)
  200. with open(outpath, "w") as result:
  201. result.writelines(
  202. cpp_cx
  203. + cpp_dx
  204. + cpp_y_corr_layers
  205. + cpp_y_corr_ref
  206. + cpp_ty_corr_ref
  207. + cpp_cy
  208. + cpp_y_match
  209. + cpp_y_match_precise,
  210. )
  211. return outpath
  212. if __name__ == "__main__":
  213. parser = argparse.ArgumentParser()
  214. parser.add_argument(
  215. "--input-file",
  216. type=str,
  217. help="Path to the input file",
  218. required=False,
  219. )
  220. parser.add_argument(
  221. "--tree-name",
  222. type=str,
  223. help="Path to the input file",
  224. required=False,
  225. )
  226. args = parser.parse_args()
  227. args_dict = {arg: val for arg, val in vars(args).items() if val is not None}
  228. outfile = parameterise_track_model(**args_dict)
  229. try:
  230. import subprocess
  231. # run clang-format for nicer looking result
  232. subprocess.run(
  233. [
  234. "clang-format",
  235. "-i",
  236. f"{outfile}",
  237. ],
  238. check=True,
  239. )
  240. except:
  241. pass