# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/16_environment_processing.ipynb.

# %% auto 0
__all__ = ['wind_turbine_results', 'EnvironmentProcessingFactory', 'BaseEnvironmentProcessing',
           'WindTurbineEnvironmentProcessing', 'DummyEnvironmentProcessing', 'GenericEnvironmentProcessing',
           'GenericGymEnvironmentProcessing', 'ARCEnvironmentProcessing']

# %% ../nbs/16_environment_processing.ipynb 3
from abc import ABC, abstractmethod
from os import sep, makedirs, getenv
import time

# Ignore deprecation warnings
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)

# %% ../nbs/16_environment_processing.ipynb 4
# from pct.yaw_module import get_comparaison_metrics, test_trad_control, test_hpct_wind, get_properties, get_indexes
from .putils import printtime, NumberStats, PCTRunProperties
from .helpers import DataManagerSingleton
from .plot import PlotARCArrays
from .hierarchy import PCTHierarchy

# %% ../nbs/16_environment_processing.ipynb 6
def wind_turbine_results(environment_properties=None, experiment=None, root=None, wt='WindTurbine', verbose=None, early=None, min=None,
                         comparisons=False, comparisons_print_plots=False, property_dir=None, property_file=None, plots=None, log_testing_to_experiment=False, hierarchy=None):

    from pct.yaw_module import get_comparaison_metrics, test_trad_control, test_hpct_wind, get_properties, get_indexes
    prefix = property_file[:property_file.find(".properties")]
    filename=wt+sep+property_dir+sep+property_file
    file = root + 'data'+sep+'ga'+sep+ filename

    wind_timeseries,start, stop, model_params,yaw_params,keep_history, rt = get_properties(environment_properties)

    history=True
    series = environment_properties['series']
    outdir='c:'+sep+'tmp'+sep+'WindTurbine'+ sep + environment_properties['range'] + sep + series + sep + prefix +sep
    makedirs(outdir, exist_ok=True)

    # lastsepIndex = filename.rfind(sep)
    # propIndex = filename.rfind('.properties')
    # filenamePrefix = filename[lastsepIndex+1:propIndex]
    # draw_file = outdir + 'draw-'+filenamePrefix+'.png'
    draw_file = False
    model_file = outdir + 'res_model.html'

    if experiment:
        from comet_ml import Artifact
        artifact = Artifact(property_file, "Properties file")
        artifact.add(file)
        experiment.log_artifact(artifact)

    (res_model, nac_pos_model, power_improvement, power_control, power_simu) = test_hpct_wind(
        file=file,plots=plots,history=history,verbose=verbose,outdir=outdir,early=early,draw_file=draw_file, model_file=model_file,
        environment_properties=environment_properties,
        start_index=model_params['start_index_test'],
        stop_index=model_params['stop_index_test'],
        experiment=experiment,
        datatype='test',
        log_testing_to_experiment=log_testing_to_experiment, min=min, hierarchy=hierarchy
        )

    if comparisons:
        start, stop = get_indexes(model_params, environment_properties)

        (res_baseline_simu, nac_pos_baseline_simu, wind_dir) = test_trad_control(
            model_params['wind_timeseries'],
            model_params['wind_timeseries_not_agg'],
            yaw_params['cycle_period'],
            start, #model_params['start_index_test'],
            stop, #model_params['stop_index_test'],
            experiment=experiment,
            datatype='baseline_simu',
            outdir=outdir
            )

        (res_baseline_logs, nac_pos_baseline_logs, wind_dir) = test_trad_control(
            model_params['wind_timeseries'],
            model_params['wind_timeseries_not_agg'],
            yaw_params['cycle_period'],
            start, #model_params['start_index_test'],
            stop, #model_params['stop_index_test'],
            experiment=experiment,
            datatype='baseline_logs',
            outdir=outdir
            )

    rel_net_prod_change=[]
    net_prod_change=[]
    power_prod_change, conso_yaw_change, net_prod_change, rel_net_prod_change,yaw_error_rel_change = None, None, None, None, None
    if comparisons :
        power_prod_change, conso_yaw_change, net_prod_change, rel_net_prod_change,yaw_error_rel_change = get_comparaison_metrics(wind_dir,power_control,power_simu,nac_pos_model, nac_pos_baseline_simu, yaw_params['yaw_rate_max'], yaw_params['yaw_consumption'], 50)    

        if comparisons_print_plots:
            fig, axs = plt.subplots(6, sharex=True, figsize=(15,25), gridspec_kw={'height_ratios': [3, 1, 1,1,1,1]})
            plt.xlabel('time (sec)', fontsize=20)
            plt.xlim(0,(model_params['stop_index_test']- model_params['start_index_test'])*yaw_params['cycle_period'])

            axs[0].plot(range(0,(model_params['stop_index_test']- model_params['start_index_test'])*yaw_params['cycle_period'] ,yaw_params['cycle_period']),wind_dir,label='wind direction')
            axs[0].plot(range(0,(model_params['stop_index_test']- model_params['start_index_test'])*yaw_params['cycle_period'] ,yaw_params['cycle_period']),nac_pos_model,linewidth=4.0, label='nacelle position RL algorithm')
            axs[0].plot(range(0,(model_params['stop_index_test']- model_params['start_index_test'])*yaw_params['cycle_period'],yaw_params['cycle_period'] ),nac_pos_baseline_simu,linewidth=4.0, label='nacelle position simulated baseline algorithm')
            axs[0].plot(range(0,(model_params['stop_index_test']- model_params['start_index_test'])*yaw_params['cycle_period'] ,yaw_params['cycle_period']),nac_pos_baseline_logs,linewidth=4.0, label='nacelle position baseline algorithm from logs')
            axs[0].legend(fontsize=20)
            axs[0].tick_params(labelsize=20)
            axs[0].set_ylabel(ylabel='angle (deg)', fontsize=20)

            axs[1].bar(range(0,(model_params['stop_index_test']- model_params['start_index_test'])*yaw_params['cycle_period'] ,yaw_params['cycle_period']*50),yaw_error_rel_change,500,linewidth=4.0, label='RL alg', align='edge')
            axs[1].get_yaxis().set_major_formatter(FuncFormatter(lambda y, _: "{:.1f}%".format(y)))
            axs[1].legend(fontsize=20)
            axs[1].tick_params(labelsize=20)
            axs[1].set_ylabel(ylabel='yaw misaligment \ndecrease (per cent)', fontsize=20,)

            axs[2].bar(range(0,(model_params['stop_index_test']- model_params['start_index_test'])*yaw_params['cycle_period'] ,yaw_params['cycle_period']*50),power_prod_change,500,linewidth=4.0, label='RL alg', align='edge')
            plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda y, _: "{:.1f}%".format(y)))
            axs[2].legend(fontsize=20)
            axs[2].tick_params(labelsize=20)
            axs[2].set_ylabel(ylabel='power output \nincrease (kW)', fontsize=20,)

            axs[3].bar(range(0,(model_params['stop_index_test']- model_params['start_index_test'])*yaw_params['cycle_period'] ,yaw_params['cycle_period']*50),conso_yaw_change,500,linewidth=4.0, label='RL alg', align='edge')
            plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda y, _: "{:.1f}%".format(y)))
            axs[3].legend(fontsize=20)
            axs[3].tick_params(labelsize=20)
            axs[3].set_ylabel(ylabel='yaw consumption \nincrease (kW)', fontsize=20,)

            axs[4].bar(range(0,(model_params['stop_index_test']- model_params['start_index_test'])*yaw_params['cycle_period'] ,yaw_params['cycle_period']*50),net_prod_change,500,linewidth=4.0, label='RL alg', align='edge')
            axs[4].legend(fontsize=20)
            axs[4].tick_params(labelsize=20)
            axs[4].set_ylabel(ylabel='net power output \nincrease (kW)', fontsize=20,)

            axs[5].bar(range(0,(model_params['stop_index_test']- model_params['start_index_test'])*yaw_params['cycle_period'] ,yaw_params['cycle_period']*50),rel_net_prod_change,500,linewidth=4.0, label='RL alg', align='edge')
            axs[5].get_yaxis().set_major_formatter(FuncFormatter(lambda y, _: "{:.1f}%".format(y)))
            axs[5].legend(fontsize=20)
            axs[5].tick_params(labelsize=20)
            axs[5].set_ylabel(ylabel='net power output \nincrease (per cent)', fontsize=20,)

            fig.tight_layout()
            plt.savefig(outdir + f'{series}_dataset',dpi=600)


            fig, axs = plt.subplots(2, sharex=True)
            axs[0].plot(range(model_params['start_index']*yaw_params['cycle_period'],model_params['stop_index']*yaw_params['cycle_period'], yaw_params['cycle_period'] ),wind_timeseries['wind_direction'][model_params['start_index']:model_params['stop_index']],label='train')
            axs[0].plot(range(model_params['start_index_test']*yaw_params['cycle_period'],model_params['stop_index_test']*yaw_params['cycle_period'],yaw_params['cycle_period'] ),wind_timeseries['wind_direction'][model_params['start_index_test']: model_params['stop_index_test']],label='test')
            plt.xlabel('time (sec)')
            axs[1].plot(range(model_params['start_index']*yaw_params['cycle_period'],model_params['stop_index']*yaw_params['cycle_period'], yaw_params['cycle_period'] ),wind_timeseries['wind_speed'][model_params['start_index']:model_params['stop_index']],label='train')
            axs[1].plot(range(model_params['start_index_test']*yaw_params['cycle_period'],model_params['stop_index_test']*yaw_params['cycle_period'],yaw_params['cycle_period'] ),wind_timeseries['wind_speed'][model_params['start_index_test']: model_params['stop_index_test']],label='test')
            plt.setp(axs[1], ylabel='wind speed (m/s)')
            plt.setp(axs[0], ylabel='wind direction (deg)')
            plt.legend()
            plt.savefig(outdir + f'{series}_results',dpi=1000)

    average_yaw_error_decrease_base = 0
    average_yaw_error_decrease_simu = 0

    if comparisons:    
        print(res_baseline_logs)
        print(res_baseline_simu)
        average_yaw_error_decrease_base = 100 * (res_baseline_logs['average yaw error_baseline_logs'] - res_model['average yaw error'])/res_baseline_logs['average yaw error_baseline_logs']
        average_yaw_error_decrease_simu = 100 * (res_baseline_simu['average yaw error_baseline_simu'] - res_model['average yaw error'])/res_baseline_simu['average yaw error_baseline_simu']

    print(res_model)

    print(f'average_yaw_error_decrease_base={average_yaw_error_decrease_base:4.2f}')
    print(f'average_yaw_error_decrease_simu={average_yaw_error_decrease_simu:4.2f}')

    energy_gain =  100*(res_model['power_control']/res_model['power_trad']-1)
    net_energy_gain = ((sum(net_prod_change) + res_model['power_trad']) / res_model['power_trad'] - 1) * 100 if net_prod_change else None

    if experiment:
        experiment.log_metric('pc_test_result', res_model['power_control'])
        experiment.log_metric('yaw_count', res_model['yaw count'])
        experiment.log_metric('mean_ye', res_model['average yaw error'])
        experiment.log_metric('energy_gain', energy_gain)
        experiment.log_metric('net_eg', net_energy_gain)
        experiment.log_metric('avg_ye_dec_base', average_yaw_error_decrease_base)
        experiment.log_metric('avg_ye_dec_simu', average_yaw_error_decrease_simu)


    return energy_gain, net_energy_gain, power_improvement, power_prod_change, conso_yaw_change, net_prod_change,rel_net_prod_change,yaw_error_rel_change



