def test_read_format_1_non_default_vals(self): app_folder_prefix = get_app_folder() + os.path.sep version1_content = dedent(""" app_preferences: app_height: 800 app_width: 1000 console_logging_level: 30 log_folder: {0}log python_script_folder: {0}python_scripts user_ds_folder: {0}user_datasource solver_preferences: auto_delete_solver_files_on_exit: true cadet_num_threads: 2 executor: ProcessPoolExecutor executor_num_worker: {1} input_file_location: {0}cadet_input_files ui_preferences: remember_layout: false version: 1 """.format(app_folder_prefix, NUM_CPU)) with open(self.filepath, "w") as f: f.write(version1_content) loaded = RevealChromatographyPreferences.from_preference_file( self.filepath) modified_prefs = self.default_prefs # Modify the default prefs to match the choices made in text above: modified_prefs.ui_preferences.app_width = 1000 modified_prefs.ui_preferences.app_height = 800 modified_prefs.solver_preferences.cadet_num_threads = 2 modified_prefs.dirty = False assert_has_traits_almost_equal(loaded, modified_prefs)
def test_build_product_with_comp_expert_mode(self): """ Test that builder in expert mode can rebuild PROD000. """ original_prod0 = self.ds.get_objects_by_type("products", {"name": "Prod000"})[0] comp_names = [c.name for c in original_prod0.product_components] self.builder.name = "Prod000" self.builder.product_type = "Globular" self.builder.pI = UnitScalar(7.52, units='1') self.builder.expert_mode = True # In expert mode, we set the list of assay names and component names # and expressions: for name in comp_names: assay_name = "CEX_{}".format(name) exp = "product_concentration * {} / 100".format(assay_name) comp_desc = ComponentDescription(name=name, concentration_exps=exp) self.builder.component_descs.append(comp_desc) assay = ProductComponentAssay(name=assay_name) self.builder.component_assay_names.append(assay) prod = self.builder.build_product(allow_ui=False) ignore = ["amino_acids", "amino_acid_numbers"] assert_has_traits_almost_equal(prod, original_prod0, ignore=ignore) # In expert mode, add_strip is ignored: self.builder.add_strip = True prod = self.builder.build_product(allow_ui=False) ignore = ["amino_acids", "amino_acid_numbers"] assert_has_traits_almost_equal(prod, original_prod0, ignore=ignore)
def test_update_starting_sim_from_name(self): """ Changing starting point sim should trigger a recomputation of cp """ optim_builder = self.make_optimizer_builder() optim_builder.experiment_selected = ['Run_1'] self.assertEqual(optim_builder.starting_point_simulation_name, 'Sim: Run_1') self.assertEqual(len(optim_builder.starting_point_simulations), 1) first_cp = optim_builder.starting_point_simulations[0] self.assertIsNot(first_cp, self.sim1) assert_has_traits_almost_equal(first_cp, self.sim1, check_type=False) with self.assertTraitChanges(optim_builder, "starting_point_simulations", 1): optim_builder.starting_point_simulation_name = 'Sim: Run_2' first_cp = optim_builder.starting_point_simulations[0] self.assertEqual(len(optim_builder.starting_point_simulations), 1) # The target experiment is still Run_1 so the resulting sim ~ sim1 assert_has_traits_almost_equal(first_cp, self.sim1, check_type=False) self.assertIsInstance(first_cp, LazyLoadingSimulation) # But several quantities are pulled from the specified starting point self.assertEqual(first_cp.method.method_steps[0].name, self.sim2.method.method_steps[0].name) self.assertEqual(first_cp.method.method_steps[-1].name, self.sim2.method.method_steps[-1].name) # Choosing a different name with self.assertTraitDoesNotChange(optim_builder, "starting_point_simulations"): with self.assertRaises(KeyError): # Reraise the exception because it happens in listener with reraise_traits_notification_exceptions(): optim_builder.starting_point_simulation_name = \ "DOESN'T EXIST!"
def test_study_datasource_from_adding_experiment(self): study = self.study ds = study.study_datasource # Initially the datasource is blank assert_has_traits_almost_equal(ds, InStudyDataSource(), ignore=["name"]) experim1, _ = load_default_experiment_simulation(expt_id='Run_1') study.add_experiments(experim1) # Check that the method was collected self.assertEqual([experim1.method], ds.object_catalog["methods"]) # Check that the solutions were collected solutions = [] for step in experim1.method.method_steps: solutions += step.solutions for sol in solutions: found = (sol in ds.object_catalog["loads"] or sol in ds.object_catalog["buffers"]) assert found # Adding another times the same experiment doesn't change the : # object_catalog study.add_experiments(experim1) self.assertEqual([experim1.method], ds.object_catalog["methods"])
def test_lazy_sim_run_to_std_sim(self): # Make the run sim's filepath created copyfile(self.result_filepath, self.sim_run.cadet_filepath) lazy_sim = LazyLoadingSimulation.from_simulation(self.sim_run) new_std_sim = lazy_sim.to_simulation() assert_has_traits_almost_equal(new_std_sim, self.sim_run, ignore=('uuid', ))
def test_selection(self): target_prod = self.ds.get_object_names_by_type("products")[0] self.prod_chooser.selected_product_name = target_prod expected = self.ds.get_object_of_type("products", target_prod) assert_has_traits_almost_equal(self.prod_chooser.selected_product, expected) assert (self.prod_chooser.selected_product is not expected)
def test_load_same_file_twice(self): filename = "demo_with_optimizerv8.chrom" obj1, _ = load_object(io_data_path(filename)) obj2, _ = load_object(io_data_path(filename)) # Make sure they are identical without being the same object: assert_has_traits_almost_equal(obj1, obj2, eps=1e-15) self.assertIsNot(obj1, obj2) self.assertIsNot(obj1.project.study, obj2.project.study)
def assert_old_file_read(filename, reference_task, ignore=(), eps=1e-9): with reraise_traits_notification_exceptions(): obj, legacy = load_object(io_data_path(filename)) assert_has_traits_almost_equal(obj.project, reference_task.project, ignore=ignore, eps=eps) assert_true(legacy)
def test_save_ds_to_file_default_loc(self): ds = load_default_user_datasource()[0] filename = save_user_datasource_to(ds) try: self.assertEqual(split(filename)[0], get_user_ds_folder()) ds2, filename2 = load_default_user_datasource() self.assertEqual(filename, filename2) assert_has_traits_almost_equal(ds, ds2) finally: os.remove(filename)
def test_get_set_product_name(self): view = self._get_model_view() self.assertEqual(view.product_name, 'NO PRODUCT SET') with self.assertRaises(DataSourceLookupError): view.product_name = 'Foo' desired_prod = 'Prod001' view.product_name = desired_prod self.assertEqual(view.product_name, desired_prod) prod = self.ds.get_object_of_type('products', desired_prod) assert_has_traits_almost_equal(self.model.product, prod)
def assert_output_close_to_reference(self, sim): """ Make sure the output data is close to identical. """ ref_perf_data = self.real_sim.output.performance_data ref_cont_data = self.real_sim.output.continuous_data assert_has_traits_almost_equal(sim.output.performance_data, ref_perf_data, eps=1e-5, ignore=('name', )) assert_values_almost_equal(sim.output.continuous_data, ref_cont_data, eps=8.e-5)
def test_multiple_target_exp_at_creation(self): """ Changing target experiments should trigger recomputing cp sims. """ optim_builder = self.make_optimizer_builder('Run_1', 'Run_2') self.assertEqual(len(optim_builder.starting_point_simulations), 2) first_cp = optim_builder.starting_point_simulations[0] second_cp = optim_builder.starting_point_simulations[1] # The target experiment is still Run_1 so the resulting sim ~ sim1 assert_has_traits_almost_equal(first_cp, self.sim1, check_type=False) assert_has_traits_almost_equal(second_cp, self.sim2, check_type=False) self.assertIsInstance(first_cp, LazyLoadingSimulation) self.assertIsInstance(second_cp, LazyLoadingSimulation)
def test_run_save_bring_back(self): # Ensure/fake a round-off error on disk self.sim.section_times[-1] -= 1e-12 save_object(self.test_file, self.sim) new_sim, _ = load_object(self.test_file) # Precision must be reduced because for the new simulation, the # section_times will be recomputed. assert_has_traits_almost_equal(new_sim, self.sim, eps=1e-11) # This is NOT assertAlmostEqual, because these 2 numbers must be # completely identical for CADET2 not to CRASH! assert_equal(new_sim.section_times[-1], new_sim.solver.user_solution_times[-1])
def test_write_read_roundtrip(self): object_to_save = self.study writer = LocalFileWriter(filepath=self.test_file, serialize=serialize) writer.save(object_to_save) reader = LocalFileReader(filepath=self.test_file, deserialize=deserialize) new_object, _ = reader.load() # Ignore the datasource and dirty flag since not stored when storing a # study: assert_has_traits_almost_equal(new_object, object_to_save, ignore=['datasource', 'dirty'])
def test_paste_lazy_sim_into_simulation_list(self): sim_list = self.study.simulations existing = len(sim_list) sim = self.study.simulations[0].copy() sim.name = "NEW NAME TO AVOID COLLISION" sim = LazyLoadingSimulation.from_simulation(sim) clipboard.instance = sim self.right_click_on_list_and_action(self.study, "simulations", "Paste") self.assertEqual(len(sim_list), existing + 1) # Not the same object because the sim was converted to regular sim so # that it doesn't cause issues when pasting self.assertIsNot(sim_list[-1], sim) assert_has_traits_almost_equal(sim_list[-1], sim, check_type=False)
def test_update_experiment_selector(self): """ Changing target experiments should trigger recomputating starting center point simulations. """ optim_builder = self.make_optimizer_builder() self.assertEqual(len(optim_builder.starting_point_simulations), 0) optim_builder.experiment_selector = ExperimentSelector( study=self.study, experiment_selected=['Run_1', 'Run_2']) self.assertEqual(len(optim_builder.starting_point_simulations), 2) first_cp = optim_builder.starting_point_simulations[0] second_cp = optim_builder.starting_point_simulations[1] # The target experiment is still Run_1 so the resulting sim ~= sim1 assert_has_traits_almost_equal(first_cp, self.sim1, check_type=False) assert_has_traits_almost_equal(second_cp, self.sim2, check_type=False) self.assertIsInstance(first_cp, LazyLoadingSimulation) self.assertIsInstance(second_cp, LazyLoadingSimulation)
def assertValidSimulations(self, sims, target_study, fstep='Load', lstep="Strip", check_product=True): existing_sim_names = [sim.name for sim in target_study.simulations] for sim in sims: self.assertNotIn(sim.name, existing_sim_names) self.assertIsInstance(sim.method, Method) self.assertEqual(sim.method.method_steps[0].name, fstep) self.assertEqual(sim.method.method_steps[-1].name, lstep) self.assertIsInstance(sim.transport_model, TransportModel) self.assertIsInstance(sim.binding_model, BindingModel) source_exp = sim.source_experiment assert_has_traits_almost_equal(source_exp.column, sim.column) self.assertIsNot(source_exp.column, sim.column) if check_product: assert_has_traits_almost_equal(source_exp.product, sim.product)
def assertValidCopy(self, new_sim, orig_sim): """ Test that a copy leads to identical attributes except run related. """ self.assertIsInstance(new_sim, orig_sim.__class__) # copies have no output self.assertIsNone(new_sim.output) # Copies use the same buffer in every step self.assertTrue(new_sim.editable) # All uses of buffers are the same object buffers = {} for step in new_sim.method.method_steps: for solution in step.solutions: if isinstance(solution, Buffer): if solution.name in buffers: self.assertIs(solution, buffers[solution.name]) else: buffers[solution.name] = solution # All subobjects are equal except the outputs, the editable flag # and the events attributes. skip_attr = { "output", "editable", "has_run", "uuid", "cadet_filename", "cadet_filepath" } relevant_attrs = set(new_sim.trait_names()) - skip_attr for attr in relevant_attrs: if is_trait_event(orig_sim, attr): continue val1, val2 = getattr(new_sim, attr), getattr(orig_sim, attr) if isinstance(val1, HasTraits): assert_has_traits_almost_equal(val1, val2) else: assert_values_almost_equal(val1, val2) # The uuid and cadet input files on the other hand is guaranteed to be # different self.assertNotEqual(orig_sim.uuid, new_sim.uuid) self.assertNotEqual(orig_sim.cadet_filename, new_sim.cadet_filename) self.assertNotEqual(orig_sim.cadet_filepath, new_sim.cadet_filepath)
def test_update_target_exp_after_creation(self): """ Changing target experiments should trigger recomputing starting center point simulations. """ optim_builder = self.make_optimizer_builder() optim_builder.experiment_selected = ['Run_1'] # Change by overwriting with self.assertTraitChanges(optim_builder, "starting_point_simulations", 1): optim_builder.experiment_selected = ['Run_2'] first_cp = optim_builder.starting_point_simulations[0] self.assertEqual(len(optim_builder.starting_point_simulations), 1) # The target experiment is still Run_1 so the resulting sim ~ sim1 assert_has_traits_almost_equal(first_cp, self.sim2, check_type=False) self.assertIsInstance(first_cp, LazyLoadingSimulation) # Change by append to the list of target experiences: with self.assertTraitChanges(optim_builder, "starting_point_simulations", 1): optim_builder.experiment_selected.append('Run_1') self.assertEqual(len(optim_builder.starting_point_simulations), 2) first_cp = optim_builder.starting_point_simulations[0] second_cp = optim_builder.starting_point_simulations[1] # The target experiment is still Run_1 so the resulting sim ~ sim1 assert_has_traits_almost_equal(first_cp, self.sim2, check_type=False) assert_has_traits_almost_equal(second_cp, self.sim1, check_type=False) self.assertIsInstance(first_cp, LazyLoadingSimulation) self.assertIsInstance(second_cp, LazyLoadingSimulation)
def test_build_product_with_comp_simplified_mode(self): """ Modify PROD000 and make sure builder can rebuild it (no strip). Simplify its component and assay names, and make sure the simplified builder with add_strip=False can rebuild it. """ orig_prod0 = self.ds.get_objects_by_type("products", {"name": "Prod000"})[0] comp_names = [c.name for c in orig_prod0.product_components] # Change the assays to be named like the components since the # simplified mode only supports that: orig_assays = ['CEX_Acidic_2', 'CEX_Acidic_1', 'CEX_Native'] self.assertEqual(orig_prod0.product_component_assays, orig_assays) orig_prod0.product_component_assays = comp_names exps = ["product_concentration * CEX_{} / 100".format(name) for name in comp_names] orig_conc_exps = Series(exps, index=comp_names) assert_series_equal(orig_prod0.product_component_concentration_exps, orig_conc_exps) new_exps = ["product_concentration * {} / 100".format(name) for name in comp_names] orig_prod0.product_component_concentration_exps = \ Series(new_exps, index=comp_names) self.builder.name = "Prod000" self.builder.product_type = "Globular" self.builder.pI = UnitScalar(7.52, units='1') self.builder.expert_mode = False self.builder.add_strip = False # In simplified mode, we just set a list of component names: for name in comp_names: comp_desc = ComponentDescription(name=name) self.builder.component_descs.append(comp_desc) prod = self.builder.build_product(allow_ui=False) ignore = ["amino_acids", "amino_acid_numbers"] assert_has_traits_almost_equal(prod, orig_prod0, ignore=ignore)
def test_std_sim_run_to_lazy_sim(self): """ Creating a Lazy sim from a run sim, with or without CADET file. """ lazy_sim = LazyLoadingSimulation.from_simulation(self.sim_run) # With missing cadet file, the lazy copy isn't run: ignore = ('uuid', 'has_run', 'run_status', 'output', 'editable') assert_has_traits_almost_equal(lazy_sim, self.sim_run, check_type=False, ignore=ignore) self.assertFalse(lazy_sim.has_run) self.assertTrue(lazy_sim.editable) # With cadet file, the lazy sim is run: copyfile(self.result_filepath, self.sim_run.cadet_filepath) try: lazy_sim2 = LazyLoadingSimulation.from_simulation(self.sim_run) assert_has_traits_almost_equal(lazy_sim2, self.sim_run, check_type=False, ignore=('uuid', )) finally: os.remove(self.sim_run.cadet_filepath)
def test_read_format_2_non_default_vals(self): app_folder_prefix = get_app_folder() + os.path.sep version2_content = """ app_preferences: console_logging_level: 30 log_folder: {0}log python_script_folder: {0}python_scripts user_ds_folder: {0}user_datasource optimizer_preferences: optimizer_step_chunk_size: 100 max_in_memory_group_size: 50 solver_preferences: auto_delete_solver_files_on_exit: true cadet_num_threads: 2 executor_num_worker: {1} input_file_location: {0}cadet_input_files solver_binary_path: cadet-cs{2} ui_preferences: app_height: 800 app_width: 1000 auto_close_empty_windows_on_open: true confirm_on_window_close: true remember_layout: false version: 2 """.format(app_folder_prefix, NUM_CPU, CADET_EXT) with open(self.filepath, "w") as f: f.write(version2_content) loaded = RevealChromatographyPreferences.from_preference_file( self.filepath) modified_prefs = self.default_prefs # Modify the default prefs to match the choices made in text above: modified_prefs.ui_preferences.app_width = 1000 modified_prefs.ui_preferences.app_height = 800 modified_prefs.solver_preferences.cadet_num_threads = 2 modified_prefs.dirty = False assert_has_traits_almost_equal(loaded, modified_prefs)
def test_build_product_with_comp_simplified_mode_with_strip(self): """ Modify PROD000 and make sure builder can rebuild it (with strip). Add a strip to it, and change its component and assay names, and make sure the simplified building with the add_strip=True. """ orig_prod0 = self.ds.get_objects_by_type("products", {"name": "Prod000"})[0] comp_names = [c.name for c in orig_prod0.product_components] # Change the assays to be named like the components since the # simplified mode only supports that: orig_prod0.product_component_assays = comp_names new_exps = ["product_concentration * {} / 100".format(name) for name in comp_names] orig_prod0.product_component_concentration_exps = \ Series(new_exps, index=comp_names) # Modify the prod to add a strip new_prod, strip_comp = add_strip_to_product(orig_prod0) # Rebuild prod0 with the builder: self.builder.name = new_prod.name self.builder.product_type = "Globular" self.builder.pI = UnitScalar(7.52, units='1') self.builder.expert_mode = False self.builder.add_strip = True for comp in new_prod.product_components: name = comp.name if name != STRIP_COMP_NAME: self.ds.set_object_of_type("product_components", comp) comp_desc = ComponentDescription(name=name) self.builder.component_descs.append(comp_desc) prod = self.builder.build_product(allow_ui=False) ignore = ["amino_acids", "amino_acid_numbers", "name"] assert_has_traits_almost_equal(prod, new_prod, ignore=ignore)
def test_conversion_brute_force_with_custom_discretization(self): p1name = "binding_model.sma_ka[1]" p1 = ParameterScanDescription(name=p1name) traits = { "parameter_scans": [p1], "optimizer_type": GRID_BASED_OPTIMIZER_TYPE } builder = make_sample_optimizer_builder(self.study, self.exp_name, **traits) # Customize discretization sim0 = self.study.search_simulation_by_name( builder.starting_point_simulation_name) sim0.discretization.ncol = 30 builder.update_starting_point_simulations() optimizer = optimizer_builder_to_optimizer(builder) self.assertIsInstance(optimizer, BruteForceOptimizer) self.assertEqual(optimizer.size, DEFAULT_NUM_VALUES) self.assertEqual(len(optimizer.steps), 1) # Make sure the custom discretization was reused: for step in optimizer.steps: for group in step.simulation_groups: cp = group.center_point_simulation assert_has_traits_almost_equal(cp.discretization, sim0.discretization)
def test_get_step_by_name(self): with self.assertRaises(ValueError): self.method.get_step_of_name("") step = self.method.get_step_of_name('Pre-Equilibration') assert_has_traits_almost_equal(step, MethodStep(**PRE_EQUIL_STEP)) step = self.method.get_step_of_name('whatever name') assert_has_traits_almost_equal(step, MethodStep(**LOAD_STEP)) # Collect step number step, num = self.method.get_step_of_name('whatever name', collect_step_num=True) assert_has_traits_almost_equal(step, MethodStep(**LOAD_STEP)) self.assertEqual(num, 2) # Don't raise on failures self.method.get_step_of_name("", handle_not_unique='warn')
def test_get_step(self): with self.assertRaises(ValueError): self.method.get_step_of_type("") step = self.method.get_step_of_type('Pre-Equilibration') assert_has_traits_almost_equal(step, MethodStep(**PRE_EQUIL_STEP)) step = self.method.get_step_of_type('Gradient Elution') assert_has_traits_almost_equal(step, MethodStep(**GRADIENT_ELUTION_STEP)) # Collect step number step, num = self.method.get_step_of_type('Pre-Equilibration', collect_step_num=True) assert_has_traits_almost_equal(step, MethodStep(**PRE_EQUIL_STEP)) self.assertEqual(num, 0) # Don't raise on failures self.method.get_step_of_type("", handle_not_unique='warn')
def test_lazy_sim_not_run_to_lazy_sim(self): # Make the run sim's filepath created copyfile(self.result_filepath, self.sim_run.cadet_filepath) lazy_sim = LazyLoadingSimulation.from_simulation(self.sim) lazy_sim2 = LazyLoadingSimulation.from_simulation(lazy_sim) assert_has_traits_almost_equal(lazy_sim, lazy_sim2, ignore=('uuid', ))
def test_lazy_sim_not_run_to_std_sim(self): lazy_sim = LazyLoadingSimulation.from_simulation(self.sim) new_std_sim = lazy_sim.to_simulation() assert_has_traits_almost_equal(new_std_sim, self.sim, ignore=('uuid', ))
def test_std_sim_not_run_to_lazy_sim(self): lazy_sim = LazyLoadingSimulation.from_simulation(self.sim) assert_has_traits_almost_equal(lazy_sim, self.sim, check_type=False, ignore=('uuid', ))
def test_product_selection(self): target_prod = self.datasource.get_object_names_by_type("products")[0] self.sim_builder.product_name = target_prod exp = self.datasource.get_object_of_type("products", target_prod) assert_has_traits_almost_equal(self.sim_builder.product, exp)