# 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 import awkward as ak from pathlib import Path def parameterise_magnet_kink( input_file: str = "data/param_data_selected.root", tree_name: str = "Selected", per_layer=False, ) -> Path: """Function that calculates parameters for estimating the magnet kink z position. Args: input_file (str, optional): Defaults to "data/param_data_selected.root". tree_name (str, optional): Defaults to "Selected". per_layer (bool, optional): If true also calculates parameters per SciFi layer. Defaults to False. Returns: Path: Path to cpp code file. """ 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"] # the magnet kink position is the point of intersection of the track tagents array["z_mag_x_fringe"] = ( array["x"] - array["x_ref"] - array["tx"] * array["z"] + array["tx_ref"] * array["z_ref"] ) / array["dSlope_fringe"] array["dSlope_xEndT"] = array["tx_l11"] - array["tx"] array["dSlope_xEndT_abs"] = abs(array["dSlope_xEndT"]) array["x_EndT_abs"] = abs( array["x_l11"] + array["tx_l11"] * (9410.0 - array["z_l11"]), ) # the magnet kink position is the point of intersection of the track tagents array["z_mag_xEndT"] = ( array["x"] - array["x_l11"] - array["tx"] * array["z"] + array["tx_l11"] * array["z_l11"] ) / array["dSlope_xEndT"] if per_layer: layered_features = [f"x_diff_straight_l{layer}" for layer in range(12)] rows = [] for i, feat in enumerate(layered_features): scale = 3000 if "dSlope" not in feat: array[f"x_l{i}_rel"] = array[f"x_l{i}"] / scale array[f"x_diff_straight_l{i}"] = ( array[f"x_l{i}"] - array["x"] - array["tx"] * (array[f"z_l{i}"] - array["z"]) ) model, poly_features = fit_linear_regression_model( array, target_feat="z_mag_x_fringe", features=[ "tx", "ty", feat, ], keep=[ "tx^2", f"tx x_diff_straight_l{i}", "ty^2", f"x_diff_straight_l{i}^2", ], degree=2, fit_intercept=True, ) rows.append( "{" + str(model.intercept_) + "f," + ",".join([str(coef) + "f" for coef in model.coef_ if coef != 0.0]) + "}", ) cpp_decl = parse_regression_coef_to_array( model, poly_features, "zMagnetParamsLayers", rows=rows, ) # now fit model for the reference plane model_ref, poly_features_ref = fit_linear_regression_model( array, target_feat="z_mag_x_fringe", features=["tx", "ty", "dSlope_fringe"], keep=["tx^2", "tx dSlope_fringe", "ty^2", "dSlope_fringe^2"], degree=2, fit_intercept=True, ) cpp_ref = parse_regression_coef_to_array( model_ref, poly_features_ref, "zMagnetParamsRef", ) model_endt, poly_features_endt = fit_linear_regression_model( array, target_feat="z_mag_xEndT", features=["tx", "dSlope_xEndT", "dSlope_xEndT_abs", "x_EndT_abs"], keep=["tx^2", "dSlope_xEndT^2", "dSlope_xEndT_abs", "x_EndT_abs"], degree=2, fit_intercept=True, ) cpp_ref += parse_regression_coef_to_array( model_endt, poly_features_endt, "zMagnetParamsEndT", ) outpath = Path("parameterisations/result/z_mag_kink_params.hpp") outpath.parent.mkdir(parents=True, exist_ok=True) with open(outpath, "w") as result: result.writelines(cpp_decl + cpp_ref if per_layer else cpp_ref) 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_magnet_kink(**args_dict) try: import subprocess # run clang-format for nicer looking result subprocess.run( [ "clang-format", "-i", f"{outfile}", ], check=True, ) except: pass