Skip to content

molmo_spaces

molmo_spaces

Modules:

Name Description
configs

Configuration module for MolmoSpaces experiments.

controllers
data_generation
env
evaluation

Evaluation utilities for MolmoSpaces benchmarks.

grasp_generation
housegen
kinematics
molmo_spaces_constants

Constants and paths for the MolmoSpaces project. Paths should be provided as Path objects.

planner
policy
renderer
resources
robots
tasks
utils

Attributes:

Name Type Description
MOLMO_SPACES_BASE_DIR

MOLMO_SPACES_BASE_DIR module-attribute

MOLMO_SPACES_BASE_DIR = parent

molmo_spaces_constants

Constants and paths for the MolmoSpaces project. Paths should be provided as Path objects.

Overwrite in the environment with e.g.: MLSPACES_ASSETS_DIR=/Users/username/mlspaces_resources mjpython scripts/...

Functions:

Name Description
single_thread_environment
resource_manager_log_level
get_resource_manager
get_scenes_root
get_asset_id_to_object_type
get_object_type_to_asset_ids
get_scenes
check_in_cache
populate_cache
get_ithor_houses

Return {split: {index: xml_path_or_None}} for iTHOR houses.

get_procthor_10k_houses

Return {split: {index: xml_path_or_None}} for ProcTHOR-10k houses.

get_procthor_objaverse_debug_houses

Return {split: {index: xml_path_or_None}} for ProcTHOR Objaverse houses.

get_procthor_objaverse_houses

Return {split: {index: xml_path_or_None}} for ProcTHOR Objaverse houses.

get_holodeck_objaverse_houses

Return {split: {index: xml_path_or_None}} for ProcTHOR Objaverse houses.

get_robot_paths

Return {robot_name: Path} for all available robot files.

get_robot_path
print_license_info

Attributes:

Name Type Description
ABS_PATH_OF_TOP_LEVEL_MOLMO_SPACES_DIR
DATA_CACHE_DIR
ASSETS_DIR
ROBOTS_DIR
OBJAVERSE_ASSETS_DIR
PINNED_ASSETS_FILE
USE_HUGGING_FACE
DATA_TYPE_TO_SOURCE_TO_VERSION
pinned_assets

ABS_PATH_OF_TOP_LEVEL_MOLMO_SPACES_DIR module-attribute

ABS_PATH_OF_TOP_LEVEL_MOLMO_SPACES_DIR = parent

DATA_CACHE_DIR module-attribute

DATA_CACHE_DIR = Path(get('MLSPACES_CACHE_DIR', _DATA_CACHE_DEFAULT))

ASSETS_DIR module-attribute

ASSETS_DIR = Path(get('MLSPACES_ASSETS_DIR', home() / '.cache' / 'molmospaces' / 'assets' / _install_hash))

ROBOTS_DIR module-attribute

ROBOTS_DIR = ASSETS_DIR / 'robots'

OBJAVERSE_ASSETS_DIR module-attribute

OBJAVERSE_ASSETS_DIR = Path(get('MLSPACES_OBJAVERSE_ASSETS_DIR', ASSETS_DIR / 'objects' / 'objaverse'))

PINNED_ASSETS_FILE module-attribute

PINNED_ASSETS_FILE = Path(environ['MLSPACES_PINNED_ASSETS_FILE']) if 'MLSPACES_PINNED_ASSETS_FILE' in environ else None

USE_HUGGING_FACE module-attribute

USE_HUGGING_FACE = False

DATA_TYPE_TO_SOURCE_TO_VERSION module-attribute

DATA_TYPE_TO_SOURCE_TO_VERSION = dict(robots={'rby1': '20251224', 'rby1m': '20251224', 'franka_droid': '20260127', 'franka_cap': '20260213', 'floating_rum': '20251110', 'floating_robotiq': '20260208_retry4', 'franka_fr3': '20260303', 'i2rt_yam': '20260223'}, scenes={'ithor': '20251217', 'refs': '20250923', 'procthor-10k-train': '20251122', 'procthor-10k-val': '20251217', 'procthor-10k-test': '20251121', 'holodeck-objaverse-train': '20251217', 'holodeck-objaverse-val': '20251217', 'procthor-objaverse-train': '20251205', 'procthor-objaverse-val': '20251205'}, objects={'thor': '20251117', 'objaverse': '20260131', 'objathor_metadata': '20260129'}, grasps={'droid': '20251116', 'droid_objaverse': '20251218'}, test_data={'franka_pick': '20260209', 'franka_pick_and_place': '20260305', 'rby1_door_opening': '20260228', 'rby1_pnp': '20260305', 'rum_open_close': '20260305', 'rum_pick': '20260209', 'test_randomized_data': '20251209', 'thormap': '20251209'}, benchmarks={'molmospaces-bench-v1': '20260408', 'molmospaces-bench-v2': '20260415'})

