Building Blocks: Metadata and Libraries

When writing scripts which use cbcflow, you should expect to use two classes: cbcflow.metadata.MetaData and cbcflow.database.LocalLibraryDatabase. These describe the attributes and methods for a given event’s metadata and the library of event metadata respectively. This page will give an introduction to each in turn, while a more thorough tour may be found in subsequent pages.

MetaData

The most central building block in cbcflow is metadata. Loading this is surprisingly easy - for example:

>>> import cbcflow

>>> metadata = cbcflow.get_superevent("S230409lg")
INFO:cbcflow.schema:Using schema file /home/rhiannon.udall/.conda/envs/cbcflow_development/lib/python3.10/site-packages/cbcflow/schema/cbc-meta-data-v2.schema

If a specific library argument is not passed, then the default library will be used (see Configuration), as has occurred in this example. To pass a specific library, one may add the keyword argument library=/a/path/to/a/library.

If the library already contains metadata for the superevent described by sname, then that metadata will be loaded. Otherwise, this superevent will start with default data.

To see what our metadata looks like, we can use the pretty_print() method.

The output should look like this:
>>> metadata.pretty_print()
INFO:cbcflow.metadata:Metadata contents for S230409lg:
INFO:cbcflow.metadata:{
    "Sname": "S230409lg",
    "Info": {
        "Labels": [],
        "SchemaVersion": "v2",
        "Notes": []
    },
    "Publications": {
        "Papers": []
    },
    "GraceDB": {
        "Events": [
            {
                "State": "neighbor",
                "UID": "G991768",
                "Pipeline": "pycbc",
                "GPSTime": 1365062495.063965,
                "FAR": 2.223779464140237e-06,
                "NetworkSNR": 16.22064184905374,
                "V1SNR": 4.3057876,
                "Mass1": 2.0122149,
                "Mass2": 1.3525492,
                "Spin1z": 0.23247161,
                "Spin2z": -0.21646233,
                "H1SNR": 11.750094,
                "L1SNR": 10.320111,
                "Pastro": 0.005880358839495448,
                "Pbbh": 0.0,
                "Pbns": 0.005880358839495448,
                "Pnsbh": 0.0,
                "HasNS": 1.0,
                "HasRemnant": 1.0,
                "HasMassGap": 0.0,
                "PipelineHasMassGap": 0.0,
                "XML": "https://gracedb-playground.ligo.org/api/events/G991768/files/coinc.xml",
                "SourceClassification": "https://gracedb-playground.ligo.org/api/events/G991768/files/pycbc.p_astro.json",
                "Skymap": "https://gracedb-playground.ligo.org/api/events/G991768/files/bayestar.multiorder.fits"
            },
            {
                "State": "neighbor",
                "UID": "G991767",
                "Pipeline": "MBTA",
                "GPSTime": 1365062495.074961,
                "FAR": 1.501446e-09,
                "NetworkSNR": 15.872046,
                "V1SNR": 2.175341,
                "Mass1": 2.76463,
                "Mass2": 1.026004,
                "Spin1z": 0.262998,
                "Spin2z": 0.0,
                "H1SNR": 12.018019,
                "L1SNR": 10.13691,
                "Pastro": 1.0,
                "Pbbh": 0.0,
                "Pbns": 0.924042,
                "Pnsbh": 0.075958,
                "HasNS": 1.0,
                "HasRemnant": 1.0,
                "HasMassGap": 0.0,
                "XML": "https://gracedb-playground.ligo.org/api/events/G991767/files/coinc.xml",
                "SourceClassification": "https://gracedb-playground.ligo.org/api/events/G991767/files/mbta.p_astro.json",
                "Skymap": "https://gracedb-playground.ligo.org/api/events/G991767/files/bayestar.multiorder.fits"
            },
            {
                "State": "preferred",
                "UID": "G991765",
                "Pipeline": "gstlal",
                "GPSTime": 1365062495.091802,
                "FAR": 2.900794989032493e-36,
                "NetworkSNR": 16.56542135029717,
                "H1SNR": 12.060055,
                "Mass1": 1.7551488,
                "Mass2": 1.540255,
                "Spin1z": 0.04640625,
                "Spin2z": 0.04640625,
                "L1SNR": 10.567706,
                "V1SNR": 4.1583471,
                "Pastro": 1.0,
                "Pbbh": 3.347659662210488e-57,
                "Pbns": 1.0,
                "Pnsbh": 5.433561263857133e-56,
                "HasNS": 1.0,
                "HasRemnant": 1.0,
                "HasMassGap": 0.0,
                "XML": "https://gracedb-playground.ligo.org/api/events/G991765/files/coinc.xml",
                "SourceClassification": "https://gracedb-playground.ligo.org/api/events/G991765/files/gstlal.p_astro.json",
                "Skymap": "https://gracedb-playground.ligo.org/api/events/G991765/files/bayestar.multiorder.fits"
            },
            {
                "State": "neighbor",
                "UID": "G991763",
                "Pipeline": "spiir",
                "GPSTime": 1365062495.087402,
                "FAR": 2.197285962424614e-27,
                "NetworkSNR": 16.38410099714992,
                "H1SNR": 12.11474,
                "Mass1": 2.1702261,
                "Mass2": 1.2627214,
                "Spin1z": 0.10948601,
                "Spin2z": 0.042859491,
                "L1SNR": 10.236156,
                "V1SNR": 4.1101012,
                "Pastro": 1.0,
                "Pbbh": 0.0,
                "Pbns": 1.0,
                "Pnsbh": 0.0,
                "HasNS": 1.0,
                "HasRemnant": 1.0,
                "HasMassGap": 0.0,
                "XML": "https://gracedb-playground.ligo.org/api/events/G991763/files/coinc.xml",
                "SourceClassification": "https://gracedb-playground.ligo.org/api/events/G991763/files/spiir.p_astro.json",
                "Skymap": "https://gracedb-playground.ligo.org/api/events/G991763/files/bayestar.multiorder.fits"
            }
        ],
        "Instruments": "H1,L1,V1",
        "LastUpdate": "2023-04-11 18:27:52.777929"
    },
    "ExtremeMatter": {
        "Analyses": []
    },
    "Cosmology": {
        "Counterparts": [],
        "CosmologyRunsUsingThisSuperevent": [],
        "Notes": [],
        "PreferredLowLatencySkymap": "https://gracedb-playground.ligo.org/api/events/G991765/files/bayestar.multiorder.fits"
    },
    "RatesAndPopulations": {
        "RnPRunsUsingThisSuperevent": []
    },
    "ParameterEstimation": {
        "Analysts": [],
        "Reviewers": [],
        "Status": "unstarted",
        "Results": [],
        "SafeSamplingRate": 4096.0,
        "SafeLowerMassRatio": 0.05,
        "Notes": []
    },
    "Lensing": {
        "Analyses": []
    },
    "TestingGR": {
        "BHMAnalyses": [],
        "EchoesCWBAnalyses": [],
        "FTIAnalyses": [],
        "IMRCTAnalyses": [],
        "LOSAAnalyses": [],
        "MDRAnalyses": [],
        "ModeledEchoesAnalyses": [],
        "PCATGRAnalyses": [],
        "POLAnalyses": [],
        "PSEOBRDAnalyses": [],
        "PYRINGAnalyses": [],
        "QNMRationalFilterAnalyses": [],
        "ResidualsAnalyses": [],
        "SIMAnalyses": [],
        "SMAAnalyses": [],
        "SSBAnalyses": [],
        "TIGERAnalyses": [],
        "UnmodeledEchoesAnalyses": [],
        "Notes": []
    },
    "DetectorCharacterization": {
        "Analysts": [],
        "Reviewers": [],
        "ParticipatingDetectors": [],
        "Status": "unstarted",
        "RecommendedDetectors": [],
        "RecommendedDuration": 4.0,
        "DQRResults": [],
        "Notes": []
    }
}

