diff --git a/include/neural-graphics-primitives/testbed.h b/include/neural-graphics-primitives/testbed.h
index 9459285110f29eb678dac7cd0c9063db5c2bef51..e88dd4576a765007dfdb23b0f8a91cfee9d41bbf 100644
--- a/include/neural-graphics-primitives/testbed.h
+++ b/include/neural-graphics-primitives/testbed.h
@@ -496,6 +496,8 @@ public:
 	void compute_and_save_marching_cubes_mesh(const char* filename, Eigen::Vector3i res3d = Eigen::Vector3i::Constant(128), BoundingBox aabb = {}, float thresh = 2.5f, bool unwrap_it = false);
 	Eigen::Vector3i compute_and_save_png_slices(const char* filename, int res, BoundingBox aabb = {}, float thresh = 2.5f, float density_range = 4.f, bool flip_y_and_z_axes = false);
 
+	fs::path root_dir();
+
 	////////////////////////////////////////////////////////////////
 	// marching cubes related state
 	struct MeshState {
@@ -935,6 +937,8 @@ public:
 		char video_path[MAX_PATH_LEN] = "video.mp4";
 	} m_imgui;
 
+	fs::path m_root_dir = "";
+
 	bool m_visualize_unit_cube = false;
 	bool m_edit_render_aabb = false;
 
diff --git a/scripts/run.py b/scripts/run.py
index d7b2054383b6eda31656629ce5dba0f2ed23514b..fce5b2a374335a4b2e247f53e255a517890e18d7 100644
--- a/scripts/run.py
+++ b/scripts/run.py
@@ -86,6 +86,7 @@ if __name__ == "__main__":
 		print("Warning: the '--mode' argument is no longer in use. It has no effect. The mode is automatically chosen based on the scene.")
 
 	testbed = ngp.Testbed()
+	testbed.root_dir = ROOT_DIR
 
 	for file in args.files:
 		scene_info = get_scene(file)