pinned_assets module-attribute

pinned_assets = load(f)

single_thread_environment

single_thread_environment()
Source code in molmo_spaces/molmo_spaces_constants.py
def single_thread_environment():
    print(f"Setting single thread environment for proc {os.getpid()}")
    try:
        import torch

        if torch.get_num_threads() != 1:
            torch.set_num_threads(1)
        if torch.get_num_interop_threads() != 1:
            torch.set_num_interop_threads(1)

        if os.environ.get("OMP_NUM_THREADS") != "1":
            os.environ["OMP_NUM_THREADS"] = "1"
        if os.environ.get("MKL_NUM_THREADS") != "1":
            os.environ["MKL_NUM_THREADS"] = "1"
    except Exception:
        pass

resource_manager_log_level

resource_manager_log_level(log_level=DEBUG)
Source code in molmo_spaces/molmo_spaces_constants.py
def resource_manager_log_level(log_level=logging.DEBUG):
    logger = logging.getLogger("molmospaces_resources")
    logger.setLevel(log_level)
    if not logger.handlers:
        logger.addHandler(logging.StreamHandler())

get_resource_manager

get_resource_manager(force_post_setup: bool = False)
Source code in molmo_spaces/molmo_spaces_constants.py
def get_resource_manager(force_post_setup: bool = False):
    global _RESOURCE_MANAGER
    if _RESOURCE_MANAGER is None:

        def post_setup(manager: ResourceManager):
            if not os.environ.get("_IN_MULTIPROCESSING_CHILD") and str2bool(
                os.environ.get("MLSPACES_DOWNLOAD_EXTRACT_ALL_SCENES_OBJECTS_GRASPS", "False")
            ):
                # extract to cache only; link on demand (per-file for scenes)
                manager.install_all_for_data_type("scenes", skip_linking=True)
                manager.install_all_for_data_type("objects")
                manager.install_all_for_data_type("grasps")
            else:
                to_install = {}
                for scene_source in DATA_TYPE_TO_SOURCE_TO_VERSION["scenes"]:
                    source_packages = manager.find_all_packages_for_source("scenes", scene_source)
                    if len(source_packages) < 10:
                        # Fully install small scene datasets
                        packages = source_packages
                    else:
                        # Install unindexed scene archives
                        packages = manager.unindexed_archives("scenes", scene_source)

                    if packages:
                        to_install[scene_source] = packages

                if to_install:
                    manager.install_packages("scenes", to_install)

        # resource_manager_log_level()

        _RESOURCE_MANAGER = setup_resource_manager(
            HFRemoteStorage(
                "allenai/molmospaces", repo_prefix="mujoco", token=os.getenv("HF_TOKEN")
            )
            if USE_HUGGING_FACE
            else R2RemoteStorage("mujoco-thor-resources"),
            symlink_dir=ASSETS_DIR,
            versions=DATA_TYPE_TO_SOURCE_TO_VERSION,
            cache_dir=DATA_CACHE_DIR,
            env_prefix="MLSPACES",
            post_setup=post_setup,
            force_post_setup=force_post_setup,
        )
    return _RESOURCE_MANAGER

get_scenes_root

get_scenes_root()
Source code in molmo_spaces/molmo_spaces_constants.py
def get_scenes_root():
    global _SCENES_ROOT
    if _SCENES_ROOT is None:
        # Ensure scenes dir under asset root exists
        get_resource_manager()

        if (ASSETS_DIR / "scenes").exists():
            _SCENES_ROOT = ASSETS_DIR / "scenes"

        else:
            _SCENES_ROOT = Path(
                os.environ.get(
                    "MLSPACES_SCENES_ROOT",
                    ASSETS_DIR / "scenes",
                )
            )
        print(f"Using SCENES_ROOT: {_SCENES_ROOT}")

    return _SCENES_ROOT

get_asset_id_to_object_type

get_asset_id_to_object_type()
Source code in molmo_spaces/molmo_spaces_constants.py
def get_asset_id_to_object_type():
    global _ASSET_ID_TO_OBJECT_TYPE
    if _ASSET_ID_TO_OBJECT_TYPE is None:
        ref_file = get_scenes_root() / "refs" / "asset_id_to_object_type.json"
        try:
            _ASSET_ID_TO_OBJECT_TYPE = compress_json.load(str(ref_file))
        except Exception as e:
            print(f"Warning: Failed to load asset_id_to_object_type.json: {e}")
            _ASSET_ID_TO_OBJECT_TYPE = {}

    return _ASSET_ID_TO_OBJECT_TYPE

