Example #1
0
def make_schema_collection_label(
    bundle_db: BundleDB,
    info: Citation_Information,
    collection_lidvid: str,
    bundle_lidvid: str,
    verify: bool,
    mod_date: str,
) -> bytes:
    """
    Create the label text for the schema collection having this LIDVID using
    the bundle database.  If verify is True, verify the label against
    its XML and Schematron schemas.  Raise an exception if either
    fails.
    """
    # TODO this is sloppy; is there a better way?
    products = bundle_db.get_schema_products()
    record_count = len(products)
    if record_count <= 0:
        raise ValueError(f"{collection_lidvid} has no schema products.")

    collection_lid = lidvid_to_lid(collection_lidvid)
    collection_vid = lidvid_to_vid(collection_lidvid)
    collection: Collection = bundle_db.get_collection(collection_lidvid)

    proposal_id = bundle_db.get_bundle(bundle_lidvid).proposal_id
    instruments = ",".join(bundle_db.get_instruments_of_the_bundle()).upper()
    title: NodeBuilder = make_schema_collection_title(
        {
            "instrument": instruments,
            "proposal_id": str(proposal_id),
        }
    )

    inventory_name = get_collection_inventory_name(bundle_db, collection_lidvid)

    try:
        label = (
            make_label(
                {
                    "collection_lid": collection_lid,
                    "collection_vid": collection_vid,
                    "record_count": record_count,
                    "title": title,
                    "mod_date": mod_date,
                    "proposal_id": str(proposal_id),
                    "Citation_Information": make_citation_information(info),
                    "inventory_name": inventory_name,
                    "Context_Area": combine_nodes_into_fragment([]),
                    "Reference_List": combine_nodes_into_fragment([]),
                    "collection_type": "Schema",
                }
            )
            .toxml()
            .encode()
        )
    except Exception as e:
        raise LabelError(collection_lidvid) from e

    return pretty_and_verify(label, verify)
Example #2
0
def make_document_collection_inventory(bundle_db: BundleDB,
                                       collection_lidvid: str) -> bytes:
    """
    Create the inventory text for the collection having this LIDVID
    using the bundle database.
    """
    products = bundle_db.get_collection_products(collection_lidvid)
    inventory_lines: List[str] = [
        f"P,{product.lidvid}\r\n" for product in products
    ]
    # Include handbooks in the document collection csv
    inst_list = bundle_db.get_instruments_of_the_bundle()
    for inst in inst_list:
        data_handbook_lid = f"S,urn:nasa:pds:hst-support:document:{inst}-dhb\r\n"
        inst_handbook_lid = f"S,urn:nasa:pds:hst-support:document:{inst}-ihb\r\n"
        inventory_lines.append(data_handbook_lid)
        inventory_lines.append(inst_handbook_lid)
    res: str = "".join(inventory_lines)
    return res.encode()
