def _check_error_dir(output_dir, save, standalone):
    """ Input consistency check
	"""
    if save and output_dir is None:
        print("Specify output_dir to save parameter files")
        raise ValueError
    if standalone and save:
        fu.assert_dir(output_dir, should_be_empty=True)
	def generate_paths(self):
		param_paths=[HUMAN_WEBOT_NMM_PATH+"config/2D_ind"+str(i)+
					"/gaits/current" for i in range(1,self.nb_ind+1)]
		log_paths=[HUMAN_WEBOT_NMM_PATH+"log/log_ind"+str(i)
					for i in range(1,self.nb_ind+1)]
		worlds_paths=[HUMAN_WEBOT_NMM_PATH+"webots/worlds/tmp_2D_noObstacle_GA_2Dind"+str(i)+
					".wbt" for i in range(1,self.nb_ind+1)]
		for p_path,l_path,w_path in zip(param_paths, log_paths,worlds_paths):
			fu.assert_dir(l_path)
			s1=fu.assert_file_exists(p_path, should_exist=True)
			s2=fu.assert_file_exists(w_path, should_exist=True)
			if not s1 or not s2:
				print(s1,p_path)
				print(s2,w_path)
				raise RuntimeError("Missing worlds or parameter path, see Readme webots files generation")
		self.param_path=param_paths
		self.log_path=log_paths
		self.world_path=worlds_paths
def gen_all_file(param_file,
                 output_dir=None,
                 standalone=False,
                 nested=False,
                 save=False):
    """ Generates all pairs {param_name:value} required by param_file 
	(see data/sensi_template,yaml for reference)

	"""
    _check_error_dir(output_dir, save, standalone)
    all_params = yaml.load(open(param_file, 'r'), Loader=yaml.FullLoader)
    file_counter = 1
    files = []
    for name, parameters in all_params.items():
        if LOG_LEVEL <= LOG_DEBUG:
            print("[DEBUG] Reading:\t Name:", name, "\nParameters:",
                  parameters)
        if nested and save:
            rdir = os.path.join(output_dir, name)
            fu.assert_dir(rdir, should_be_empty=True)
        elif save:
            rdir = output_dir
        else:
            rdir = None

        if parameters[0] == "single":
            files.append(
                gen_single(parameters[1:], name, output_dir=rdir, save=save))

        elif parameters[0] == "range":
            files.append(
                gen_range(parameters[1:], name, output_dir=rdir, save=save))

        elif parameters[0] == "modrange":
            files.append(
                gen_modrange(parameters[1:], name, output_dir=rdir, save=save))
        elif parameters[0] == "dual_modrange":
            files.append(
                gen_dual_modrange(parameters[1:],
                                  name,
                                  output_dir=rdir,
                                  save=save))
    return files, list(all_params.keys())
	def __init__(self,args):
		if args is not None:
			for arg_name,arg_value in args.items():
				if hasattr(self, arg_name):
					setattr(self, arg_name, arg_value)
			if LOG_LEVEL<=LOG_INFO:
				print("\n[INFO]Launcher ",self.__class__.__name__," initialized with\n",self.__dict__)

		if self.trial_dir is None:
			self.trial_dir = os.path.join(ROOT_RESULT_DIR, time.strftime("%j_%H:%M"))
			fu.assert_dir(self.trial_dir,should_be_empty=True)
		try:
			self.worlds = fu.file_list(self.worlds_dir, file_format=".wbt")
		except FileNotFoundError:
			if LOG_LEVEL<=LOG_WARNING:
				print("\n[WARNING]No world file in\n",worlds_dir,"\nignore if optimization")
		except AttributeError:
			if LOG_LEVEL<=LOG_WARNING:
				print("\n[WARNING]No world directory,ignore if optimization")
		self.generate_paths()
	def generate_paths(self):
		"""
			Python implementation not suitable for this method at the time of
			this project, see generate_paths in CppLauncher for reference
		"""
		param_paths=[H2D_PATH+"modeling/configFiles/Controllers/current"+str(i)
			+".yaml" for i in range(self.nb_ind)]
		log_paths=[H2D_PATH+"webots/controllers/GeyerReflex/Raw_files"+str(i)
					for i in range(self.nb_ind)]
		worlds_paths=[H2D_PATH+"webots/worlds/current"+str(i)+
					".wbt" for i in range(self.nb_ind)]
		for p_path,l_path,w_path in zip(param_paths, log_paths,worlds_paths):
			fu.assert_dir(l_path)
			s1=fu.assert_file_exists(p_path, should_exist=True)
			s2=fu.assert_file_exists(w_path, should_exist=True)
			if not s1 or not s2:
				raise RuntimeError("Missing worlds or parameter path, see Readme")
		self.param_path=param_paths
		self.log_path=log_paths
		self.world_path=worlds_paths
		raise NotImplementedError
    def __init__(self, ev_config):
        """ Evolution controller initialisation
				
				Initialization of the evolution controller arguments, creation of
				the optimizer object and the trial directory, where the relevant 
				optimisation parameters are saved
				Input:
				- ev_config: dict containing all configuration for the evolution,
					read from the .yaml file specified at launch 
					(see ev_config_template.yaml)				
				Dependencies:
				optimizers
				
		"""
        self.__dict__.update(ev_config)

        self.trial_dir = os.path.join(ROOT_RESULT_DIR,
                                      time.strftime("%j_%H:%M"))
        assert_dir(self.trial_dir, should_be_empty=True)
        with open(os.path.join(self.trial_dir, "ev_params.yaml"),
                  "w+") as outparams:
            yaml.dump(ev_config, outparams, default_flow_style=False)

        if self.optimizer_name == "NSGAII":
            self.union_pop = True
            self.opti = NSGAIIOptimizer(ev_config)
        elif self.optimizer_name == "GA":
            self.union_pop = False
            self.opti = GAOptimizer(ev_config)
        elif self.optimizer_name == "PSO":
            self.union_pop = False
            self.opti = PSOptimizer(ev_config)
        else:
            if LOG_LEVEL <= LOG_ERROR:
                print("\n[ERROR]Unknown optimizer name\n", self.optimizer_name)
            raise ValueError

        self.nb_gen = 0
        self.flatten_params()
        self.current_pop = None