get_object_type_to_asset_ids

get_object_type_to_asset_ids()
Source code in molmo_spaces/molmo_spaces_constants.py
def get_object_type_to_asset_ids():
    global _OBJECT_TYPE_TO_ASSET_IDS
    if _OBJECT_TYPE_TO_ASSET_IDS is None:
        # Group asset IDs by object type
        _OBJECT_TYPE_TO_ASSET_IDS = defaultdict(list)
        for asset_id, obj_type in get_asset_id_to_object_type().items():
            _OBJECT_TYPE_TO_ASSET_IDS[obj_type].append(asset_id)
        _OBJECT_TYPE_TO_ASSET_IDS = dict(_OBJECT_TYPE_TO_ASSET_IDS)  # Convert back to regular dict

    return _OBJECT_TYPE_TO_ASSET_IDS

get_scenes

get_scenes(dataset_name: str, split: str = 'train', return_version: bool = False) -> dict | tuple[dict, str | None]
Source code in molmo_spaces/molmo_spaces_constants.py
def get_scenes(
    dataset_name: str, split: str = "train", return_version: bool = False
) -> dict | tuple[dict, str | None]:
    names2functions = {
        "ithor": get_ithor_houses,
        "procthor-10k": get_procthor_10k_houses,
        "procthor-100k-debug": get_procthor_objaverse_houses,
        "procthor-objaverse-debug": get_procthor_objaverse_debug_houses,
        "procthor-objaverse": get_procthor_objaverse_houses,
        "holodeck-objaverse": get_holodeck_objaverse_houses,
    }
    if dataset_name not in names2functions:
        raise ValueError(
            f"dataset_name was {dataset_name}, must be one of {names2functions.keys()}"
        )
    index_map = names2functions[dataset_name](split=split)

    if not return_version:
        return index_map
    else:
        if dataset_name.startswith("procthor-10k"):
            version = DATA_TYPE_TO_SOURCE_TO_VERSION["scenes"][f"procthor-10k-{split}"]
        elif (
            dataset_name.startswith("procthor-objaverse")
            and dataset_name != "procthor-objaverse-debug"
        ):
            version = DATA_TYPE_TO_SOURCE_TO_VERSION["scenes"][f"procthor-objaverse-{split}"]
        elif dataset_name.startswith("holodeck-objaverse"):
            version = DATA_TYPE_TO_SOURCE_TO_VERSION["scenes"][f"holodeck-objaverse-{split}"]

        elif dataset_name not in DATA_TYPE_TO_SOURCE_TO_VERSION["scenes"]:
            print(f"WARNING: Missing source for {dataset_name}")
            version = None
        else:
            version = DATA_TYPE_TO_SOURCE_TO_VERSION["scenes"][dataset_name]
        return index_map, version

check_in_cache

check_in_cache(cache_key, split)
Source code in molmo_spaces/molmo_spaces_constants.py
def check_in_cache(cache_key, split):
    return cache_key in _DATASET_INDEX_CACHE and split in _DATASET_INDEX_CACHE[cache_key]

populate_cache

populate_cache(cache_key, split, index_map)
Source code in molmo_spaces/molmo_spaces_constants.py
def populate_cache(cache_key, split, index_map):
    if cache_key not in _DATASET_INDEX_CACHE:
        _DATASET_INDEX_CACHE[cache_key] = {}
    # If we got val and test (we should), add those to the cache
    for rsplit in ["train", "val", "test"]:
        num_houses = len([idx for idx in index_map[rsplit] if index_map[rsplit][idx] is not None])
        if num_houses > 0:
            _DATASET_INDEX_CACHE[cache_key][rsplit] = index_map[rsplit]

    # If no houses available for split, make sure to still set it up in the cache
    _DATASET_INDEX_CACHE[cache_key][split] = index_map[split]

get_ithor_houses

get_ithor_houses(split) -> dict

Return {split: {index: xml_path_or_None}} for iTHOR houses.

Source code in molmo_spaces/molmo_spaces_constants.py
def get_ithor_houses(split) -> dict:
    """Return {split: {index: xml_path_or_None}} for iTHOR houses."""
    cache_key = "ithor"

    if check_in_cache(cache_key, split):
        return _DATASET_INDEX_CACHE[cache_key]

    houses_dir = get_scenes_root() / "ithor"
    index_map = _build_scene_index_map_ithor(houses_dir)

    populate_cache(cache_key, split, index_map)

    return index_map

get_procthor_10k_houses

get_procthor_10k_houses(split) -> dict

Return {split: {index: xml_path_or_None}} for ProcTHOR-10k houses.

