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.

257 lines
8.0 KiB

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