docstr: Retrieves a sample from the dataset.
  
  Retrieves a sample from the dataset. This function, for the
  most part, is spent performing ad-hoc data augmentation and
  restoration. It recieves a DataSample object from the storage,
  and returns an almost-identical DataSample object that may
  have been augmented with /possibly/ (depending on augment_punct
  settings) PUNCT chopped.
  
  **Important Note**
  ------------------
  If you would like to load the data into a model, please convert
  this Dataset object into a DataLoader via self.to_loader(). Then,
  you can use the resulting object like any other PyTorch data
  loader. As masks are calculated ad-hoc given the batch, the samples
  returned from this object doesn't have the appropriate masking.
  
  Motivation
  ----------
  Why is this here? Every time you call next(iter(dataloader)), it calls
  this function. Therefore, if we augmented each sample on each iteration,
  the model will see dynamically generated augmentation.
  Furthermore, PyTorch dataloader handles shuffling natively.
  
  Parameters
  ----------
  key : int
      the integer ID to from which to retrieve the key.
  
  Returns
  -------
  DataSample
      The sample of data you requested, with augmentation.
docstr_tok: ["Retrieves","a","sample","from","the","dataset",".","Retrieves","a","sample","from","the","dataset",".","This","function",",","for","the","most","part",",","is","spent","performing","ad-hoc","data","augmentation","and","restoration",".","It","recieves","a","DataSample","object","from","the","storage",",","and","returns","an","almost-identical","DataSample","object","that","may","have","been","augmented","with","\/possibly\/","(","depending","on","augment_punct","settings",")","PUNCT","chopped",".","*","*","Important","Note","*","*","--","--","--","--","--","--","--","--","--","If","you","would","like","to","load","the","data","into","a","model",",","please","convert","this","Dataset","object","into","a","DataLoader","via","self.to_loader","(",")",".","Then",",","you","can","use","the","resulting","object","like","any","other","PyTorch","data","loader",".","As","masks","are","calculated","ad-hoc","given","the","batch",",","the","samples","returned","from","this","object","does","n't","have","the","appropriate","masking",".","Motivation","--","--","--","--","--","Why","is","this","here","?","Every","time","you","call","next","(","iter","(","dataloader",")",")",",","it","calls","this","function",".","Therefore",",","if","we","augmented","each","sample","on","each","iteration",",","the","model","will","see","dynamically","generated","augmentation",".","Furthermore",",","PyTorch","dataloader","handles","shuffling","natively",".","Parameters","--","--","--","--","--","key",":","int","the","integer","ID","to","from","which","to","retrieve","the","key",".","Returns","--","--","--","-","DataSample","The","sample","of","data","you","requested",",","with","augmentation","."]
code: def __getitem__(self, key):
      """Retrieves a sample from the dataset.
  
      Retrieves a sample from the dataset. This function, for the
      most part, is spent performing ad-hoc data augmentation and
      restoration. It recieves a DataSample object from the storage,
      and returns an almost-identical DataSample object that may
      have been augmented with /possibly/ (depending on augment_punct
      settings) PUNCT chopped.
  
      **Important Note**
      ------------------
      If you would like to load the data into a model, please convert
      this Dataset object into a DataLoader via self.to_loader(). Then,
      you can use the resulting object like any other PyTorch data
      loader. As masks are calculated ad-hoc given the batch, the samples
      returned from this object doesn't have the appropriate masking.
  
      Motivation
      ----------
      Why is this here? Every time you call next(iter(dataloader)), it calls
      this function. Therefore, if we augmented each sample on each iteration,
      the model will see dynamically generated augmentation.
      Furthermore, PyTorch dataloader handles shuffling natively.
  
      Parameters
      ----------
      key : int
          the integer ID to from which to retrieve the key.
  
      Returns
      -------
      DataSample
          The sample of data you requested, with augmentation.
      """
      # get a sample of the input data
      sample = self.data[key]
  
      # some data augmentation requires constructing a mask based on upos.
      # For instance, sometimes we'd like to mask out ending sentence punctuation.
      # We copy the other items here so that any edits made because
      # of the mask don't clobber the version owned by the Dataset
      # convert to tensors
      # TODO: only store single lists per data entry?
      words = torch.tensor(sample.word[0])
      # convert the rest to tensors
      upos = torch.tensor(sample.upos[0]) if self.has_upos else None
      xpos = torch.tensor(sample.xpos[0]) if self.has_xpos else None
      ufeats = torch.tensor(sample.feats[0]) if self.has_feats else None
      pretrained = torch.tensor(sample.pretrain[0])
  
      # and deal with char & raw_text
      char = sample.char[0]
      raw_text = sample.text
  
      # some data augmentation requires constructing a mask based on
      # which upos. For instance, sometimes we'd like to mask out ending
      # sentence punctuation. The mask is True if we want to remove the element
      if self.has_upos and upos is not None and not self.eval:
          # perform actual masking
          mask = self.__mask(upos)
      else:
          # dummy mask that's all false
          mask = None
      if mask is not None:
          mask_index = mask.nonzero()
  
          # mask out the elements that we need to mask out
          for mask in mask_index:
              mask = mask.item()
              words[mask] = PAD_ID
              if upos is not None:
                  upos[mask] = PAD_ID
              if xpos is not None:
                  # TODO: test the multi-dimension xpos
                  xpos[mask, ...] = PAD_ID
              if ufeats is not None:
                  ufeats[mask, ...] = PAD_ID
              pretrained[mask] = PAD_ID
              char = char[:mask] + char[mask + 1 :]
              raw_text = raw_text[:mask] + raw_text[mask + 1 :]
  
      # get each character from the input sentnece
      # chars = [w for sent in char for w in sent]
  
      return (
          DataSample(
              words, char, upos, xpos, ufeats, pretrained, raw_text
          ),
          key,
      )
  
imports: import random
  import logging
  import copy
  import torch
  from collections import namedtuple
  from torch.utils.data import DataLoader
  from torch.nn.utils.rnn import pad_sequence
  from stanza.models.common.bert_embedding import filter_data
  from stanza.models.common.data import map_to_ids, get_long_tensor, get_float_tensor, sort_all
  from stanza.models.common.vocab import PAD_ID, VOCAB_PREFIX, CharVocab
  from stanza.models.pos.vocab import WordVocab, XPOSVocab, FeatureVocab, MultiVocab
  from stanza.models.pos.xpos_vocab_factory import xpos_vocab_factory
  from stanza.models.common.doc import *
label_desc: Use image node_id 6 for calling the Dataset obj's underlying member method code with example usage: obj.__getitem__(key) and returns: DataSample,  key