# %% ../nbs/16_environment_processing.ipynb 9
class EnvironmentProcessingFactory:
    factories = {}
    def addFactory(id, environmentProcessingFactory):
        EnvironmentProcessingFactory.factories.put[id] = environmentProcessingFactory
    addFactory = staticmethod(addFactory)
    
    # A Template Method:
    def createEnvironmentProcessing(id):
        if not EnvironmentProcessingFactory.factories.__contains__(id):
            EnvironmentProcessingFactory.factories[id] = \
              eval(id + '.Factory()')
        return EnvironmentProcessingFactory.factories[id].create()
    
    createEnvironmentProcessing = staticmethod(createEnvironmentProcessing)       


# %% ../nbs/16_environment_processing.ipynb 11
class BaseEnvironmentProcessing(ABC):
    "Base class of environment processing."
    # def __init__(self):

    def init_properties(self, args):
        self.args = args
        self.env_processing_details={}

    def set_properties(self, args):
        self.init_properties(args)

    def get_file_props(self, filepath):
        if filepath.find(sep) < 0:
            file = filepath
            property_dir = ""
        else:
            index1=filepath.rindex(sep)
            file = filepath[index1+1:]
            index2=filepath.rindex(sep, 0, index1)
            property_dir=filepath[index2+1:index1]
        drive=self.args['drive']

        return drive, property_dir, file

    # deprecated
    def add_processing_detail(self, key, value):
        self.env_processing_details[key]=value

    # deprecated
    def add_details(self, details):
        if details is not None:
            for key, value in details.items():
                self.env_processing_details[key]=value

    def add_metrics(self, metrics):
        if not metrics or len(metrics) == 0:
            return
        if not hasattr(self, 'metrics') or self.metrics is None:
            self.metrics = {}

        self.metrics.update(metrics)
 
    def add_metrics_other(self, metrics):
        if not metrics or len(metrics) == 0:
            return
        if not hasattr(self, 'metrics_other') or self.metrics_other is None:
            self.metrics_other = {}

        self.metrics_other.update(metrics)
 
    def get_metrics(self):
        return self.metrics
    
    def get_metrics_other(self):
        return self.metrics_other

    def log_properties_file(self, experiment, filepath):
        # artifact - properties file
        from comet_ml import Artifact
        index = filepath.rfind('ga-')
        print(filepath[index:])
        artifact = Artifact(filepath[index:], "Properties file")
        artifact.add(filepath)
        experiment.log_artifact(artifact)


    def get_experiment(self):
        if self.args and 'project_name' in self.args and self.args['project_name']:
            # env_name=self.args['env_name']
            # filename=self.args['file']
            # root = self.args['root_path']
            # pfile = root + self.args['configs_dir'] + env_name +sep+ filename + ".properties"
            api_key=getenv('COMET_API_KEY')
            final_ex_name = self.get_experiment_name()
            if not self.args['overwrite']:
                from comet_ml import api
                capi = api.API(api_key=api_key)
                while True:
                    connected = False
                    try:
                        experiment_exists = capi.get( workspace=self.args['workspace'] + '/' + self.args['project_name'] +'/' + final_ex_name)
                        connected = True
                    except Exception as e:
                        print ('type is:', e.__class__.__name__)
                        # print(experiment_exists)
                        print('Sleeping for 5 ...')
                        time.sleep(5)

                    if connected:
                        break

                if experiment_exists:
                    print("Experiment", final_ex_name, "already exists in", self.args['project_name'])
                    return None, True

            from comet_ml import Experiment
            experiment = Experiment(api_key=api_key,
                                    project_name=self.args['project_name'],
                                    workspace=self.args['workspace'], display_summary_level=0)

            # experiment.log_parameters(model_params)
            # experiment.log_code(path.basename(__file__))	
            experiment.set_name(final_ex_name)
        else:
            experiment = None


        return experiment, None

    def get_experiment_name(self):
        filename=self.args['file']

        prefix = filename[2:6]	
        final_ex_name = f'{prefix}-{self.args["seed"]:02}'

        return final_ex_name
    
    @abstractmethod
    def results(self, filepath=None, experiment=None, environment_properties=None, hierarchy=None):
        return None

    @abstractmethod
    def get_workspace(self):
        return 'wind-turbine'
    