Example #3
0
def make_bundle_label(
    bundle_db: BundleDB,
    bundle_lidvid: str,
    info: Citation_Information,
    verify: bool,
    use_mod_date_for_testing: bool = False,
) -> bytes:
    """
    Create the label text for the bundle in the bundle database using
    the database connection.  If verify is True, verify the label
    against its XML and Schematron schemas.  Raise an exception if
    either fails.
    """
    bundle = bundle_db.get_bundle(bundle_lidvid)
    proposal_id = bundle.proposal_id

    def get_ref_type(collection: Collection) -> str:
        ref_type = switch_on_collection_subtype(
            collection,
            "bundle_has_context_collection",
            "bundle_has_document_collection",
            "bundle_has_schema_collection",
            "bundle_has_other_collection",
        )

        if ref_type == "bundle_has_other_collection":
            collection_type = cast(OtherCollection, collection).prefix
            ref_type = f"bundle_has_{collection_type}_collection"

        return ref_type

    reduced_collections = [
        make_bundle_entry_member({
            "collection_lidvid": collection.lidvid,
            "ref_type": get_ref_type(collection),
        }) for collection in bundle_db.get_bundle_collections(bundle.lidvid)
    ]

    # Get the bundle title from part of CitationInformation description
    title = (info.title + ", HST Cycle " + str(info.cycle) + " Program " +
             str(info.propno) + ", " + info.publication_year + ".")

    # Get the list of target identifications nodes for the collection
    target_identifications = bundle_db.get_all_target_identification()
    target_identification_nodes: List[NodeBuilder] = []
    target_identification_nodes = create_target_identification_nodes(
        bundle_db, target_identifications, "bundle")

    # Get the investigation node for the collection
    investigation_area_name = mk_Investigation_Area_name(proposal_id)
    investigation_area_lidvid = mk_Investigation_Area_lidvid(proposal_id)
    investigation_area_node = investigation_area(investigation_area_name,
                                                 investigation_area_lidvid,
                                                 "bundle")

    # Get min start_time and max stop_time
    start_time, stop_time = bundle_db.get_roll_up_time_from_db()
    # Make sure start/stop time exists in db.
    if start_time is None:
        raise ValueError("Start time is not stored in FitsProduct table.")
    if stop_time is None:
        raise ValueError("Stop time is not stored in FitsProduct table.")

    start_stop_times = {
        "start_date_time": start_time,
        "stop_date_time": stop_time,
    }
    time_coordinates_node = get_time_coordinates(start_stop_times)

    # Dictionary used for primary result summary
    primary_result_dict: Dict[str, Any] = {}
    # Put dummy value in processing level, wait for update.
    primary_result_dict["processing_level"] = "Raw"
    instruments_list = bundle_db.get_instruments_of_the_bundle()
    instruments = ", ".join(instruments_list).upper()
    p_title = (f"{instruments} observations obtained by the HST " +
               f"Observing Program {proposal_id}.")
    primary_result_dict["description"] = p_title

    # Get unique wavelength names for roll-up in bundle
    wavelength_range = bundle_db.get_wavelength_range_from_db()
    primary_result_dict["wavelength_range"] = wavelength_range
    primary_result_summary_node = primary_result_summary(primary_result_dict)

    # Get the observing system node for the bundle
    observing_system_nodes: List[NodeBuilder] = [
        observing_system(instrument) for instrument in instruments_list
    ]

    context_node: List[NodeBuilder] = []
    context_node = [
        make_bundle_context_node(
            time_coordinates_node,
            primary_result_summary_node,
            investigation_area_node,
            observing_system_nodes,
            target_identification_nodes,
        )
    ]

    if not use_mod_date_for_testing:
        # Get the date when the label is created
        mod_date = get_current_date()
    else:
        mod_date = MOD_DATE_FOR_TESTESING

    try:
        label = (make_label({
            "bundle_lid":
            lidvid_to_lid(bundle.lidvid),
            "bundle_vid":
            lidvid_to_vid(bundle.lidvid),
            "proposal_id":
            str(proposal_id),
            "title":
            title,
            "Citation_Information":
            make_citation_information(info, is_for_bundle=True),
            "mod_date":
            mod_date,
            "Bundle_Member_Entries":
            combine_nodes_into_fragment(reduced_collections),
            "Context_Area":
            combine_nodes_into_fragment(context_node),
            "Reference_List":
            make_document_reference_list(instruments_list, "bundle"),
        }).toxml().encode())
    except Exception as e:
        raise LabelError(bundle.lidvid) from e

    if label[:6] != b"<?xml ":
        raise ValueError("Bundle label is not XML.")
    return pretty_and_verify(label, verify)