diff --git a/src/nerf_loader.cu b/src/nerf_loader.cu
index 69af304f8e3aed090d0ffe81fd46d38dcfd4e1af..9b91a4215e5f274af8fb5d93b605c490102b2a4a 100644
--- a/src/nerf_loader.cu
+++ b/src/nerf_loader.cu
@@ -744,6 +744,7 @@ void NerfDataset::set_training_image(int frame_idx, const Eigen::Vector2i& image
 	if (frame_idx < 0 || frame_idx >= n_images) {
 		throw std::runtime_error{"NerfDataset::set_training_image: invalid frame index"};
 	}
+
 	size_t n_pixels = image_resolution.prod();
 	size_t img_size = n_pixels * 4; // 4 channels
 	size_t image_type_stride = image_type_size(image_type);
diff --git a/src/python_api.cu b/src/python_api.cu
index 8a8d436405d11488fd550c77f5ff6468300cde91..fc95fe7b7a638e1ff69239dde456fd2fcc0c998c 100644
--- a/src/python_api.cu
+++ b/src/python_api.cu
@@ -529,6 +529,10 @@ PYBIND11_MODULE(pyngp, m) {
 		.def("crop_box", &Testbed::crop_box, py::arg("nerf_space") = true)
 		.def("set_crop_box", &Testbed::set_crop_box, py::arg("matrix"), py::arg("nerf_space") = true)
 		.def("crop_box_corners", &Testbed::crop_box_corners, py::arg("nerf_space") = true)
+		.def_property("root_dir",
+			[](py::object& obj) { return obj.cast<Testbed&>().root_dir().str(); },
+			[](const py::object& obj, const std::string& value) { obj.cast<Testbed&>().m_root_dir = value; }
+		)
 		;
 
 	py::class_<Lens> lens(m, "Lens");
diff --git a/src/testbed.cu b/src/testbed.cu
index 6f088bec62c0d9f0afc77ee98588ad4ab257a1e5..c212f96de628af14f5f0886ae8e1f83e4eb77957 100644
--- a/src/testbed.cu
+++ b/src/testbed.cu
@@ -223,7 +223,7 @@ fs::path Testbed::find_network_config(const fs::path& network_config_path) {
 		return network_config_path;
 	}
 
-	fs::path candidate = get_root_dir()/"configs"/to_string(m_testbed_mode)/network_config_path;
+	fs::path candidate = root_dir()/"configs"/to_string(m_testbed_mode)/network_config_path;
 	if (candidate.exists()) {
 		return candidate;
 	}
@@ -526,6 +526,14 @@ Eigen::Vector3i Testbed::compute_and_save_png_slices(const char* filename, int r
 	return res3d;
 }
 
+fs::path Testbed::root_dir() {
+	if (m_root_dir.empty()) {
+		m_root_dir = get_root_dir();
+	}
+
+	return m_root_dir;
+}
+
 inline float linear_to_db(float x) {
 	return -10.f*logf(x)/logf(10.f);
 }
@@ -2409,19 +2417,19 @@ void Testbed::prepare_next_camera_path_frame() {
 #ifdef _WIN32
 			// Under Windows, try automatically downloading FFmpeg binaries if they don't exist
 			if (system(fmt::format("where {} >nul 2>nul", ffmpeg.str()).c_str()) != 0) {
-				fs::path root_dir = get_root_dir();
-				if ((root_dir/"external"/"ffmpeg").exists()) {
-					for (const auto& path : fs::directory{root_dir/"external"/"ffmpeg"}) {
+				fs::path dir = root_dir();
+				if ((dir/"external"/"ffmpeg").exists()) {
+					for (const auto& path : fs::directory{dir/"external"/"ffmpeg"}) {
 						ffmpeg = path/"bin"/"ffmpeg.exe";
 					}
 				}
 
 				if (!ffmpeg.exists()) {
 					tlog::info() << "FFmpeg not found. Downloading FFmpeg...";
-					do_system((root_dir/"scripts"/"download_ffmpeg.bat").str());
+					do_system((dir/"scripts"/"download_ffmpeg.bat").str());
 				}
 
-				for (const auto& path : fs::directory{root_dir/"external"/"ffmpeg"}) {
+				for (const auto& path : fs::directory{dir/"external"/"ffmpeg"}) {
 					ffmpeg = path/"bin"/"ffmpeg.exe";
 				}
 
@@ -2994,7 +3002,7 @@ void Testbed::init_window(int resw, int resh, bool hidden, bool second_window) {
 	// Instead, we would like to place imgui.ini in the directory that instant-ngp project
 	// resides in.
 	static std::string ini_filename;
-	ini_filename = (get_root_dir()/"imgui.ini").str();
+	ini_filename = (root_dir()/"imgui.ini").str();
 	io.IniFilename = ini_filename.c_str();
 
 	// New ImGui event handling seems to make camera controls laggy if input trickling is true.
diff --git a/src/testbed_nerf.cu b/src/testbed_nerf.cu
index ba563a6d1115ebd38bbe864e1e99bc6c44d326a5..bdc35f1256a1272900b21cf3840219e97f0c33e2 100644
--- a/src/testbed_nerf.cu
+++ b/src/testbed_nerf.cu
@@ -2683,10 +2683,7 @@ void Testbed::load_nerf(const fs::path& data_path) {
 
 		// Check if the NeRF network has been previously configured.
 		// If it has not, don't reset it.
-		bool previously_configured = !m_network_config["rgb_network"].is_null()
-		                          && !m_network_config["dir_encoding"].is_null();
-
-		if (m_nerf.training.dataset.aabb_scale != prev_aabb_scale && previously_configured) {
+		if (m_nerf.training.dataset.aabb_scale != prev_aabb_scale && m_nerf_network) {
 			// The AABB scale affects network size indirectly. If it changed after loading,
 			// we need to reset the previously configured network to keep a consistent internal state.
 			reset_network();