def _merge_parameters(self, other_trajectory, remove_duplicates=False,<EOL>trial_parameter_name=None,<EOL>ignore_data=()):
if trial_parameter_name:<EOL><INDENT>if remove_duplicates:<EOL><INDENT>self._logger.warning('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL>remove_duplicates = False<EOL><DEDENT><DEDENT>params_to_change = {}<EOL>if trial_parameter_name:<EOL><INDENT>my_trial_parameter = self.f_get(trial_parameter_name)<EOL>other_trial_parameter = other_trajectory.f_get(trial_parameter_name)<EOL>if not isinstance(my_trial_parameter, BaseParameter):<EOL><INDENT>raise TypeError('<STR_LIT>'<EOL>'<STR_LIT>' % trial_parameter_name)<EOL><DEDENT>if my_trial_parameter.f_has_range():<EOL><INDENT>my_trial_list = my_trial_parameter.f_get_range(copy=False)<EOL><DEDENT>else:<EOL><INDENT>my_trial_list = [my_trial_parameter.f_get()]<EOL><DEDENT>if other_trial_parameter.f_has_range():<EOL><INDENT>other_trial_list = other_trial_parameter.f_get_range(copy=False)<EOL><DEDENT>else:<EOL><INDENT>other_trial_list = [other_trial_parameter.f_get()]<EOL><DEDENT>mytrialset = set(my_trial_list)<EOL>mymaxtrial_T1 = max(mytrialset)  <EOL>if mytrialset != set(range(mymaxtrial_T1 + <NUM_LIT:1>)):<EOL><INDENT>raise TypeError('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' % (mymaxtrial_T1, str(mytrialset)))<EOL><DEDENT>othertrialset = set(other_trial_list)<EOL>othermaxtrial_T2 = max(othertrialset)  <EOL>if othertrialset != set(range(othermaxtrial_T2 + <NUM_LIT:1>)):<EOL><INDENT>raise TypeError('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(othermaxtrial_T2, str(othertrialset)))<EOL><DEDENT>trial_parameter_name = my_trial_parameter.v_full_name<EOL>if not trial_parameter_name in self._explored_parameters:<EOL><INDENT>self._explored_parameters[trial_parameter_name] = my_trial_parameter<EOL><DEDENT>params_to_change[trial_parameter_name] = (my_trial_parameter, other_trial_parameter)<EOL><DEDENT>params_to_merge = other_trajectory._parameters.copy()<EOL>params_to_merge.update(other_trajectory._derived_parameters)<EOL>for ignore in ignore_data:<EOL><INDENT>if ignore in params_to_merge:<EOL><INDENT>del params_to_merge[ignore]<EOL><DEDENT><DEDENT>run_name_dummys = set([f(-<NUM_LIT:1>) for f in other_trajectory._wildcard_functions.values()])<EOL>for key in params_to_merge:<EOL><INDENT>other_param = params_to_merge[key]<EOL>split_key = key.split('<STR_LIT:.>')<EOL>if any(x in other_trajectory._reversed_wildcards for x in split_key):<EOL><INDENT>continue<EOL><DEDENT>my_param = self.f_get(key)<EOL>if not my_param._values_of_same_type(my_param.f_get(), other_param.f_get()):<EOL><INDENT>raise TypeError('<STR_LIT>'<EOL>'<STR_LIT>' % key)<EOL><DEDENT>if my_param.v_full_name == trial_parameter_name:<EOL><INDENT>continue<EOL><DEDENT>if (my_param.f_has_range() or<EOL>other_param.f_has_range() or<EOL>not my_param._equal_values(my_param.f_get(), other_param.f_get())):<EOL><INDENT>params_to_change[key] = (my_param, other_param)<EOL>if not my_param.f_has_range() and not other_param.f_has_range():<EOL><INDENT>remove_duplicates = False<EOL><DEDENT><DEDENT><DEDENT>used_runs = {}<EOL>for idx in range(len(other_trajectory)):<EOL><INDENT>used_runs[idx] = idx<EOL><DEDENT>if remove_duplicates:<EOL><INDENT>for irun in range(len(other_trajectory)):<EOL><INDENT>for jrun in range(len(self)):<EOL><INDENT>change = True<EOL>for my_param, other_param in params_to_change.values():<EOL><INDENT>if other_param.f_has_range():<EOL><INDENT>other_param._set_parameter_access(irun)<EOL><DEDENT>if my_param.f_has_range():<EOL><INDENT>my_param._set_parameter_access(jrun)<EOL><DEDENT>val1 = my_param.f_get()<EOL>val2 = other_param.f_get()<EOL>if not my_param._equal_values(val1, val2):<EOL><INDENT>change = False<EOL>break<EOL><DEDENT><DEDENT>if change:<EOL><INDENT>del used_runs[irun]<EOL>break<EOL><DEDENT><DEDENT><DEDENT>for my_param, other_param in params_to_change.values():<EOL><INDENT>other_param._restore_default()<EOL>my_param._restore_default()<EOL><DEDENT><DEDENT>adding_length = len(used_runs)<EOL>starting_length = len(self)<EOL>if adding_length == <NUM_LIT:0>:<EOL><INDENT>return used_runs, []<EOL><DEDENT>count = <NUM_LIT:0><EOL>for key in sorted(used_runs.keys()):<EOL><INDENT>used_runs[key] = starting_length + count<EOL>count += <NUM_LIT:1><EOL><DEDENT>for my_param, other_param in params_to_change.values():<EOL><INDENT>fullname = my_param.v_full_name<EOL>if fullname == trial_parameter_name:<EOL><INDENT>other_range = [x + mymaxtrial_T1 + <NUM_LIT:1> for x in other_trial_list]<EOL><DEDENT>else:<EOL><INDENT>if other_param.f_has_range():<EOL><INDENT>other_range = (x for jdx, x in enumerate(other_param.f_get_range(copy=False))<EOL>if jdx in used_runs)<EOL><DEDENT>else:<EOL><INDENT>other_range = (other_param.f_get() for _ in range(adding_length))<EOL><DEDENT><DEDENT>if not my_param.f_has_range():<EOL><INDENT>my_param.f_unlock()<EOL>my_param._explore((my_param.f_get() for _ in  range(len(self))))<EOL><DEDENT>my_param.f_unlock()<EOL>my_param._expand(other_range)<EOL>if not fullname in self._explored_parameters:<EOL><INDENT>self._explored_parameters[fullname] = my_param<EOL><DEDENT><DEDENT>return used_runs, list(params_to_change.keys())<EOL>
Merges parameters from the other trajectory into the current one.

        The explored parameters in the current trajectory are directly enlarged (in RAM),
        no storage service is needed here. Later on in `f_merge` the storage service
        will be requested to store the enlarge parameters to disk.

        Note explored parameters are always enlarged. Unexplored parameters might become
        new explored parameters if they differ in their default values
        in the current and the other trajectory, respectively.

        :return: A tuple with two elements:

            1.

                Dictionary of run index mappings from old trajectroy to the new one.

            2.

                List of names of parameters that were altered.