# flake8: noqa from parameterisations.utils.parse_regression_coef_to_array import ( parse_regression_coef_to_array, ) from parameterisations.utils.fit_linear_regression_model import ( fit_linear_regression_model, ) import uproot import argparse from pathlib import Path def parameterise_track_model( input_file: str = "data/param_data_selected.root", tree_name: str = "Selected", ) -> Path: """Function that calculates the parameterisations to estimate track model coefficients. Args: input_file (str, optional): Defaults to "data/param_data_selected.root". tree_name (str, optional): Defaults to "Selected". Returns: Path: Path to cpp code files containing the found parameters. """ input_tree = uproot.open({input_file: tree_name}) # this is an event list of dictionaries containing awkward arrays array = input_tree.arrays() array["dSlope_fringe"] = array["tx_ref"] - array["tx"] array["dSlope_fringe_abs"] = abs(array["dSlope_fringe"]) array["yStraightRef"] = array["y"] + array["ty"] * (array["z_ref"] - array["z"]) array["y_ref_straight_diff"] = array["y_ref"] - array["yStraightRef"] array["ty_ref_straight_diff"] = array["ty_ref"] - array["ty"] array["dSlope_xEndT"] = array["tx_l11"] - array["tx"] array["dSlope_yEndT"] = array["ty_l11"] - array["ty"] array["dSlope_xEndT_abs"] = abs(array["dSlope_xEndT"]) array["dSlope_yEndT_abs"] = abs(array["dSlope_yEndT"]) array["yStraightOut"] = array["y"] + array["ty"] * (array["z_out"] - array["z"]) array["yDiffOut"] = array["y_out"] - array["yStraightOut"] array["yStraightEndT"] = array["y"] + array["ty"] * (9410.0 - array["z"]) array["yDiffEndT"] = ( array["y_l11"] + array["ty_l11"] * (9410.0 - array["z_l11"]) ) - array["yStraightEndT"] stereo_layers = [1, 2, 5, 6, 9, 10] for layer in stereo_layers: array[f"y_straight_diff_l{layer}"] = ( array[f"y_l{layer}"] - array["y"] - array["ty"] * (array[f"z_l{layer}"] - array["z"]) ) model_cx, poly_features_cx = fit_linear_regression_model( array, target_feat="CX_ex", features=["tx", "ty", "dSlope_fringe"], degree=3, keep_only_linear_in="dSlope_fringe", fit_intercept=False, ) model_dx, poly_features_dx = fit_linear_regression_model( array, target_feat="DX_ex", features=["tx", "ty", "dSlope_fringe"], degree=3, keep_only_linear_in="dSlope_fringe", fit_intercept=False, ) # this list has been found empirically by C.Hasse keep_y_corr = [ "ty dSlope_fringe_abs", "ty tx^2 dSlope_fringe_abs", "ty^3 dSlope_fringe_abs", "ty^3 tx^2 dSlope_fringe_abs", "dSlope_fringe", "ty tx dSlope_fringe", "ty tx^3 dSlope_fringe", "ty^3 tx dSlope_fringe", ] model_y_corr_ref, poly_features_y_corr_ref = fit_linear_regression_model( array, target_feat="y_ref_straight_diff", features=["ty", "tx", "dSlope_fringe", "dSlope_fringe_abs"], keep=keep_y_corr, degree=6, fit_intercept=False, ) rows = [] for layer in stereo_layers: model_y_corr_l, poly_features_y_corr_l = fit_linear_regression_model( array, target_feat=f"y_straight_diff_l{layer}", features=["ty", "tx", "dSlope_fringe", "dSlope_fringe_abs"], keep=keep_y_corr, degree=6, fit_intercept=False, ) rows.append( "{" + ",".join( [str(coef) + "f" for coef in model_y_corr_l.coef_ if coef != 0.0], ) + "}", ) model_ty_corr_ref, poly_features_ty_corr_ref = fit_linear_regression_model( array, target_feat="ty_ref_straight_diff", features=["ty", "tx", "dSlope_fringe", "dSlope_fringe_abs"], # this list was found by using Lasso regularisation to drop useless features keep=[ "ty dSlope_fringe^2", "ty tx^2 dSlope_fringe_abs", "ty^3 dSlope_fringe_abs", "ty^3 tx^2 dSlope_fringe_abs", "ty tx dSlope_fringe", "ty tx^3 dSlope_fringe", ], degree=6, fit_intercept=False, ) model_cy, poly_features_cy = fit_linear_regression_model( array, target_feat="CY_ex", features=["ty", "tx", "dSlope_fringe", "dSlope_fringe_abs"], # this list was found by using Lasso regularisation to drop useless features keep=[ "ty dSlope_fringe^2", "ty dSlope_fringe_abs", "ty tx^2 dSlope_fringe_abs", "ty^3 dSlope_fringe_abs", "ty tx dSlope_fringe", ], degree=4, fit_intercept=False, ) model_y_match, poly_features_y_match = fit_linear_regression_model( array, target_feat="yDiffOut", features=[ "ty", "dSlope_xEndT", "dSlope_yEndT", ], keep=[ "ty dSlope_yEndT^2", "ty dSlope_xEndT^2", ], degree=3, fit_intercept=False, ) keep_y_match_precise = [ "dSlope_yEndT", "ty dSlope_xEndT_abs", "ty dSlope_yEndT_abs", "ty dSlope_yEndT^2", "ty dSlope_xEndT^2", "ty tx dSlope_xEndT", "tx^2 dSlope_yEndT", "ty tx^2 dSlope_xEndT_abs", "ty^3 tx dSlope_xEndT", ] model_y_match_precise, poly_features_y_match_precise = fit_linear_regression_model( array, "yDiffEndT", [ "ty", "tx", "dSlope_xEndT", "dSlope_yEndT", "dSlope_xEndT_abs", "dSlope_yEndT_abs", ], keep=keep_y_match_precise, degree=5, ) cpp_cx = parse_regression_coef_to_array(model_cx, poly_features_cx, "cxParams") cpp_dx = parse_regression_coef_to_array(model_dx, poly_features_dx, "dxParams") cpp_y_corr_layers = parse_regression_coef_to_array( model_y_corr_l, poly_features_y_corr_l, "yCorrParamsLayers", rows=rows, ) cpp_y_corr_ref = parse_regression_coef_to_array( model_y_corr_ref, poly_features_y_corr_ref, "yCorrParamsRef", ) cpp_ty_corr_ref = parse_regression_coef_to_array( model_ty_corr_ref, poly_features_ty_corr_ref, "tyCorrParamsRef", ) cpp_cy = parse_regression_coef_to_array(model_cy, poly_features_cy, "cyParams") cpp_y_match = parse_regression_coef_to_array( model_y_match, poly_features_y_match, "bendYParamsMatch", ) cpp_y_match_precise = parse_regression_coef_to_array( model_y_match_precise, poly_features_y_match_precise, "bendYParams", ) outpath = Path("parameterisations/result/track_model_params.hpp") outpath.parent.mkdir(parents=True, exist_ok=True) with open(outpath, "w") as result: result.writelines( cpp_cx + cpp_dx + cpp_y_corr_layers + cpp_y_corr_ref + cpp_ty_corr_ref + cpp_cy + cpp_y_match + cpp_y_match_precise, ) return outpath if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument( "--input-file", type=str, help="Path to the input file", required=False, ) parser.add_argument( "--tree-name", type=str, help="Path to the input file", required=False, ) args = parser.parse_args() args_dict = {arg: val for arg, val in vars(args).items() if val is not None} outfile = parameterise_track_model(**args_dict) try: import subprocess # run clang-format for nicer looking result subprocess.run( [ "clang-format", "-i", f"{outfile}", ], check=True, ) except: pass