code: def process_umls_training_dataset(
      data_path,
      train_save_name,
      val_save_name,
      max_pairs,
      train_split,
      headers,
  ):
      """
      Generates and saves UMLS self alignment pretraining train and validation data. Takes the raw .RRF UMLS
      data file and creates different pair combinations for entities with the same CUI. Each row in the output
      will be formatted as 'CUI EntitySynonym1 EntitySynonym2' with each item in a row separated by tabs.
      Saves two .tsv output files, one for the train split and one for the validation split.
      Only data marked as English is added to the train and val splits.
  
      Arguments:
          data_path (str): path to MRCONSO.RRF UMLS data file
          train_save_name (str): path to where training data will be saved
          val_save_name (str): path to where validation data will be saved
          max_pairs (int): max number of pairs for any one CUI added to the train
                     or validation splits
          train_split (float): precentage of raw data to be added to train set split
          headers (list): column lables within MRCONSO.RRF
      """
  
      print("Loading training data file...")
      df = pd.read_table(
          data_path, names=headers, index_col=False, delimiter="|"
      )
      train_file = open(train_save_name, "w")
      val_file = open(val_save_name, "w")
  
      cui = df["CUI"].iloc[0]
      names = []
      random.seed(2021)
  
      for idx in tqdm(range(len(df))):
          # Address incorrectly formatted data
          if (
              type(df["STR"].iloc[idx]) != str
              or "|" in df["STR"].iloc[idx]
          ):
              continue
  
          # Collect all english concept strings matching the current CUI
          if (
              df["CUI"].iloc[idx] == cui
              and df["LAT"].iloc[idx] == "ENG"
          ):
              concept_string = df["STR"].iloc[idx]
              names.append(concept_string)
  
          else:
              # Pair off concept synonyms to make training and val sets
              pairs = list(itertools.combinations(names, 2))
  
              if len(pairs) == 0:
                  # Not enough concepts gathered to make a pair
                  cui = df["CUI"].iloc[idx]
                  names = [df["STR"].iloc[idx]]
                  continue
  
              # Removing leading C to convert label string to int
              cui = int(cui[1:])
              random.shuffle(pairs)
  
              # Keep up to max pairs number pairs for any one concept
              for pair in pairs[:max_pairs]:
                  # Want concepts in train and val splits to be randomly selected and mutually exclusive
                  add_to_train = random.random()
  
                  if add_to_train <= train_split:
                      train_file.write(f"{cui}\t{pair[0]}\t{pair[1]}\n")
                  else:
                      val_file.write(f"{cui}\t{pair[0]}\t{pair[1]}\n")
  
              # Switch to next concept
              cui = df["CUI"].iloc[idx]
              names = [df["STR"].iloc[idx]]
  
      train_file.close()
      val_file.close()
      print("Finished making training and validation data")
  
file_path: NeMo/examples/nlp/entity_linking/data/umls_dataset_processing.py
imports: import itertools
  import pickle
  import random
  from argparse import ArgumentParser
  import pandas
  from omegaconf import OmegaConf
  from tqdm import tqdm
label_desc: Use image node_id 1 for calling a global function with example usage: process_umls_training_dataset(data_path, train_save_name, val_save_name, max_pairs, train_split, headers) without return types