docs: def save(self, models_dir, model_names_to_write=None, write_metadata=True):
          """
          Serialize the predictor to a directory on disk. If the directory does
          not exist it will be created.
          
          The serialization format consists of a file called "manifest.csv" with
          the configurations of each Class1NeuralNetwork, along with per-network
          files giving the model weights. If there are pan-allele predictors in
          the ensemble, the allele sequences are also stored in the
          directory. There is also a small file "index.txt" with basic metadata:
          when the models were trained, by whom, on what host.
          
          Parameters
          ----------
          models_dir : string
              Path to directory
              
          model_names_to_write : list of string, optional
              Only write the weights for the specified models. Useful for
              incremental updates during training.
  
          write_metadata : boolean, optional
              Whether to write optional metadata
          """
          num_models = len(self.class1_pan_allele_models) + sum(
              len(v) for v in self.allele_to_allele_specific_models.values())
          assert len(self.manifest_df) == num_models, (
              "Manifest seems out of sync with models: %d vs %d entries" % (
                  len(self.manifest_df), num_models))
  
          if model_names_to_write is None:
              # Write all models
              model_names_to_write = self.manifest_df.model_name.values
  
          if not exists(models_dir):
              mkdir(models_dir)
  
          sub_manifest_df = self.manifest_df.ix[
              self.manifest_df.model_name.isin(model_names_to_write)
          ]
  
          for (_, row) in sub_manifest_df.iterrows():
              weights_path = self.weights_path(models_dir, row.model_name)
              Class1AffinityPredictor.save_weights(
                  row.model.get_weights(), weights_path)
              logging.info("Wrote: %s" % weights_path)
  
          write_manifest_df = self.manifest_df[[
              c for c in self.manifest_df.columns if c != "model"
          ]]
          manifest_path = join(models_dir, "manifest.csv")
          write_manifest_df.to_csv(manifest_path, index=False)
          logging.info("Wrote: %s" % manifest_path)
  
          if write_metadata:
              # Write "info.txt"
              info_path = join(models_dir, "info.txt")
              rows = [
                  ("trained on", time.asctime()),
                  ("package   ", "mhcflurry %s" % __version__),
                  ("hostname  ", gethostname()),
                  ("user      ", getuser()),
              ]
              pandas.DataFrame(rows).to_csv(
                  info_path, sep="\t", header=False, index=False)
  
              if self.metadata_dataframes:
                  for (name, df) in self.metadata_dataframes.items():
                      metadata_df_path = join(models_dir, "%s.csv.bz2" % name)
                      df.to_csv(metadata_df_path, index=False, compression="bz2")
  
          if self.allele_to_fixed_length_sequence is not None:
              allele_to_sequence_df = pandas.DataFrame(
                  list(self.allele_to_fixed_length_sequence.items()),
                  columns=['allele', 'sequence']
              )
              allele_to_sequence_df.to_csv(
                  join(models_dir, "allele_sequences.csv"), index=False)
              logging.info("Wrote: %s" % join(models_dir, "allele_sequences.csv"))
  
          if self.allele_to_percent_rank_transform:
              percent_ranks_df = None
              for (allele, transform) in self.allele_to_percent_rank_transform.items():
                  series = transform.to_series()
                  if percent_ranks_df is None:
                      percent_ranks_df = pandas.DataFrame(index=series.index)
                  assert_equal(series.index.values, percent_ranks_df.index.values)
                  percent_ranks_df[allele] = series
              percent_ranks_path = join(models_dir, "percent_ranks.csv")
              percent_ranks_df.to_csv(
                  percent_ranks_path,
                  index=True,
                  index_label="bin")
              logging.info("Wrote: %s" % percent_ranks_path)