docs: def train(self, X_feat, X_seq, y, id_vec=None, n_folds=10, use_stored_folds=None, n_cores=1,
                train_global_model=False):
          """Train the Concise model in cross-validation.
  
          Args:
              X_feat: See :py:func:`concise.Concise.train`
              X_seq: See :py:func:`concise.Concise.train`
              y: See :py:func:`concise.Concise.train`
              id_vec: List of character id's used to differentiate the trainig samples. Returned by :py:func:`concise.prepare_data`.
              n_folds (int): Number of CV-folds to use.
              use_stored_folds (chr or None): File path to a .json file containing the fold information (as returned by :py:func:`concise.ConciseCV.get_folds`). If None, the folds are generated.
              n_cores (int): Number of CPU cores used for training. If available, GPU is used for training and this argument is ignored.
              train_global_model (bool): In addition to training the model in cross-validation, should the global model be fitted (using all the samples from :code:`(X_feat, X_seq, y)`). 
          """
          # TODO: input check - dimensions
          self._use_stored_folds = use_stored_folds
          self._n_folds = n_folds
          self._n_rows = X_feat.shape[0]
  
      # TODO: - fix the get_cv_accuracy
      # save:
      # - each model
      # - each model's performance
      # - each model's predictions
      # - globally:
      #    - mean perfomance
      #    - sd performance
      #    - predictions
  
          self._kf = self._get_folds(self._n_rows, self._n_folds, self._use_stored_folds)
  
          cv_obj = {}
  
          if id_vec is None:
              id_vec = np.arange(1, self._n_rows + 1)
  
          best_val_acc_epoch_l = []
          for fold, train, test in self._kf:
              X_feat_train = X_feat[train]
              X_seq_train = X_seq[train]
              y_train = y[train]
  
              X_feat_test = X_feat[test]
              X_seq_test = X_seq[test]
              y_test = y[test]
              id_vec_test = id_vec[test]
              print(fold, "/", n_folds)
  
              # copy the object
              dc = copy.deepcopy(self._concise_model)
              dc.train(X_feat_train, X_seq_train, y_train,
                       X_feat_test, X_seq_test, y_test,
                       n_cores=n_cores
                       )
  
              dc._test(X_feat_test, X_seq_test, y_test, id_vec_test)
              cv_obj[fold] = dc
              best_val_acc_epoch_l.append(dc.get_accuracy()["best_val_acc_epoch"])
          self._cv_model = cv_obj
  
          # additionaly train the global model
          if train_global_model:
              dc = copy.deepcopy(self._concise_model)
  
              # overwrite n_epochs with the best average number of best epochs
              dc._param["n_epochs"] = int(np.array(best_val_acc_epoch_l).mean())
              print("tranining global model with n_epochs = " + str(dc._param["n_epochs"]))
  
              dc.train(X_feat, X_seq, y,
                       n_cores=n_cores
                       )
              dc._test(X_feat, X_seq, y, id_vec)
              self._concise_global_model = dc