<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def eval_mus_track( track, user_estimates, output_dir=None, mode='v4', win=1.0, hop=1.0 ):
 """Compute all bss_eval metrics for the musdb track and estimated signals, given by a `user_estimates` dict. Parameters track : Track musdb track object loaded using musdb estimated_sources : Dict dictionary, containing the user estimates as np.arrays. output_dir : str path to output directory used to save evaluation results. Defaults to `None`, meaning no evaluation files will be saved. mode : str bsseval version number. Defaults to 'v4'. win : int window size in Returns ------- scores : EvalStore scores object that holds the framewise and global evaluation scores. """


    audio_estimates = []
    audio_reference = []

    # make sure to always build the list in the same order
    # therefore track.targets is an OrderedDict
    eval_targets = []  # save the list of target names to be evaluated
    for key, target in list(track.targets.items()):
        try:
            # try to fetch the audio from the user_results of a given key
            user_estimates[key]
        except KeyError:
            # ignore wrong key and continue
            continue

        # append this target name to the list of target to evaluate
        eval_targets.append(key)

    data = EvalStore(win=win, hop=hop)

    # check if vocals and accompaniment is among the targets
    has_acc = all(x in eval_targets for x in ['vocals', 'accompaniment'])
    if has_acc:
        # remove accompaniment from list of targets, because
        # the voc/acc scenario will be evaluated separately
        eval_targets.remove('accompaniment')

    if len(eval_targets) >= 2:
        # compute evaluation of remaining targets
        for target in eval_targets:
            audio_estimates.append(user_estimates[target])
            audio_reference.append(track.targets[target].audio)

        SDR, ISR, SIR, SAR = evaluate(
            audio_reference,
            audio_estimates,
            win=int(win*track.rate),
            hop=int(hop*track.rate),
            mode=mode
        )

        # iterate over all evaluation results except for vocals
        for i, target in enumerate(eval_targets):
            if target == 'vocals' and has_acc:
                continue

            values = {
                "SDR": SDR[i].tolist(),
                "SIR": SIR[i].tolist(),
                "ISR": ISR[i].tolist(),
                "SAR": SAR[i].tolist()
            }

            data.add_target(
                target_name=target,
                values=values
            )

    # add vocal accompaniment targets later
    if has_acc:
        # add vocals and accompaniments as a separate scenario
        eval_targets = ['vocals', 'accompaniment']

        audio_estimates = []
        audio_reference = []

        for target in eval_targets:
            audio_estimates.append(user_estimates[target])
            audio_reference.append(track.targets[target].audio)

        SDR, ISR, SIR, SAR = evaluate(
            audio_reference,
            audio_estimates,
            win=int(win*track.rate),
            hop=int(hop*track.rate),
            mode=mode
        )

        # iterate over all targets
        for i, target in enumerate(eval_targets):
            values = {
                "SDR": SDR[i].tolist(),
                "SIR": SIR[i].tolist(),
                "ISR": ISR[i].tolist(),
                "SAR": SAR[i].tolist()
            }

            data.add_target(
                target_name=target,
                values=values
            )

    if output_dir:
        # validate against the schema
        data.validate()

        try:
            subset_path = op.join(
                output_dir,
                track.subset
            )

            if not op.exists(subset_path):
                os.makedirs(subset_path)

            with open(
                op.join(subset_path, track.name) + '.json', 'w+'
            ) as f:
                f.write(data.json)

        except (IOError):
            pass

    return data