docs: def make_split(self, split_name, val_indices=None, train_pct=0.8, field_name=None):
          """ Splits the dataset into train and test according
          to the given attribute.
          The split is saved with the dataset for future access.
  
          Parameters
          ----------
          split_name : str
              name of the split (for future accesses)
          val_indices : 
              indices of the validation datapoints (overrides other variables if not None) 
          train_pct : float
              percent of data to use for training
          field_name : str
              name of the field to use in splitting (None for raw indices)
  
          Returns
          -------
          :obj:`numpy.ndarray`
              array of training indices in the global dataset
          :obj:`numpy.ndarray`
              array of validation indices in the global dataset
          """
          # check train percentage
          if train_pct < 0 or train_pct > 1:
              raise ValueError('Train pct must be a float between 0 and 1')
  
          # check existence
          if self.has_split(split_name):
              raise ValueError('Cannot create split %s - it already exists! To overwrite, delete split with TensorDataset.delete_split(split_name)' %(split_name))
  
          # perform splitting
          if val_indices is not None:
              all_indices = np.arange(self.num_datapoints)
              train_indices = np.setdiff1d(all_indices, val_indices)
          elif field_name is None:
              # split on indices
              indices = np.arange(self.num_datapoints)
              num_train = int(train_pct * self.num_datapoints)
              np.random.shuffle(indices)
              train_indices = indices[:num_train]
              val_indices = indices[num_train:]
              field_name = 'index'
          elif field_name == 'split':
              # split on binary values
              train_indices = []
              val_indices = []
              for i in range(self.num_datapoints):
                  datapoint = self.datapoint(i, field_names=['split'])
                  split = datapoint['split']
                  if split == TRAIN_ID:
                      train_indices.append(i)
                  else:
                      val_indices.append(i)
              train_indices = np.array(train_indices)
              val_indices = np.array(val_indices)
          else:
              # split on field name
  
              # check valid field
              if field_name not in self.config['fields'].keys():
                  raise ValueError('Field %d not in dataset!' %(field_name))
              if 'height' in self.config['fields'][field_name].keys():
                  raise ValueError('Can only split on scalar fields!')
  
              # find unique values
              values = []
              for i in range(self.num_datapoints):
                  datapoint = self.datapoint(i, field_names=[field_name])
                  values.append(datapoint[field_name])
              unique_values = np.unique(values)
              num_unique = unique_values.shape[0]
              num_train = int(train_pct * num_unique)
  
              # split
              np.random.shuffle(unique_values)
              train_values = unique_values[:num_train]
              val_values = unique_values[num_train:]
  
              # aggregate indices
              train_indices = []
              val_indices = []
              for i in range(self.num_datatpoints):
                  datapoint = self.datapoint(i, field_names=[field_name])
                  if datapoint[field_name] in train_values:
                      train_indices.append(i)
                  else:
                      val_indices.append(i)
              train_indices = np.array(train_indices)
              val_indices = np.array(val_indices)                    
                  
          # sort indices
          train_indices.sort()
          val_indices.sort()
  
          # save to disk
          if not os.path.exists(self.split_dir):
              os.mkdir(self.split_dir)
          split_dir = os.path.join(self.split_dir, split_name)
          os.mkdir(split_dir)
          train_filename = self.train_indices_filename(split_name)
          val_filename = self.val_indices_filename(split_name)        
          np.savez_compressed(train_filename, train_indices)
          np.savez_compressed(val_filename, val_indices)
          metadata_filename = self.split_metadata_filename(split_name)
          metadata = {
              'field_name': field_name,
              'train_pct': train_pct
          }
          json.dump(metadata, open(metadata_filename, 'w'),
                    indent=JSON_INDENT,
                    sort_keys=True)
          return train_indices, val_indices