Source code in molmo_spaces/molmo_spaces_constants.py
def get_procthor_10k_houses(split) -> dict:
    """Return {split: {index: xml_path_or_None}} for ProcTHOR-10k houses."""
    cache_key = "procthor-10k"
    if split == "train":
        location = "procthor-10k-train"
    elif split == "val":
        location = "procthor-10k-val"
    elif split == "test":
        location = "procthor-10k-test"
    else:
        raise ValueError

    if check_in_cache(cache_key, split):
        return _DATASET_INDEX_CACHE[cache_key]

    houses_dir = get_scenes_root() / location
    index_map = _build_scene_index_map_procthor(houses_dir, split)

    populate_cache(cache_key, split, index_map)

    return index_map

get_procthor_objaverse_debug_houses

get_procthor_objaverse_debug_houses(split) -> dict

Return {split: {index: xml_path_or_None}} for ProcTHOR Objaverse houses.

Source code in molmo_spaces/molmo_spaces_constants.py
def get_procthor_objaverse_debug_houses(split) -> dict:
    """Return {split: {index: xml_path_or_None}} for ProcTHOR Objaverse houses."""
    cache_key = "procthor-objaverse-debug"

    if check_in_cache(cache_key, split):
        return _DATASET_INDEX_CACHE[cache_key]

    houses_dir = get_scenes_root() / "procthor-objaverse-debug"
    index_map = _build_scene_index_map_procthor(houses_dir, split)

    populate_cache(cache_key, split, index_map)

    return index_map

get_procthor_objaverse_houses

get_procthor_objaverse_houses(split) -> dict

Return {split: {index: xml_path_or_None}} for ProcTHOR Objaverse houses.

Source code in molmo_spaces/molmo_spaces_constants.py
def get_procthor_objaverse_houses(split) -> dict:
    """Return {split: {index: xml_path_or_None}} for ProcTHOR Objaverse houses."""
    cache_key = "procthor-objaverse"

    if check_in_cache(cache_key, split):
        return _DATASET_INDEX_CACHE[cache_key]

    houses_dir = get_scenes_root() / f"procthor-objaverse-{split}"
    index_map = _build_scene_index_map_procthor(houses_dir, split)

    populate_cache(cache_key, split, index_map)

    return index_map

get_holodeck_objaverse_houses

get_holodeck_objaverse_houses(split) -> dict

Return {split: {index: xml_path_or_None}} for ProcTHOR Objaverse houses.

Source code in molmo_spaces/molmo_spaces_constants.py
def get_holodeck_objaverse_houses(split) -> dict:
    """Return {split: {index: xml_path_or_None}} for ProcTHOR Objaverse houses."""
    cache_key = "holodeck-objaverse"

    if check_in_cache(cache_key, split):
        return _DATASET_INDEX_CACHE[cache_key]

    houses_dir = get_scenes_root() / f"holodeck-objaverse-{split}"
    index_map = _build_scene_index_map_procthor(houses_dir, split)

    populate_cache(cache_key, split, index_map)

    return index_map

get_robot_paths

get_robot_paths() -> dict[str, Path]

Return {robot_name: Path} for all available robot files.

Source code in molmo_spaces/molmo_spaces_constants.py
def get_robot_paths() -> dict[str, Path]:
    """Return {robot_name: Path} for all available robot files."""
    robot_paths = {}
    for robot_name in os.listdir(ROBOTS_DIR):
        robot_paths[robot_name] = ROBOTS_DIR / robot_name
    return robot_paths

get_robot_path

get_robot_path(robot_name) -> Path
Source code in molmo_spaces/molmo_spaces_constants.py
def get_robot_path(robot_name) -> Path:
    return ROBOTS_DIR / robot_name

print_license_info

print_license_info(data_type, data_source, asset_or_tar_id)
Source code in molmo_spaces/molmo_spaces_constants.py
def print_license_info(data_type, data_source, asset_or_tar_id):
    from molmo_spaces.utils.license_utils import resolve_license

    def get_identifiers():
        return [
            archive.replace(f"{data_source}_", "").replace(".tar.zst", "")
            for archive in get_resource_manager().find_all_packages_for_source(
                data_type, data_source
            )
        ]

    if asset_or_tar_id == "--list_all":
        print(f"Possible identifiers: {sorted(get_identifiers())}")
        return

    try:
        license_info = resolve_license(data_type, data_source, asset_or_tar_id)
        print(json.dumps(license_info, indent=2))
    except ValueError as e:
        import random

        archives = get_identifiers()
        formatted = "\n".join(sorted(random.choices(archives, k=min(len(archives), 10))))
        print(e)
        print(f"Possible identifiers:\n{formatted}{'...' if len(archives) > 10 else ''}")