Source code for analyzer.core.datasets
from __future__ import annotations
import enum
from analyzer.core.event_collection import SourceDescription
from pathlib import Path
from analyzer.core.serialization import converter
from analyzer.core.caching import cache
from typing import Any
from attrs import define, field, fields
from analyzer.logging import logger
import yaml
try:
from yaml import CLoader as Loader
except ImportError:
from yaml import Loader
[docs]
def getDatasets(query, client):
from coffea.dataset_tools import rucio_utils
outlist, outtree = rucio_utils.query_dataset(
query,
client=client,
tree=True,
scope="cms",
)
return outlist
[docs]
def getReplicas(dataset, client):
from coffea.dataset_tools import rucio_utils
(
outfiles,
outsites,
sites_counts,
) = rucio_utils.get_dataset_files_replicas(
dataset,
allowlist_sites=[],
blocklist_sites=["T3_CH_CERN_OpenData"],
regex_sites=[],
mode="full", # full or first. "full"==all the available replicas
client=client,
)
ret = [dict(zip(s, f)) for s, f in zip(outfiles, outsites)]
return ret
[docs]
class SampleType(enum.Enum):
@define
[docs]
class Sample:
[docs]
source: SourceDescription
[docs]
x_sec: float | None = None
@property
@define
[docs]
class Dataset:
[docs]
sample_type: SampleType
[docs]
other_data: dict[str, Any] = field(factory=dict)
@property
[docs]
def __iter__(self):
return iter(self.samples)
[docs]
def __len__(self):
return len(self.samples)
[docs]
def __getitem__(self, sample_name):
found = next(x for x in self.samples if x.name == sample_name)
return found
@cache.memoize(tag="dataset")
[docs]
def getDatasetFromPathMTime(path, mtime):
print(path)
with open(path, "r") as fo:
data = yaml.load(fo, Loader=Loader)
data = converter.structure(data, list[Dataset])
return data
@define
[docs]
class DatasetRepo:
[docs]
datasets: dict[str, Dataset] = field(factory=dict)
[docs]
def __getitem__(self, key):
return self.datasets[key]
[docs]
def __iter__(self):
return iter(self.datasets)
[docs]
def addFromFile(self, path):
path = Path(path)
try:
data = getDatasetFromPathMTime(path, path.stat().st_mtime)
for d in data:
# logger.debug(f"Adding dataset {d.name} to repo")
if d.name in self.datasets:
raise KeyError(f"A dataset with the name {d.name} already exists")
self.datasets[d.name] = d
except Exception as e:
logger.error(f"Failed to add dataset {path} to repo: {e}")
raise e
[docs]
def addFromDirectory(self, path):
logger.info(f"Loading datasets recursively from path {path}")
directory = Path(path)
if directory.is_file():
self.addFromFile(directory)
else:
files = list(directory.rglob("*.yaml"))
for f in files:
self.addFromFile(f)