def create_creator(fname=None, lname=None, email=None, organization=None): creator = libcombine.VCard() if lname: creator.setFamilyName(lname) if fname: creator.setGivenName(fname) if email: creator.setEmail(email) if organization: creator.setOrganization(organization) return creator
def create_combine_archive( yaml_file: str, filename: str, family_name: Optional[str] = None, given_name: Optional[str] = None, email: Optional[str] = None, organization: Optional[str] = None, ) -> None: """Create COMBINE archive (http://co.mbine.org/documents/archive) based on PEtab YAML file. Arguments: yaml_file: Path to PEtab YAML file family_name: Family name of archive creator given_name: Given name of archive creator email: E-mail address of archive creator organization: Organization of archive creator """ path_prefix = os.path.dirname(yaml_file) yaml_config = yaml.load_yaml(yaml_file) # function-level import, because module-level import interfered with # other SWIG interfaces try: import libcombine except ImportError: raise ImportError("To use PEtab's COMBINE functionality, libcombine " "(python-libcombine) must be installed.") def _add_file_metadata(location: str, description: str = ""): """Add metadata to the added file""" omex_description = libcombine.OmexDescription() omex_description.setAbout(location) omex_description.setDescription(description) omex_description.setCreated( libcombine.OmexDescription.getCurrentDateAndTime()) archive.addMetadata(location, omex_description) archive = libcombine.CombineArchive() # Add PEtab files and metadata archive.addFile(yaml_file, os.path.basename(yaml_file), libcombine.KnownFormats.lookupFormat("yaml"), True) _add_file_metadata(location=os.path.basename(yaml_file), description="PEtab YAML file") # Add parameter file(s) that describe a single parameter table. # Works for a single file name, or a list of file names. for parameter_subset_file in (list( np.array(yaml_config[PARAMETER_FILE]).flat)): archive.addFile(os.path.join(path_prefix, parameter_subset_file), parameter_subset_file, libcombine.KnownFormats.lookupFormat("tsv"), False) _add_file_metadata(location=parameter_subset_file, description="PEtab parameter file") for problem in yaml_config[PROBLEMS]: for sbml_file in problem[SBML_FILES]: archive.addFile(os.path.join(path_prefix, sbml_file), sbml_file, libcombine.KnownFormats.lookupFormat("sbml"), False) _add_file_metadata(location=sbml_file, description="SBML model") for field in [ MEASUREMENT_FILES, OBSERVABLE_FILES, VISUALIZATION_FILES, CONDITION_FILES ]: if field not in problem: continue for file in problem[field]: archive.addFile(os.path.join(path_prefix, file), file, libcombine.KnownFormats.lookupFormat("tsv"), False) desc = field.split("_")[0] _add_file_metadata(location=file, description=f"PEtab {desc} file") # Add archive metadata description = libcombine.OmexDescription() description.setAbout(".") description.setDescription("PEtab archive") description.setCreated(libcombine.OmexDescription.getCurrentDateAndTime()) # Add creator info creator = libcombine.VCard() if family_name: creator.setFamilyName(family_name) if given_name: creator.setGivenName(given_name) if email: creator.setEmail(email) if organization: creator.setOrganization(organization) description.addCreator(creator) archive.addMetadata(".", description) archive.writeToFile(filename)
def _addEntriesToArchive(omexPath, entries, workingDir, add_entries): """ :param archive: :param entries: :param workingDir: :return: """ omexPath = os.path.abspath(omexPath) print('omexPath:', omexPath) print('workingDir:', workingDir) if not os.path.exists(workingDir): raise IOError( "Working directory does not exist: {}".format(workingDir)) if add_entries is False: if os.path.exists(omexPath): # delete the old omex file warnings.warn( "Combine archive is overwritten: {}".format(omexPath)) os.remove(omexPath) archive = libcombine.CombineArchive() if add_entries is True: # use existing entries if os.path.exists(omexPath): # init archive from existing content if archive.initializeFromArchive(omexPath) is None: raise IOError("Combine Archive is invalid: ", omexPath) # timestamp time_now = libcombine.OmexDescription.getCurrentDateAndTime() print('*' * 80) for entry in entries: print(entry) location = entry.location path = os.path.join(workingDir, location) if not os.path.exists(path): raise IOError( "File does not exist at given location: {}".format(path)) archive.addFile(path, location, entry.format, entry.master) if entry.description or entry.creators: omex_d = libcombine.OmexDescription() omex_d.setAbout(location) omex_d.setCreated(time_now) if entry.description: omex_d.setDescription(entry.description) if entry.creators: for c in entry.creators: creator = libcombine.VCard() creator.setFamilyName(c.familyName) creator.setGivenName(c.givenName) creator.setEmail(c.email) creator.setOrganization(c.organization) omex_d.addCreator(creator) archive.addMetadata(location, omex_d) archive.writeToFile(omexPath) archive.cleanUp()
def create_omex(folder, omex_file, strict=True): """ Creates a combine archive from folder :param folder: :param omex_file: :param strict: strict creation, raises Errors instead of warnings :return: """ print('*' * 100) print('Create OMEX:') print('\t', folder) print('*' * 100) if not os.path.exists(folder): raise IOError("Input folder does not exist:", folder) # delete the old omex file if os.path.exists(omex_file): os.remove(omex_file) json_manifest = os.path.join(folder, 'manifest.json') # print(json_manifest) with open(json_manifest, "r") as f: json_entries = json.load(f) json_entries = json_entries['entries'] # pprint.pprint(json_entries) # ---------------------------------- # Create metadata file # ---------------------------------- # create the metadata file # <content format = "http://identifiers.org/combine.specifications/omex-metadata" location = "metadata.rdf" / > time_now = libcombine.OmexDescription.getCurrentDateAndTime() metadata_xml = [] for entry in json_entries: location = entry['location'] # add metadata for location description = entry.get("description", None) creators = entry.get("creators", None) if description or creators: # Create an omex description omex_d = libcombine.OmexDescription() omex_d.setAbout(location) omex_d.setCreated(time_now) if description: omex_d.setDescription(description) if creators: for c in creators: creator = libcombine.VCard() creator.setFamilyName(c.get("familyName", "")) creator.setGivenName(c.get("givenName", "")) creator.setEmail(c.get("email", "")) creator.setOrganization(c.get("organisation")) omex_d.addCreator(creator) metadata_xml.append(omex_d.toXML()) # store the metadata file # FIXME: bad hack for now, but seems to work contents = [(item.split("\n"))[2:-2] for item in metadata_xml] start_str = "<?xml version='1.0' encoding='UTF-8'?>\n" \ "<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:dcterms='http://purl.org/dc/terms/' xmlns:vCard='http://www.w3.org/2006/vcard/ns#'>" content_str = "\n".join(["\n".join(lines) for lines in contents]) end_str = "</rdf:RDF>" metadata_str = "\n".join([start_str, content_str, end_str]) f_metadata = os.path.join(folder, "metadata.rdf") with open(f_metadata, "w") as f: f.write(metadata_str) # ---------------------------------- # create manifest.xml # ---------------------------------- f_manifest = os.path.join(folder, "manifest.xml") with open(f_manifest, "w") as f: f.write("<omexManifest>\n") for entry in json_entries: location = entry['location'] path = os.path.join(folder, location) if not os.path.exists(path) and not path.endswith('manifest.xml'): msg = "File does not exist at given location: {}".format(path) if strict: raise IOError(msg) else: warnings.warn(msg) # add file to archive format = entry['format'] master = entry.get('master', False) # archive.addFile(path, location, format, master) f.write('<content location="{}" format="{}" master="{}"/>\n'.format(location, format, master)) f.write("</omexManifest>\n") # ---------------------------------- # create omex # ---------------------------------- zip_dir(folder, omex_file) print('Archive created:', omex_file)