# flake8: noqa
from Moore import options, run_reconstruction
from RecoConf.hlt2_tracking import (
    make_hlt2_tracks,
    get_default_out_track_types_for_light_reco,
    convert_tracks_to_v3_from_v1,
    get_global_ut_hits_tool,
)
from RecoConf.hlt1_tracking import make_all_pvs
from RecoConf.event_filters import require_gec
from RecoConf.mc_checking import (
    get_track_checkers,
    get_fitted_tracks_checkers,
    check_tracking_efficiency,
    make_links_lhcbids_mcparticles_tracking_system,
    make_links_tracks_mcparticles,
    get_mc_categories,
    get_hit_type_mask,
)
from RecoConf.calorimeter_reconstruction import (
    make_photons_and_electrons,
    make_clusters,
    make_acceptance,
    make_track_cluster_matching,
    make_digits,
    make_track_electron_and_brem_matching,
    make_trackbased_eshower,
)
from Moore.config import Reconstruction
from PyConf.Algorithms import (
    PrFilterTracks2CaloClusters,
    PrMatchNNv3,
    PrFilterTracks2ElectronMatch,
    PrFilterTracks2ElectronShower,
    fromPrMatchTracksV1Tracks,
    fromV3TrackV1Track,
    PrTrackAssociator,
)
from PyConf.Tools import PrMCDebugForwardTool, PrMCDebugMatchToolNN
from PyConf.application import make_data_with_FetchDataFromFile
from RecoConf.data_from_file import mc_unpackers
import Functors as F
import glob


decay = "testJpsi"

options.evt_max = -1

# options.ntuple_file = f"/work/cetin/LHCb/reco_tuner/data_matching/NewParams/calo_data_{decay}_NewParams.root"  # _dll_NegThree_mlp_NullSix.root"

# options.ntuple_file = f"/work/cetin/LHCb/reco_tuner/efficiencies/electrons/calo_selected_effs_{decay}_VeloEcalSelection.root"

options.ntuple_file = f"data/calo_selected_effs_{decay}.root"


if decay == "B":
    options.input_files = glob.glob("/auto/data/guenther/Bd_Kstee/*.xdigi")
elif decay == "BJpsi":
    options.input_files = glob.glob("/auto/data/guenther/Bd_JpsiKst_ee/*.xdigi")
elif decay == "D":
    options.input_files = glob.glob("/auto/data/guenther/Dst_D0ee/*.xdigi")
elif decay == "testJpsi":
    options.input_files = [
        "/auto/data/guenther/Bd_JpsiKst_ee/00143565_00000009_1.xdigi",
        "/auto/data/guenther/Bd_JpsiKst_ee/00143565_00000059_1.xdigi",
        "/auto/data/guenther/Bd_JpsiKst_ee/00143565_00000020_1.xdigi",
    ]
elif decay == "test":
    options.input_files = [
        "/auto/data/guenther/Bd_JpsiKst_ee/00143565_00000009_1.xdigi"
    ]

options.input_type = "ROOT"

options.dddb_tag = "dddb-20210617"
options.conddb_tag = "sim-20210617-vc-md100"
options.simulation = True


def standalone_hlt2_fastest_reco():
    links_to_hits = make_links_lhcbids_mcparticles_tracking_system()
    hlt2_tracks = make_hlt2_tracks(light_reco=True, fast_reco=False, use_pr_kf=True)

    digisEcal = make_digits(calo_raw_bank=False)["digitsEcal"]
    tracks_v3, trackrels = convert_tracks_to_v3_from_v1(
        hlt2_tracks["Seed"]["v1"],
        track_types=["Ttrack"],
    )
    # track acceptances
    tracks_incalo = make_acceptance(tracks_v3)
    eshower = make_trackbased_eshower(tracks_incalo, digisEcal)

    matched_seeds = {}
    # should be best; shape of shower etc; E/p statt chi2; DLL even better? GET(1)
    # Cut=F.FILTER(F.ALL)).Output
    matched_seeds["v3"] = PrFilterTracks2ElectronShower(
        Relation=eshower["Ttrack"],
        # Cut=F.FILTER(((F.GET(1) @ F.WEIGHT) > -3)),  # | ((F.GET(0) @ F.WEIGHT) > 0.7)),
        Cut=F.FILTER(((F.GET(0) @ F.WEIGHT) > 0.7) | ((F.GET(1) @ F.WEIGHT) > -2)),
    ).Output

    matched_seeds["v1"] = fromV3TrackV1Track(
        InputTracks=matched_seeds["v3"]
    ).OutputTracks

    links_to_velo_tracks = PrTrackAssociator(
        SingleContainer=hlt2_tracks["Velo"]["v1"],
        LinkerLocationID=links_to_hits,
        MCParticleLocation=mc_unpackers()["MCParticles"],
        MCVerticesInput=mc_unpackers()["MCVertices"],
    ).OutputLocation

    links_to_seed_tracks = PrTrackAssociator(
        SingleContainer=matched_seeds["v1"],
        LinkerLocationID=links_to_hits,
        MCParticleLocation=mc_unpackers()["MCParticles"],
        MCVerticesInput=mc_unpackers()["MCVertices"],
    ).OutputLocation

    matching_params = dict(
        MaxdDist=0.1,
        MinMatchNN=0.25,
        # PerfectTSelection=1.0,
        PerfectVeloSelection=1.0,
        MinZMag=5100,
        MaxZMag=5700,
        matchDebugOutput=0.0,
    )
    match_tracks = {}
    match_tracks["Pr"] = PrMatchNNv3(
        VeloInput=hlt2_tracks["Velo"]["Pr"],
        SeedInput=matched_seeds["v3"],
        MatchDebugToolName=PrMCDebugMatchToolNN(
            VeloTracks=hlt2_tracks["Velo"]["v1"],
            SeedTracks=matched_seeds["v1"],
            VeloTrackLinks=links_to_velo_tracks,
            SeedTrackLinks=links_to_seed_tracks,
            TrackInfo=make_data_with_FetchDataFromFile(
                "/Event/MC/TrackInfo", "LHCb::MCProperty"
            ),
            MCParticles=mc_unpackers()["MCParticles"],
        ),
        AddUTHitsToolName=get_global_ut_hits_tool(),
        **matching_params,
    ).MatchOutput

    match_tracks["v1"] = fromPrMatchTracksV1Tracks(
        InputTracksLocation=match_tracks["Pr"],
        VeloTracksLocation=hlt2_tracks["Velo"]["v1"],
        SeedTracksLocation=matched_seeds["v1"],
    ).OutputTracksLocation

    data = []
    types_and_locations_for_checkers = {
        "Forward": hlt2_tracks["Forward"],
        "Match": match_tracks,
        # "Seed": hlt2_tracks["Seed"],
    }
    data += get_track_checkers(types_and_locations_for_checkers)
    # data += get_fitted_tracks_checkers(best_tracks)

    return Reconstruction("hlt2_reco", data, [require_gec()])


run_reconstruction(options, standalone_hlt2_fastest_reco)
