code: def _store_words(self, words, line_xml, line_coords, ns) -> float:
      # page schema requires that word tags are directly after coords (and baseline, if present)
      line_coords_xml = line_xml.find("./ns:Coords", namespaces=ns)
      line_baseline_xml = line_xml.find("./ns:Baseline", namespaces=ns)
  
      if line_baseline_xml is not None:
          # if there is a baseline element, insert after it
          insert_index = line_xml.index(line_baseline_xml) + 1
      elif line_coords_xml is not None:
          # if there is a coords element, but no baseline element, insert after it
          insert_index = line_xml.index(line_coords_xml) + 1
      else:
          # otherwise, insert at the start
          insert_index = 0
  
      line_x, line_y, _, line_height = self._bounding_rect_from_points(
          line_coords
      )
  
      for word in words:
          if not word:
              # ignore empty words
              continue
  
          word_id = "w" + str(self._next_word_id)
  
          self._next_word_id += 1
  
          # find if we already have words with this id and overwrite them
          word_xml = line_xml.find(
              f'./ns:Word[@id="{word_id}"]', namespaces=ns
          )
          if word_xml is None:
              # no word with this id, create a new word element
              word_xml = self._make_subelement(
                  line_xml, "Word", attrib={"id": word_id}
              )
  
          coords_xml = word_xml.find("./ns:Coords", namespaces=ns)
          if coords_xml is None:
              coords_xml = self._make_subelement(word_xml, "Coords")
  
          word_text = ""
          word_confidence = 1
          glyph_counter = 0
  
          for glyph in word:
              word_text += glyph.chars[0].char
              word_confidence *= glyph.chars[0].probability
  
              self._store_glyph(
                  glyph,
                  word_id,
                  word_xml,
                  line_x,
                  line_y,
                  line_height,
                  glyph_counter,
                  ns,
              )
              glyph_counter += 1
  
          # check if a TextEquiv with this index already exists
  
          textequiv_xml = word_xml.find(
              f'./ns:TextEquiv[@index="{self.params.text_index}"]',
              namespaces=ns,
          )
          if textequiv_xml is None:
              textequiv_xml = self._make_subelement(
                  word_xml, "TextEquiv"
              )
              textequiv_xml.set("index", str(self.params.text_index))
  
          if self.params.output_confidences:
              textequiv_xml.set("conf", str(word_confidence))
  
          u_xml = textequiv_xml.find("./ns:Unicode", namespaces=ns)
          if u_xml is None:
              u_xml = self._make_subelement(textequiv_xml, "Unicode")
          u_xml.text = word_text
  
          word_x, word_y = word[0].global_start + line_x, line_y
          word_width, word_height = (
              word[-1].global_end - word[0].global_start,
              line_height,
          )
          coords_xml.set(
              "points",
              self._coords_for_rectangle(
                  word_x, word_y, word_width, word_height
              ),
          )
  
          line_xml.insert(insert_index, word_xml)
          insert_index += 1
  
imports: import os
  from copy import deepcopy
  from dataclasses import dataclass, field
  from random import shuffle
  import math
  import numpy
  from paiargparse import pai_dataclass, pai_meta
  from tfaip.data.pipeline.definitions import PipelineMode, INPUT_PROCESSOR, TARGETS_PROCESSOR
  from tqdm import tqdm
  from lxml import etree
  import cv2
  from typing import List, Generator, Optional, Iterable, Dict, Any, Tuple
  from enum import IntEnum
  from calamari_ocr.ocr.dataset.datareader.base import CalamariDataGenerator, CalamariDataGeneratorParams, InputSample, SampleMeta
  from calamari_ocr.utils import split_all_ext, filename, glob_all
  from calamari_ocr.ocr.predict.params import Prediction
  import logging
label_desc: Use image node_id 14 for calling the PageXMLReader obj's underlying member method code with example usage: obj._store_words(words, line_xml, line_coords, ns) without return types