Projects & Properties & Context Management

Nexus provides several ways to organize your data, store custom parameters and integrate these easily into your workflows.

  • Projects are a way of categorizing and containing your workflows and data, a bit like a folder in a filesystem.

  • Properties are a place to store additional custom metadata or scientific parameters. Properties are defined on a Project, and given values for data within that project.

from datetime import datetime
import qnexus as qnx

from pytket import Circuit
# Get a ProjectRef 
my_project_ref = qnx.projects.create(name=f"My Project from {datetime.now()}")

# Show basic information about the project
my_project_ref.df()
# Get a summary of the project as a DataFrame (shows Job statuses)
qnx.projects.summarize(my_project_ref)
# Lets add a custom property 

qnx.projects.add_property(
    name="molecule_type",
    property_type="string",
    project=my_project_ref,
    description="The type of molecule being studied",
)

qnx.projects.add_property(
    name="iteration",
    property_type="int",
    project=my_project_ref,
    description="The iteration number of the experiment",
)
# View the properties defined on the project as a DataFrame

qnx.projects.get_properties(project=my_project_ref).df()
# We can then define property values on data we create within the project

my_circuit_ref = qnx.circuits.upload(
    name=f"My Circuit from {datetime.now()}",
    circuit = Circuit(2).ZZPhase(0.5, 0, 1).measure_all(),
    project = my_project_ref,
    properties={"molecule_type": "H2"},
)

my_circuit_ref.df()

If you submit a Job to Nexus with defined property values, these values will be propogated to the outputs of the Job.

Context Management

If we know we’ll be working within a project or with a set of defined property values we can provide these in a system of context management.

# Via a typical context manager
with qnx.context.using_project(my_project_ref):
    # Show all circuits  in the project
    qnx.circuits.get_all().df()

    # These values can be overridden, with parameters taking precedence over context
    my_circuit_ref = qnx.circuits.upload(
        name=f"My Circuit from {datetime.now()}",
        circuit = Circuit(2).ZZPhase(0.5, 0, 1).measure_all(),
        project=qnx.projects.create(name=f"My other Nexus Project from {datetime.now()}")
    )

    with qnx.context.using_properties(molecule_type = "H2", iteration = 0):

        # Create a circuit within the project and with defined property values
        my_circuit_ref = qnx.circuits.upload(
            name=f"My Circuit from {datetime.now()}",
            circuit = Circuit(2).ZZPhase(0.5, 0, 1).measure_all(),
        )

        # Property parameters will be the union of the parameters and context (parameters take precedence)
        my_circuit_ref = qnx.circuits.upload(
            name=f"My Circuit from {datetime.now()}",
            circuit = Circuit(2).ZZPhase(0.5, 0, 1).measure_all(),
            properties={"iteration": 1},
        )
# Values can also be set in the global context

current_project_context = qnx.context.set_active_project_token(my_project_ref)

# Deactivate the project context

qnx.context.deactivate_project(current_project_context)

Project Updating & Deletion

qnexus can be used to update or delete a project. Updating will allow you to change details such as the project’s name, or set it as ‘archived’ (meaning it will no longer show up by default in the UI or when retrieving projects via the API).

Projects can also be deleted, which will permanently and irreversibly purge any project data stored by Nexus (including circuits and results). This will free up Storage quota for all the resources within the project.

NB:

  • projects must be archived before they can be deleted.

  • project deletion won’t cancel any jobs submitted to either H-series or third parties - so make sure that any running jobs are cancelled to be safe.

  • project deletion will delete the data for all contributors to the project, so double check with your team members before deleting any data.

# update the project
updated_project_ref = qnx.projects.update(
    project=my_project_ref,
    archive=True,
)

# Permanently delete the project and all underlying data for everyone
qnx.projects.delete(project=updated_project_ref)