# %% ../nbs/16_environment_processing.ipynb 13
class WindTurbineEnvironmentProcessing(BaseEnvironmentProcessing):
    "WindTurbine environment processing."
    # def __init__(self):

    def get_experiment_name(self):
        env_name=self.args['env_name']
        filename=self.args['file']
        root = self.args['root_path']
        pfile = root + self.args['configs_dir'] + env_name +sep+ filename + ".properties"

        ep, en = PCTRunProperties.get_environment_properties_from_filename(pfile)
        ex_name = ep['series']
        self.args['experiment_name']= ex_name
        self.args['project_name'] = self.args['project_name']+"-" + ex_name

        prefix = filename[2:6]	
        final_ex_name = f'{ex_name[0:1]}-{prefix}-{self.args["seed"]:02}'

        return final_ex_name

    def get_workspace(self):
        return 'wind-turbine'
    
    def results(self, filepath=None, experiment=None, environment_properties=None, hierarchy=None):
        plots=None
        early=None
        self.start = printtime('Start')
        
        if 'log_testing_to_experiment' in self.args:
            log_testing_to_experiment =  self.args['log_testing_to_experiment']
        else:
            log_testing_to_experiment = False


        drive, property_dir, file = self.get_file_props(filepath=filepath)

        if environment_properties is None:
            environment_properties, en = PCTRunProperties.get_environment_properties(root=drive, env='WindTurbine', property_dir=property_dir, property_file=file)
            environment_properties['keep_history'] = True
            environment_properties['range'] = 'test'
            print(environment_properties)

        if 'comparisons_print_plots' not in self.args:
            self.args['comparisons_print_plots'] = False
            print("Warning: 'comparisons_print_plots' not found in args, setting to False. Comparisons with baseline will not be computed.")

        if 'comparisons' not in self.args:
            self.args['comparisons'] = False
            print("Warning: 'comparisons' not found in args, setting to False. Comparisons with baseline will not be computed.")

        energy_gain, net_energy_gain, _ , _, _, _,_,_ = wind_turbine_results(environment_properties=environment_properties, experiment=experiment, root=drive, 
                            verbose=self.args['verbosed']['hpct_verbose'], early=early, comparisons=self.args['comparisons'], 
                            comparisons_print_plots=self.args['comparisons_print_plots'], min= not self.args['max'],
                            property_dir=property_dir, property_file=file, plots=plots, log_testing_to_experiment=log_testing_to_experiment, hierarchy=hierarchy)

        print(f'energy_gain = {energy_gain:4.2f}')
        if net_energy_gain:
            print(f'net_energy_gain = {net_energy_gain:4.2f}')

        end = printtime('End')	
        elapsed = end-self.start        
        print(f'Elapsed time: {elapsed:4.2f}')
        # NumberStats.getInstance().report()
        if experiment:
            experiment.end()

        return {'energy_gain' : energy_gain, 'net_energy_gain' : net_energy_gain}


    class Factory:
        def create(self): return WindTurbineEnvironmentProcessing()

