def save(self, models_dir, model_names_to_write=None, write_metadata=True):
num_models = len(self.class1_pan_allele_models) + sum(<EOL>len(v) for v in self.allele_to_allele_specific_models.values())<EOL>assert len(self.manifest_df) == num_models, (<EOL>"<STR_LIT>" % (<EOL>len(self.manifest_df), num_models))<EOL>if model_names_to_write is None:<EOL><INDENT>model_names_to_write = self.manifest_df.model_name.values<EOL><DEDENT>if not exists(models_dir):<EOL><INDENT>mkdir(models_dir)<EOL><DEDENT>sub_manifest_df = self.manifest_df.ix[<EOL>self.manifest_df.model_name.isin(model_names_to_write)<EOL>]<EOL>for (_, row) in sub_manifest_df.iterrows():<EOL><INDENT>weights_path = self.weights_path(models_dir, row.model_name)<EOL>Class1AffinityPredictor.save_weights(<EOL>row.model.get_weights(), weights_path)<EOL>logging.info("<STR_LIT>" % weights_path)<EOL><DEDENT>write_manifest_df = self.manifest_df[[<EOL>c for c in self.manifest_df.columns if c != "<STR_LIT>"<EOL>]]<EOL>manifest_path = join(models_dir, "<STR_LIT>")<EOL>write_manifest_df.to_csv(manifest_path, index=False)<EOL>logging.info("<STR_LIT>" % manifest_path)<EOL>if write_metadata:<EOL><INDENT>info_path = join(models_dir, "<STR_LIT>")<EOL>rows = [<EOL>("<STR_LIT>", time.asctime()),<EOL>("<STR_LIT>", "<STR_LIT>" % __version__),<EOL>("<STR_LIT>", gethostname()),<EOL>("<STR_LIT>", getuser()),<EOL>]<EOL>pandas.DataFrame(rows).to_csv(<EOL>info_path, sep="<STR_LIT:\t>", header=False, index=False)<EOL>if self.metadata_dataframes:<EOL><INDENT>for (name, df) in self.metadata_dataframes.items():<EOL><INDENT>metadata_df_path = join(models_dir, "<STR_LIT>" % name)<EOL>df.to_csv(metadata_df_path, index=False, compression="<STR_LIT>")<EOL><DEDENT><DEDENT><DEDENT>if self.allele_to_fixed_length_sequence is not None:<EOL><INDENT>allele_to_sequence_df = pandas.DataFrame(<EOL>list(self.allele_to_fixed_length_sequence.items()),<EOL>columns=['<STR_LIT>', '<STR_LIT>']<EOL>)<EOL>allele_to_sequence_df.to_csv(<EOL>join(models_dir, "<STR_LIT>"), index=False)<EOL>logging.info("<STR_LIT>" % join(models_dir, "<STR_LIT>"))<EOL><DEDENT>if self.allele_to_percent_rank_transform:<EOL><INDENT>percent_ranks_df = None<EOL>for (allele, transform) in self.allele_to_percent_rank_transform.items():<EOL><INDENT>series = transform.to_series()<EOL>if percent_ranks_df is None:<EOL><INDENT>percent_ranks_df = pandas.DataFrame(index=series.index)<EOL><DEDENT>assert_equal(series.index.values, percent_ranks_df.index.values)<EOL>percent_ranks_df[allele] = series<EOL><DEDENT>percent_ranks_path = join(models_dir, "<STR_LIT>")<EOL>percent_ranks_df.to_csv(<EOL>percent_ranks_path,<EOL>index=True,<EOL>index_label="<STR_LIT>")<EOL>logging.info("<STR_LIT>" % percent_ranks_path)<EOL><DEDENT>
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