code: def config_join_project_dir(config):
      """operations after the config been loaded."""
      if "data" not in config or "project_dir" not in config["data"]:
          return
      project_dir = config["data"]["project_dir"]
      file_key_paths = [
          ["data", "task", "preparer", "done_sign"],
          ["data", "task", "text_vocab"],
          ["data", "task", "label_vocab"],
          ["solver", "service", "model_path"],
          ["solver", "saver", "model_path"],
      ]
  
      for data_type in ["train", "eval", "infer"]:
          if isinstance(config["data"][data_type]["paths"], dict):
              for k in config["data"][data_type]["paths"]:
                  file_key_paths.append(["data", data_type, "paths", k])
          else:
              file_key_paths.append(["data", data_type, "paths"])
  
      if isinstance(config["solver"]["metrics"], dict):
          metric = config["solver"]["metrics"]
          if "target_file" in metric:
              file_key_paths.append(
                  ["solver", "metrics", "target_file"]
              )
          if "text_vocab" in metric:
              file_key_paths.append(["solver", "metrics", "text_vocab"])
          if "res_file" in metric:
              file_key_paths.append(["solver", "metrics", "res_file"])
          for j, cal in enumerate(metric["cals"]):
              if (
                  cal["arguments"] is not None
                  and "label_vocab_path" in cal["arguments"]
              ):
                  file_key_paths.append(
                      [
                          "solver",
                          "metrics",
                          "cals",
                          j,
                          "arguments",
                          "label_vocab_path",
                      ]
                  )
      else:
          for i, metric in enumerate(config["solver"]["metrics"]):
              for j, cal in enumerate(metric["cals"]):
                  if (
                      cal["arguments"] is not None
                      and "label_vocab_path" in cal["arguments"]
                  ):
                      file_key_paths.append(
                          [
                              "solver",
                              "metrics",
                              i,
                              "cals",
                              j,
                              "arguments",
                              "label_vocab_path",
                          ]
                      )
  
      if isinstance(config["solver"]["postproc"], list):
          for i, postproc in enumerate(config["solver"]["postproc"]):
              file_key_paths.append(
                  ["solver", "postproc", i, "res_file"]
              )
      else:
          file_key_paths.append(["solver", "postproc", "res_file"])
  
      for file_key_path in file_key_paths:
          config_join_project_path(project_dir, config, file_key_path)
  
file_path: delta/delta/utils/config.py
imports: from typing import List, Union
  import os
  import json
  import time
  from shutil import copyfile, SameFileError
  from pathlib import Path
  import yaml
  from absl import logging
label_desc: Use image node_id 3 for calling a global function with example usage: config_join_project_dir(config) without return types