Since this event has already been initialized from gracedb, we can see a lot of gracedb information already.

If you want to read a specific element in a MetaData object, it also works like you expect it to. For example:

>>> metadata["GraceDB"]["Events"][2]
{'State': 'preferred', 'UID': 'G991765', 'Pipeline': 'gstlal', 'GPSTime': 1365062495.091802, 'FAR': 2.900794989032493e-36,
'NetworkSNR': 16.56542135029717, 'H1SNR': 12.060055, 'Mass1': 1.7551488, 'Mass2': 1.540255, 'Spin1z': 0.04640625, 'Spin2z': 0.04640625,
'L1SNR': 10.567706, 'V1SNR': 4.1583471, 'Pastro': 1.0, 'Pbbh': 3.347659662210488e-57, 'Pbns': 1.0, 'Pnsbh': 5.433561263857133e-56,
'HasNS': 1.0, 'HasRemnant': 1.0, 'HasMassGap': 0.0, 'XML': 'https://gracedb-playground.ligo.org/api/events/G991765/files/coinc.xml',
'SourceClassification': 'https://gracedb-playground.ligo.org/api/events/G991765/files/gstlal.p_astro.json',
'Skymap': 'https://gracedb-playground.ligo.org/api/events/G991765/files/bayestar.multiorder.fits'}

Note that since Events is a list (of dictionaries), this level of the hierarchy must be accessed by list index, not by the UID name. This may be updated in the future, but for now is a necessary evil.

If you want to write to the metadata, it is strongly recommended that you do so with the update method detailed in updating-metadata-with-the-python-api, which will automatically handle merging the correct UIDs, validation against the schema, and so on.

LocalLibraryDatabase

The LocalLibraryDatabase, which we’ll just call the library, is an object that reflects the collection of many metadata objects. One of these is automatically generated whenever we load metadata, but to edit it directly we will want to invoke it directly. This may be done with:

>>> import cbcflow
>>> library = cbcflow.database.LocalLibraryDatabase("/home/rhiannon.udall/meta-data/testing_libraries/cbcflow-tutorial-library")
2023-06-09 13:53:18 CBCFlow INFO: Using cbc schema file /home/rhiannon.udall/meta-data/meta-data/src/cbcflow/schema/cbc-meta-data-v2.schema

We can now load the metadata using this library by doing:

>>> metadata = cbcflow.get_superevent("S230409lg", library=library)
2023-06-09 13:56:31 CBCFlow INFO: Using cbc schema file /home/rhiannon.udall/meta-data/meta-data/src/cbcflow/schema/cbc-meta-data-v2.schema

This metadata exists as before, but we can also access it through the library.

On its own, this probably does not seem particularly useful, and if you are just updating (or, especially, reading) a single metadata file you are safe to not worry about libraries. If you wish to do more advanced automation, though, especially involving interactions with git, please see The LocalLibraryDatabase for more information on how to use libraries.