To check whether this was an issue with my code, I ran exactly the same notebook using the latest r29 release, and everything worked as expected. This makes me think that the problem is related to changes introduced in r30, possibly involving the Butler dimension universe or dataset type compatibility.
Has anyone encountered this issue before, or is there any migration step required when creating a local repository with r30+? Any suggestions would be greatly appreciated.
If you are creating the local repository using v30 from a DP1 butler this should work since I fixed a bug for exactly that issue in v30.0.10 (there was a DP1 tutorial notebook doing this). Can you give me more explicit instructions on how to reproduce?
The same code works correctly with r29, so I suspect this is related to a change in the Butler dimension universe between r29 and r30. Does register_datasetTypes require any changes in r30, or is there now a different recommended way to register dataset types from a remote repository?
You have your own API wrappers so it’s hard for me to say exactly what you are doing but if you are trying to register a dataset type from one butler in another butler and they do not have identical dimension universes you need to conform the source to the destination. Something like:
If you use dest_butler.transfer_from() then this is all handled for you, including registering of dataset types and dimension records.
If you are running a pipeline task you can also use executor.use_local_butler(local_repo_path) to copy what you need from the graph into a local butler (see DP1 tutorial 105_6).
Thanks, this is very helpful. I think I understand where the problem is now.
In my wrapper I create a new local Butler repository and then manually register the DatasetTypes before transferring the datasets. In particular, I currently have something like:
def register_datasetTypes(local_repo, datasettypes, ...):
lbutler = Butler(local_repo, writeable=True)
lreg = lbutler.registry
for dt in datasettypes:
lreg.registerDatasetType(dt)
The DatasetType objects in this case come directly from the remote Butler. Therefore, I think this is exactly where the dimension-universe mismatch occurs: I am trying to register the remote DatasetType directly into the newly created local Butler.
Based on your suggestion, I think the minimal fix should be:
for dt in datasettypes:
local_dt = dt.conform_to(lbutler.dimensions)
lreg.registerDatasetType(local_dt)
At the moment, after this manual registration I use butler transfer-datasets to transfer the actual datasets and preserve their UUIDs.
I also see your point about using dest_butler.transfer_from() instead. It seems that this could simplify my wrapper considerably, since I would not need to manually register the DatasetTypes and dimension records before the transfer.
I will first test the conform_to() change to confirm that this is the source of the r30 problem, and then I will look at replacing part of my manual transfer logic with transfer_from().
Thanks also for pointing me to executor.use_local_butler(). My current code is a more general wrapper for constructing a local Butler before running the pipeline, but I will check tutorial 105_6 as well.
I tested the change you recommended, using dataset_type.conform_to(local_butler.dimensions) before registering the DatasetType , and it solved the problem. The dimension universe mismatch disappeared, so that was indeed the issue. Thanks for pointing me in the right direction!
I will also take a closer look at your recommendation of using dest_butler.transfer_from() . It seems like a much cleaner approach than my current implementation, so I’ll evaluate whether I can simplify my wrapper around it.
Thanks again for your help. I really appreciate it.