---
# System prepended metadata

title: PSEUDOCODE

---

# PSEUDOCODE

The purpose of this document is to sketch one possible way to structure the GCBM endpoints. 

The general concept is to maintain the configuration of a GCBM simulation in memory and synchronise any user changes to files saved on the server. It is incomplete and not optimised. There may be simpler ways to achieve the desired behaviour.

I propose we separate the Flask endpoints from the pre-processing logic. People more fluent in Python can show me how this is best achieved, please.

Please take the good ideas and discard the bad ones. Make it your own.

## gcbm.py
```python
Class GCBMSimulation:
    def __init__:
        create_simulation_folder()
        create_file_index()

    def create_file_index(self):
        # create a global index
        self.files = dict()
        
        # create sub-indexes of different types
        self.config = list()
        self.parameters = list() # this is the input_db
        self.classifiers = list()
        self.disturbances = list()
        self.covariates = list() #this is e.g. temperature
        
        # store config in key-value pair
        for config_file in list_files('../templates/config/'):
            with read_json(config_file) as config:
                self.files[config_file] = config
                self.config.append(config_file)
            
            sync_config(config_file)
            
            
    def add_file(self, file):
        if(is_disturbance(file)):
            self.disturbances.append(file)
            self.update_disturbance_config()
            
        if(is_classifer(file)):
            self.classifiers.append(file)
            self.update_classifier_config()
            ...
            
        save(file)
    
        
    def sync_config(self, file, config_file):
        if(is.null(config_file))
            config_file = change_extension(file, '.json')
        
        # check for any user changes
        with read_json(config_file) as saved_config
            if(self.files[file] != saved_config):
                write(self.files[file], config_file)
        
        
    def update_disturbance_config(self):
        for file in self.disturbances:
            config_file = change_extension(file, '.json')
            
            # use templates for new inputs
            if(!exists(self.config(config_file))):
                generate_disturbance_config(file)
                
            sync_config(file, config_file) 
                    
        # synchronise parent config (ugly - improvements welcome)
        self.files['modules_cbm.json']['Modules']['CBMDisturbanceListener']['settings']['vars'] = self.disturbances
        sync_config('modules_cbm.json')
        
        ...
            
                
    def generate_disturbance_config(self, file):
        with read_json('templates/disturbances/example.json') as config:
            with raster.open(file) as disturbance:
                # extract meta data 
                config['resolution'] = disturbance.resolution
                ...
            
            # set flags for fields requiring user input
            config['has_year'] = False
            config['has_type'] = False
            ...
         
            config_file = change_extension(file, '.json')
            
            # append to global indexes
            self.files[file] = config
            self.config.append(config_file)
            
        # save output
        sync_config(file, config_file)
            
            
    # example payload:
    # {
    #   "year": 2011, 
    #   "disturbance_type": "Wildfire", 
    #   "transition": 1
    # }
    def set_disturbance_attributes(self, file, attributes):
        config = self.files[file]
        config["attributes"] = attributes
        
        # set flags for user input
        if(is_year(config['attributes']['year'])):
            config['has_year'] = True
        
        ...
        
        # cascade changes to saved files
        self.files[file] = config
        self.update_disturbance_config()
        
    
    def check_disturbances(self):
        missing_year = list()
        missing_type = list()

        for disturbance in self.disturbances:
            if(!disturbance.has_year)
                missing_year.append(disturbance)

            if(!disturbance.has_type)
                missing_type.append(disturbance)
            ...
            
        return [missing_year, missing_type]
        
```

## app.py
```python
from gcbm import GCBMSimulation

# POST
@new
def new(title):
    sim = GCBMSimulation()
    save(sim, title)
    
# GET
@load
def load(title)
    sim = open(title)

# POST
@upload
def upload():
    for file in request.files:
        # need some way to access upload flags
        if(request.file.flag == '-d')
            file.is_disturbance = True
            ...
            
        sim.add_file(file)
     
# GET
@files
def get_files():
    return sim.files.keys

# GET
@files/config
def show_config(file):
    return sim.files[file]

# POST
@file/config
def edit_config(file, config)
    sim.files[file] = config
    sim.sync_config(file)
    
# GET
@disturbances
def get_disturbances():
    return sim.disturbances

# POST
@disturbances
def set_disturbances(file):
    sim.disturbances.append(file)

# GET
@disturbances/config
def show_disturbance_config(disturbance):
    return sim.files[disturbance]

# POST
@disturbances/config
def edit_disturbance_config(disturbance, attributes):
    sim.set_disturbance_attributes(disturbance, attributes)
  
# GET
@disturbances/check
def check_disturbance_config():
    return sim.check_disturbances()
  

```