Example #4
0
def make_other_collection_label(
    bundle_db: BundleDB,
    info: Citation_Information,
    collection_lidvid: str,
    bundle_lidvid: str,
    verify: bool,
    mod_date: str,
) -> bytes:
    """
    Create the label text for the document, browse, and data collection having
    this LIDVID using the bundle database.  If verify is True, verify the label
    against its XML and Schematron schemas.  Raise an exception if either
    fails.
    """
    # TODO this is sloppy; is there a better way?
    products = bundle_db.get_collection_products(collection_lidvid)
    record_count = len(products)
    if record_count <= 0:
        raise ValueError(f"{collection_lidvid} has no products.")

    collection_lid = lidvid_to_lid(collection_lidvid)
    collection_vid = lidvid_to_vid(collection_lidvid)
    collection: Collection = bundle_db.get_collection(collection_lidvid)

    proposal_id = bundle_db.get_bundle(bundle_lidvid).proposal_id
    instruments = ",".join(bundle_db.get_instruments_of_the_bundle()).upper()

    def make_ctxt_coll_title(_coll: Collection) -> NodeBuilder:
        return make_context_collection_title(
            {
                "instrument": instruments,
                "proposal_id": str(proposal_id),
            }
        )

    def make_doc_coll_title(_coll: Collection) -> NodeBuilder:
        return make_document_collection_title(
            {
                "instrument": instruments,
                "proposal_id": str(proposal_id),
            }
        )

    def make_sch_coll_title(_coll: Collection) -> NodeBuilder:
        return make_schema_collection_title(
            {
                "instrument": instruments,
                "proposal_id": str(proposal_id),
            }
        )

    def make_other_coll_title(coll: Collection) -> NodeBuilder:
        other_collection = cast(OtherCollection, coll)
        if other_collection.prefix == "browse":
            collection_title = (
                f"{other_collection.prefix.capitalize()} "
                + f"collection of {other_collection.instrument.upper()} "
                + f"observations obtained from HST Observing Program {proposal_id}."
            )
        else:
            # Get the data/misc collection title from db.
            collection_title = str(other_collection.title)
        return make_other_collection_title({"collection_title": collection_title})

    title: NodeBuilder = switch_on_collection_subtype(
        collection,
        make_ctxt_coll_title,
        make_doc_coll_title,
        make_sch_coll_title,
        make_other_coll_title,
    )(collection)

    inventory_name = get_collection_inventory_name(bundle_db, collection_lidvid)

    # Properly assign collection type for Document, Browse, or Data collection.
    # Context node only exists in Data collection label.
    # Reference_List only exists in Data collection label.
    context_node: List[NodeBuilder] = []
    reference_list_node: List[NodeBuilder] = []
    collection_type: str = ""
    type_name = type(collection).__name__
    if type_name == "DocumentCollection":
        collection_type = "Document"
        # For document collection, we need to add all handbooks in the csv but
        # we won't create the label for it.
        inst_list = bundle_db.get_instruments_of_the_bundle()
        record_count += 2 * len(inst_list)
    elif type_name == "OtherCollection":
        collection_type = cast(OtherCollection, collection).prefix.capitalize()
        suffix = cast(OtherCollection, collection).suffix
        instrument = cast(OtherCollection, collection).instrument

        # Roll-up (Context node) only exists in data collection
        if collection_type == "Data":
            # Get min start_time and max stop_time
            start_time, stop_time = bundle_db.get_roll_up_time_from_db(suffix)
            # Make sure start/stop time exists in db.
            if start_time is None:
                raise ValueError("Start time is not stored in FitsProduct table.")
            if stop_time is None:
                raise ValueError("Stop time is not stored in FitsProduct table.")

            start_stop_times = {
                "start_date_time": start_time,
                "stop_date_time": stop_time,
            }
            time_coordinates_node = get_time_coordinates(start_stop_times)

            # Dictionary used for primary result summary
            primary_result_dict: Dict[str, Any] = {}
            # Check if it's raw or calibrated image, we will update this later
            processing_level = get_processing_level(
                suffix=suffix, instrument_id=instrument.upper()
            )
            primary_result_dict["processing_level"] = processing_level

            p_title = bundle_db.get_fits_product_collection_title(collection_lidvid)
            primary_result_dict["description"] = p_title
            # Get unique wavelength names for roll-up in data collection
            wavelength_range = bundle_db.get_wavelength_range_from_db(suffix)
            primary_result_dict["wavelength_range"] = wavelength_range
            primary_result_summary_node = primary_result_summary(primary_result_dict)

            # Get the list of target identifications nodes for the collection
            target_identifications = bundle_db.get_all_target_identification()
            target_identification_nodes: List[NodeBuilder] = []
            target_identification_nodes = create_target_identification_nodes(
                bundle_db, target_identifications, "collection"
            )

            # Get the investigation node for the collection
            investigation_area_name = mk_Investigation_Area_name(proposal_id)
            investigation_area_lidvid = mk_Investigation_Area_lidvid(proposal_id)
            investigation_area_node = investigation_area(
                investigation_area_name, investigation_area_lidvid, "collection"
            )

            # Get the observing system node for the collection
            observing_system_node = observing_system(instrument)

            context_node = [
                make_collection_context_node(
                    time_coordinates_node,
                    primary_result_summary_node,
                    investigation_area_node,
                    observing_system_node,
                    target_identification_nodes,
                )
            ]

            # document reference list only exists in data collection
            reference_list_node = [
                make_document_reference_list([instrument], "collection")
            ]

    try:
        label = (
            make_label(
                {
                    "collection_lid": collection_lid,
                    "collection_vid": collection_vid,
                    "record_count": record_count,
                    "title": title,
                    "mod_date": mod_date,
                    "proposal_id": str(proposal_id),
                    "Citation_Information": make_citation_information(info),
                    "inventory_name": inventory_name,
                    "Context_Area": combine_nodes_into_fragment(context_node),
                    "collection_type": collection_type,
                    "Reference_List": combine_nodes_into_fragment(reference_list_node),
                }
            )
            .toxml()
            .encode()
        )
    except Exception as e:
        raise LabelError(collection_lidvid) from e

    return pretty_and_verify(label, verify)