# %% ../nbs/16_environment_processing.ipynb 15
class DummyEnvironmentProcessing(BaseEnvironmentProcessing):
    "Dummy environment processing."

    def get_workspace(self):
        return 'dummy'
    
    def results(self, filepath=None, experiment=None, environment_properties=None, hierarchy=None):

        return {}


    class Factory:
        def create(self): return DummyEnvironmentProcessing()

# %% ../nbs/16_environment_processing.ipynb 17
class GenericEnvironmentProcessing(BaseEnvironmentProcessing):
    "Generic environment processing."

    def get_workspace(self):
        return self.args['env_name']
    
    def results(self, filepath=None, experiment=None, environment_properties=None, hierarchy=None):

        return {}


    class Factory:
        def create(self): return GenericEnvironmentProcessing()

# %% ../nbs/16_environment_processing.ipynb 19
class GenericGymEnvironmentProcessing(BaseEnvironmentProcessing):
    "GenericGym environment processing."

    def set_properties(self, args):
        self.args = args
        self.env_processing_details={}
        root = self.args['root_path']
        configs_dir = self.args['configs_dir']
        env_name = self.args['env_name']
        filename = self.args['file'] + ".properties"
        pfile = root + configs_dir + env_name + sep + filename

        props = PCTRunProperties.get_properties_from_filename(pfile)
        self.args['gym_name'] = props['gym_name']

    def get_workspace(self):
        ws = self.args['gym_name']
        if 'workspace' in self.args and self.args['workspace'] != ws:
            raise ValueError(f"Workspace mismatch: existing workspace is '{self.args['workspace']}', but new workspace is '{ws}'")
        self.args['workspace'] = ws
        return ws
    
    def results(self, filepath=None, experiment=None, environment_properties=None, hierarchy=None):

        if experiment:         
            # artifact - properties file
            self.log_properties_file(experiment, filepath)

            #     hierarchy, score = PCTHierarchy.run_from_file(filepath, env_props=environment_properties, history=history, hpct_verbose= verbose, 
            # render=self.args['verbosed']['display_env'], runs=runs, experiment=experiment, min=min, plots=plots, plots_dir=self.args['plots_dir'],
            # title_prefix=title_prefix, early_termination=False
            # # ,enhanced_environment_properties=enhanced_environment_properties
            # )


            # other metrics
            experiment.log_other('LxC', self.env_processing_details['LxC'])
            experiment.log_metric('last_gen', self.env_processing_details['last_gen'])
            experiment.log_metric('score', self.env_processing_details['score'])
            experiment.log_metric('last_step', self.env_processing_details['last_step'])
            experiment.log_metrics(self.get_metrics())
            experiment.log_others(self.get_metrics_other())

        
        return {}

    class Factory:
        def create(self): return GenericGymEnvironmentProcessing()

