Group Attribution
Group attribution aggregates carbon usage by machine type and cloud project, enabling facility-level carbon reporting.
What is a Group?
In the Ada carbon monitoring system, a group is the combination of:
- cloud_project_name - The OpenStack project (e.g., “IDAaaS”, “CDAaaS”)
- machine_name - The machine type (e.g., “Muon”, “SANS”, “Tomography”)
This combination identifies all workspaces of a particular type within a facility.
Group Name Format
Groups are named as: {cloud_project}_{machine_name}
Examples:
IDAaaS_Muon- ISIS Muon workspacesIDAaaS_SANS- ISIS SANS workspacesCDAaaS_Tomography- CLF Tomography workspaces
API Endpoints
List All Groups
GET /groups
Response:
{
"groups": [
{"name": "IDAaaS_Muon", "cloud_project": "IDAaaS", "machine_name": "Muon"},
{"name": "IDAaaS_SANS", "cloud_project": "IDAaaS", "machine_name": "SANS"},
{"name": "CDAaaS_Tomography", "cloud_project": "CDAaaS", "machine_name": "Tomography"}
],
"count": 780
}
Get Group Carbon Usage
GET /groups/{group_name}/usage
Example:
curl http://localhost:8000/groups/IDAaaS_Muon/usage
Response:
[
{
"workspace_id": "IDAaaS_Muon",
"hostname": "IDAaaS_Muon",
"cpu_usage": {
"busy_seconds": 537.45,
"idle_seconds": 287239.26,
"total_seconds": 287776.71
},
"energy_kwh": {
"busy": 0.00179,
"idle": 0.07979,
"total": 0.08158
},
"carbon_gco2eq": {
"busy": 0.41,
"idle": 18.47,
"total": 18.89
},
"carbon_intensity_g_per_kwh": 231.5,
"status": "processed"
}
]
Get Group Carbon Summary
GET /groups/{group_name}/summary
Response:
{
"workspace_count": 1,
"complete_count": 1,
"total_cpu_seconds": {
"busy_seconds": 537.45,
"idle_seconds": 287239.26,
"total_seconds": 287776.71
},
"total_energy_kwh": 0.08158,
"total_carbon_gco2eq": 18.89,
"carbon_equivalencies": {
"total_gco2eq": 18.89,
"top_equivalencies": {
"smartphone_charges": {"value": 2.3, "unit": "charges"},
"streaming_hours": {"value": 0.34, "unit": "hours"}
}
}
}
Implementation
WorkspaceTracker.track_group()
The track_group method queries Prometheus for all hosts in a group:
def track_group(
self,
cloud_project_name: str,
machine_name: Optional[str] = None,
timestamp: Optional[datetime] = None
) -> Optional[WorkspaceUsageEntry]:
"""
Track carbon usage for a group (cloud_project + machine_name).
Unlike track_workspace which tracks individual hosts, this method
aggregates all usage for a cloud project and machine type combination.
"""
group_name = f"{cloud_project_name}_{machine_name}"
# Create entry for the group
entry = WorkspaceUsageEntry(
workspace_id=group_name,
hostname=group_name,
owner=None
)
entry.set_timestamp(timestamp)
# Query Prometheus WITHOUT host filter - gets all hosts in group
cpu_data = self.prometheus_client.get_cpu_usage_breakdown(
timestamp=timestamp,
cloud_project_name=cloud_project_name,
machine_name=machine_name,
host=None # No host filter = aggregate all
)
if cpu_data:
# Calculate energy and carbon...
entry.set_cpu_seconds_total(cpu_data["busy"], cpu_data["idle"])
# ... rest of calculation
return entry
Prometheus Query
Group queries use the same metric but without the instance filter:
# Individual workspace
increase(node_cpu_seconds_total{
cloud_project_name="IDAaaS",
machine_name="Muon",
instance=~"172.16.100.50.*"
}[1h])
# Group (all workspaces of this type)
increase(node_cpu_seconds_total{
cloud_project_name="IDAaaS",
machine_name="Muon"
}[1h])
Prometheus Labels
The group identification relies on Prometheus labels:
| Label | Description | Example |
|---|---|---|
cloud_project_name | OpenStack project | “IDAaaS”, “CDAaaS” |
machine_name | Machine type | “Muon”, “SANS”, “Tomography” |
instance | Host IP/hostname | “172.16.100.50:9100” |
Label to Facility Mapping
| cloud_project_name | Facility |
|---|---|
| IDAaaS | ISIS |
| CDAaaS | CLF |
| DDAaaS | Development |
| TDAaaS | Training |
Use Cases
Facility Reporting
Generate monthly carbon reports per instrument:
# Get all ISIS Muon carbon for January 2026
summary = tracker.track_group(
cloud_project_name="IDAaaS",
machine_name="Muon",
timestamp=datetime(2026, 1, 31)
)
print(f"ISIS Muon: {summary.total_usage_gco2eq:.2f} gCO2eq")
Cross-Facility Comparison
Compare carbon across facilities:
facilities = ["IDAaaS", "CDAaaS"]
for facility in facilities:
summary = tracker.track_group(cloud_project_name=facility)
print(f"{facility}: {summary.total_usage_gco2eq:.2f} gCO2eq")
Instrument Efficiency Analysis
Identify high-carbon instruments:
groups = get_all_groups()
usage = []
for group in groups:
summary = tracker.track_group(
cloud_project_name=group.cloud_project,
machine_name=group.machine_name
)
usage.append((group.name, summary.total_usage_gco2eq))
# Sort by carbon usage
usage.sort(key=lambda x: x[1], reverse=True)
print("Top 5 carbon-intensive groups:")
for name, carbon in usage[:5]:
print(f" {name}: {carbon:.2f} gCO2eq")
MongoDB Groups Collection
In addition to Prometheus-based groups, MongoDB stores experiment groups:
{
"_id": ObjectId("..."),
"name": "RB2024001",
"gid": 200001,
"tag": "ISIS",
"members": ["aa123456", "bb234567"],
"type": "experiment",
"parameters": {
"title": "Neutron Diffraction Study",
"pi": "aa123456",
"instrument": "WISH"
}
}
These can be used for:
- Attributing carbon to specific experiments (by matching instrument and time period)
- Generating per-experiment carbon reports
- Tracking carbon per PI or research group
Relationship to User Attribution
| Attribution Type | Scope | Use Case |
|---|---|---|
| User | Individual workspaces owned by a user | Personal carbon tracking |
| Group | All workspaces of a machine type | Facility/instrument reporting |
| Experiment | Workspaces used during an experiment | Research project carbon |
Users belong to groups, and groups contribute to facility totals:
Facility (IDAaaS)
├── Group (Muon)
│ ├── User A's workspace (5 gCO2eq)
│ └── User B's workspace (3 gCO2eq)
│ Total: 8 gCO2eq
├── Group (SANS)
│ └── User C's workspace (10 gCO2eq)
│ Total: 10 gCO2eq
Total: 18 gCO2eq