if __name__ == '__main__':
	mode=sys.argv[1]
	param=sys.argv[2:]
	if mode=="plot_with_success":
		run_dir = param[0]
		#ref_dir=param[1]
		metrics=["maxtime",	"distance",	"mean_speed",	"energy","energy_to_dist","corankle","corhip","corknee"]
		disc_params=[0.0, 19.0, 19.0, 19.0, 19.0, 19.0,19.0,19.0]
		do_save=True
		gen_dirs=fu.dir_list(run_dir,"param")

		for metric,disc_param in zip(metrics,disc_params):
			if do_save:
				save_path=os.path.join(run_dir,"figures",metric)
				fu.assert_dir(save_path)
			else:
				save_path=None
			if len(gen_dirs)>0:
				for gen_dir in gen_dirs:
					ind_dirs=fu.dir_list(gen_dir,pattern="ind")
					plot_with_success(	ind_dirs,metric,disc_name='maxtime',
										disc_params=disc_param,what="max_value",save_path=save_path)
			else:
				ind_dirs=fu.dir_list(run_dir,pattern="ind")
				plot_with_success(	ind_dirs,metric,disc_name='maxtime',
									disc_params=disc_param,what="max_value",save_path=save_path)
						
	elif mode=="export_joined_df":
		"""
		python process_run.py export_joined_df /data/prevel/runs/dual_modrange_SOL_TA/param1/ 4000 /data/prevel/runs/dual_modrange_SOL_TA/met.csv
	def run_batch(self,mode,*args):
		""" Implementation of different run launching modes

			 - parallel_sensitivity_analysis :
				Generates and runs parameters set to perform a sensitivity analysis
				(see reference file). Raw data generted by each run is saved for 
				further processing
				Input : 
				parameter file, see sensi_template.yaml 
				Output : 
					Saves raw data, with one directory per line on the parameter
					file for further processing
				Dependencies:
					gen_all_file in generate_paramfile_range.py

			 - check:
				Parses the arguments to create a single individual, and runs
				webots in full screen, displaying the processed information
				Input :
					list formated as 
					[ [ param1, value1, param2, value2] ], see 
					main for reference

			- worlds:
				Runs all available worlds (in self.world_path), and returns
				the logs directory. 
				Input:
					None, but we must take care to update individuals parameters
					(with create_pop) before calling this method
				Output:
					List containing logs directories for further processing
					(see get_fitness_from_dir in data_analysis/process_run.py)
		"""
		if mode == "parallel_sensitivity_analysis":

			
			param_values_file = args[0][0]
			if LOG_LEVEL<=LOG_INFO:
				print("\n[INFO]Parameters taken from\n",param_values_file)
			all_params,gen_ids=gen_all_file(param_values_file, standalone=True)
			gen_count=1

			for gen_vals, gen_id in zip(all_params,gen_ids):
				save_dir = os.path.join(self.trial_dir, gen_id)
				fu.assert_dir(save_dir, should_be_empty=True)
				population={}
				for ind, cnt in zip(gen_vals,range(len(gen_vals))):
					uid="param"+str(gen_count)+"val"+str(cnt)
					population[uid]=ind
				self.create_pop(population)
				self.run_worlds(self.world_path,self.log_path)
				runs=self.proc_run.import_runs_from_dir(self.log_path,save=False)
				for run, cnt in zip(runs,range(len(runs))):
					run.to_csv(os.path.join(save_dir,"raw"+str(cnt)+".csv"))
				gen_count+=1

		elif mode=="check":
			ind={}
			for par_idx in range(0,len(args[0]),2):
				ind[args[0][par_idx]]=float(args[0][par_idx+1])
			if LOG_LEVEL<=LOG_INFO:
				print("\n[INFO]Checking individual\n",ind)
			self.check_run(ind)

		elif mode=="worlds":
			self.run_worlds(self.world_path,self.log_path)
			return self.log_path
		else:
			if LOG_LEVEL<=LOG_ERROR:
				print("[ERROR]Incorrect input",mode)
			raise KeyError