# %% ../nbs/16_environment_processing.ipynb 21
class ARCEnvironmentProcessing(BaseEnvironmentProcessing):
    "ARC environment processing."

    def get_workspace(self):
        return 'arc-challenge'
    
    # def enhanced_environment_properties(self, environment_properties=None):
    #     enhanced_environment_properties = {}
    #     if 'dir' in environment_properties:
    #         dir = environment_properties['dir']
    #     else:
    #         dir = 'C:\\packages\\arc-prize-2024'
    #         environment_properties['dir'] = dir 

    #     if 'file_prefix' in environment_properties:
    #         file_prefix = environment_properties['file_prefix']
    #     else:
    #         file_prefix = 'arc-agi_training_'
    #         environment_properties['file_prefix'] = file_prefix

    #     file_name = path.join(dir, file_prefix) + 'challenges.json' 
    #     challenges_manager = ChallengesDataManager(file_name)
    #     data = challenges_manager.get_data_for_key(environment_properties['code'])
        
    #     self.number_of_challenges = 1
    #     if 'index' not in environment_properties:
    #         self.number_of_challenges = len(data['train'])
                
    #     enhanced_environment_properties['data']=data
    #     solutions_file = path.join(environment_properties['dir'], environment_properties['file_prefix']) + 'solutions.json' 
    #     solutions_manager = SolutionsDataManager(solutions_file)
    #     test_output_array = solutions_manager.get_data_for_key(environment_properties['code'])
    #     enhanced_environment_properties['test_output_array']=test_output_array

    #     return enhanced_environment_properties
    
    def results(self, filepath=None, experiment=None, environment_properties=None, hierarchy=None):
        print(filepath)
        
        drive, property_dir, file = self.get_file_props(filepath=filepath)
        if environment_properties is None:
            environment_properties, en = PCTRunProperties.get_environment_properties(root=drive, env='ARC', property_dir=property_dir, property_file=file)
            environment_properties['dataset'] = 'test'
            if 'index' in environment_properties:
                environment_properties['index'] = 0
            # print(environment_properties)

        # enhanced_environment_properties = self.enhanced_environment_properties(environment_properties=environment_properties)

        verbose= self.args['verbosed']['hpct_verbose'] 
        min= not self.args['max']
        history=True

        title_prefix="Test_"
        plots=self.args['hierarchy_plots'] 
        runs = int(1.5*environment_properties['runs']/DataManagerSingleton.get_instance().get_num_arrays_for_code(environment_properties['code']))
        hierarchy, score = PCTHierarchy.run_from_file(filepath, env_props=environment_properties, history=history, hpct_verbose= verbose, 
                render=self.args['verbosed']['display_env'], runs=runs, experiment=experiment, min=min, plots=plots, plots_dir=self.args['plots_dir'],
                title_prefix=title_prefix, early_termination=False
                # ,enhanced_environment_properties=enhanced_environment_properties
                )

        print(f'Test score = {score:4.3f}')
        
        fitness_list = str( [f'{i:4.3f}' for i in  self.env_processing_details['fitness_list']])
        glist = self.env_processing_details['gradient_list']
        success = hierarchy.get_environment().success(glist, self.env_processing_details['fitness'], score)    
        gradient_list = str( [f'{i:4.5f}' for i in  glist])
        print(f'Success = {success}')

        if experiment:         
            # artifact - properties file
            self.log_properties_file(experiment, filepath)

            # other metrics
            code = environment_properties['code']
            grid = hierarchy.get_grid()
            experiment.log_other('LxC', f'{len(grid)}x{max(grid)}')
            indstr = 'all'
            if 'index' in environment_properties:
                indstr = str(environment_properties['index'])
            experiment.log_other('index', indstr)
            experiment.log_other('fitness_list', fitness_list)
            experiment.log_other('gradient_list', gradient_list)
            input_set = environment_properties['input_set']
            experiment.log_other('input_set', str(input_set))
            experiment.log_metric('last_gen', self.env_processing_details['last_gen'])
            experiment.log_metric('fitness', self.env_processing_details['fitness'])
            experiment.log_metric('test_score', round(score, 3))
            experiment.log_other('code', code)
            experiment.log_other('success', success)

            # html_file
            data = DataManagerSingleton.get_instance().get_data_for_code(code)
            task_solution = DataManagerSingleton.get_instance().get_solutions_for_code(code)
            pas = PlotARCArrays()
            input_array = data['test'][0]['input']
            env_array = hierarchy.get_environment().get_env_array()
            image_file = pas.to_image("/tmp/ARC", input_array, task_solution, env_array, 'test', environment_properties['code'])
            experiment.log_image(image_file)

        return {}

    # def success(self, gradient_list, fitness, test_score):
    #     if len(gradient_list) == 0:
    #         return False        
        
    #     if fitness < self.abs_tol_ARC_resolved: # was 0.1
    #         if test_score < self.abs_tol_ARC_resolved: # was 0.5
    #             return True
            
    #     return False

    def get_experiment_name(self):
        filename=self.args['file']

        prefix = filename[3:7]	
        final_ex_name = f'{prefix}-{self.args["seed"]:02}'

        return final_ex_name


    class Factory:
        def create(self): return ARCEnvironmentProcessing()
