Source code for lowEBMs.Packages.Configuration

"""
Package with functions which configure the model setup.

.. autosummary::
    :toctree:
    :nosignatures:

    importer
    dict_to_list
    parameterimporter
    parameterinterpolator
    parameterinterpolatorstepwise
    add_sellersparameters
    import_parallelparameter
    allocate_parallelparameter
    write_parallelparameter
"""
import configparser
import os
import sys
from lowEBMs.Packages.Functions import *
from lowEBMs.Packages.Variables import *

[docs]def importer(filename,*args,**kwargs): """ Reads a **configuration.ini-file** and creates the model run setup in a dictionary. It is one of the coremodules of this project, mostly called as first step, because it gathers all information about the model setup and summarizes it. .. Note:: The file from which the information is imported has to have a specific structure, please read :ref:`Input <../input>` first to see how the **configuration.ini-files** are created. The specificaton of the path to the filedirectory is optional. If none is given some standard diretories will be tried (python sys.paths and relative paths like '../', '../Config/',..) **Function-call arguments** \n :param string filename: The name of the **configuration.ini-file** * type: string * value: example: 'Configuration.ini' :param args: :param kwargs: Optional Keyword arguments: * *path*: The directory path where the **configuration.ini-file** is located. * type: string * value: **full path** ('/home/user/dir0/dir1/filedir/') or **relative path** ('../../filedir/') :returns: configdic: Dictionary of model setup parameters distributed over several subdictionaries :rtype: Dictionary """ path=kwargs.get('path',None) #Importing the configfile.ini from path if path == None: possible_paths=['','Config/','../Config/'] for i in sys.path: possible_paths.append(i+'/lowEBMs/Tutorials/Config/') for trypath in possible_paths: exists = os.path.isfile(trypath+filename) if exists: path=trypath print('Loading Configuration from: '+path+filename) config=configparser.ConfigParser() config.read(path+filename) break if trypath==possible_paths[-1]: sys.exit('Error: File not found, please specify the path of the configuration.ini. importer(filename,path= " ... ")') else: #Importing the configfile.ini if os.path.isfile(path+filename): print('Loading Configuration from: '+path) config=configparser.ConfigParser() config.read(path+filename) elif os.path.isfile(path+'/'+filename): print('Loading Configuration from: '+path) config=configparser.ConfigParser() config.read(path+'/'+filename) else: sys.exit('Error: File not found, please specify the path of the configuration.ini. importer(filename,path= " ... ")') #Creating arrays for the sections in the configfile keys=config.options('eqparam') values=[] for j in range(len(keys)): values.append(eval(config['eqparam'][keys[j]])) eqparamd=dict(zip(keys,values)) keys=config.options('rk4input') values=[] for j in range(len(keys)): values.append(eval(config['rk4input'][keys[j]])) rk4inputd=dict(zip(keys,values)) keys=config.options('initials') values=[] for j in range(len(keys)): values.append(eval(config['initials'][keys[j]])) initialsd=dict(zip(keys,values)) #Creating a dictionary of functions included funclistd={} funcparamd={} i=0 for func in config: if func[:4]=='func': funclistd[func]=eval(config[func]['func']) keys=config.options(func)[1:] values=[] for j in range(len(keys)): values.append(eval(config[func][keys[j]])) funcparamd[func]=dict(zip(keys,values)) """while 'func'+str(i) in config: funclistd['func'+str(i)]=eval(config['func'+str(i)]['func']) keys=config.options('func'+str(i))[1:] values=[] for j in range(len(keys)): values.append(eval(config['func'+str(i)][keys[j]])) funcparamd['func'+str(i)]=dict(zip(keys,values)) i+=1 """ #packing the function components into one dictionary funccompd={'funclist':funclistd,'funcparam':funcparamd} #converting to list-type to allow indexing #funccomp=dict_to_list(funccompd) #eqparam=dict_to_list(eqparamd) #rk4input=dict_to_list(rk4inputd) #initials=dict_to_list(initialsd) #creating output array #configa=[eqparam, rk4input, funccomp, initials] configad=[eqparamd, rk4inputd, funccompd, initialsd] #creating array with the names of configa configdicnames=lna(['eqparam','rk4input','funccomp','initials']) configdic=dict(zip(configdicnames,configad)) #Importing the Variables and initial conditions #Variable_importer() #returning the arrays with all needed system parameters and variables #return configa, configdic return configdic
[docs]def dict_to_list(dic): """ Converts dictionaries returned from ``Configuration.importer`` into a list with the same structure. This allows calling the content by index not keyword. It works for a maximum of 3 dimensions of dictionaries (dictionary inside a dictionary). **Function-call arguments** \n :param dict dic: The dictionary to convert :returns: List with same structure as input dictionary :rtype: List """ dic_to_list=list(dic.values()) to_list=dic_to_list #print(to_list) i=0 while type(to_list[i]) == dict: to_list[i]=list(to_list[i].values()) j=0 while type(to_list[i][j])==dict: to_list[i][j]=list(to_list[i][j].values()) k=0 while type(to_list[i][j][k])==dict: to_list[i][j][k]=list(to_list[i][j][k].values()) if k<len(to_list[i][j])-1: k+=1 if j<len(to_list[i])-1: j+=1 if i<len(to_list)-1: i+=1 return to_list
###Function to import parameters for the Sellers-EBM from a parameterfile ###with arrays of values
[docs]def parameterimporter(filename,*args,**kwargs): """ A function purpose-built to import 1-dimensional parameters for the sellers-type functions. The standard parameters (:ref:`Sellers 1969`) are written into a **.ini-file** and will be extracted to override the 0-dimensional parameters with 1-dimensional ones. .. Important:: This function is inbound into ``Configuration.parameterinterpolater`` or ``Configuration.parameterinterpolaterstepwise`` which interpolate the parameters to the gridresolution. **To import, interpolate and overwrite these parameter use** ``Configuration.add_sellersparameters``. Parameters which are imported 1-dimensionally: * *b*: Empirical constant to estimate the albedo * *Z*: Zonal mean altitude * *Q*: Solar insolation * *dp*: The tropospheric pressure depth * *dz*: The average zonal ocean depth * *Kh*: The thermal diffusivity of the atmospheric sensible heat term * *Kwv*: The thermal diffusivity of the watervapour term * *Ko*: The thermal diffusivity of the oceanic sensible heat term * *a*: Empricial constant to calculate the meridional windspeed The parameters are divided into two types, one defined on a latitudinal circle (gridlines) and one defined on a latitudinal belt (center point between two latitudinal circles/gridlines) .. Note:: The standard parameters from :ref:`Sellers (1969)` are already provided with this project in 'lowEBMs/Tutorials/Config/Data/'. By specifying no path (**path=None**) they can directly be used (advised since the parameters are structured in a special way). **Function-call arguments** \n :param string filename: The name of the **parameter.ini-file** * type: string * value: standard: 'SellersParameterization.ini' :param args: :param kwargs: Optional Keyword arguments: * *path*: The directory path where the **parameter.ini-file** is located. * type: string * value: **full path** ('/home/user/dir0/dir1/filedir/') or **relative path** ('../../filedir/') :returns: circlecomb, beltcomb: List of parameters defined on a latitudinal circle, and latitudinal belt :rtype: List, List """ path=kwargs.get('path',None) #Importing the paras.ini from path if path == None: possible_paths=['','Config/Data/','../Config/Data/'] for i in sys.path: possible_paths.append(i+'/lowEBMs/Tutorials/Config/Data/') for trypath in possible_paths: exists = os.path.isfile(trypath+filename) if exists: path=trypath print('Loading Parameters from: '+path+filename) paras=configparser.ConfigParser() paras.read(path+filename) break if trypath==possible_paths[-1]: sys.exit('Error: File not found, please specify the path of the configuration.ini. parameterimporter(filename,path= " ... ")') else: #Importing the configfile.ini exists = os.path.isfile(path+filename) if exists: print('Loading parameters from: '+path) paras=configparser.ConfigParser() paras.read(path+filename) else: sys.exit('Error: File not found, please specify the path of the parameter.ini. parameterimporter(filename,path= " ... ")') #Creating and filling arrays with values for latitudinal belts belt=paras.options('belt') for i in range(int(len(paras.options('belt')))): belt[i]=eval(paras['belt'][belt[i]]) #Creating and filling arrays with values for latitudinal circles circle=paras.options('circle') for i in range(int(len(paras.options('circle')))): circle[i]=eval(paras['circle'][circle[i]]) #Splitting the arrays to get the arrays for northern and southern hemisphere splitted beltn,belts=belt[:int(len(belt)/2)],belt[int(len(belt)/2):] circlen,circles=circle[:int(len(circle)/2)],circle[int(len(circle)/2):] #Recombining arrays. Needed because the arrays belt and circle are not #ordered from -90° to 90° beltcomb=[0]*len(beltn) circlecomb=[0]*len(circlen) for i in range(len(beltn)): belts[i].reverse() beltcomb[i]=belts[i]+beltn[i] for i in range(len(circlen)): circles[i].reverse() circlecomb[i]=circles[i]+circlen[i] #Returning the ordered arrays with systemparameters for latitudinal circles and belts return circlecomb, beltcomb
###Function to interpolate the parameterizations given from sellers, into an interpolated ####output with higher resolution
[docs]def parameterinterpolator(filename,*args,**kwargs): """ An interpolation method fitting a polynomial of degree 10 to the parameter distributions. This creates parameter distributions suitable for the gridresolution (necessary if a higher resolution than 10° is used. This function includes the function ``Configuration.parameterimporter`` and takes the same arguments. **Function-call arguments** \n :param string filename: The name of the **parameter.ini-file** * type: string * value: standard: 'SellersParameterization.ini' :param args: :param kwargs: Optional Keyword arguments: * *path*: The directory path where the **parameter.ini-file** is located. * type: string * value: **full path** ('/home/user/dir0/dir1/filedir/') or **relative path** ('../../filedir/') :returns: newcircle, newbelt: List of interpolated parameters defined on a latitudinal circle, and latitudinal belt :rtype: List, List """ path=kwargs.get('path',None) #Importing parameters inputparas=parameterimporter(filename,path=path) #defining new latitudinal arrays if both_hemispheres==True: Latrange=180 latnewc=np.linspace(-90,90,int(Latrange/spatial_resolution+1)) latnewb=np.linspace(-90,90-spatial_resolution, int(Latrange/spatial_resolution))+spatial_resolution/2 latnewb=np.insert(latnewb,0,-90) latnewb=np.append(latnewb,90) else: Latrange=90 latnewc=np.linspace(0,90-spatial_resolution, int(Latrange/spatial_resolution)) latnewb=np.linspace(0,90-spatial_resolution, int(Latrange/spatial_resolution))+spatial_resolution/2 latnewb=np.insert(latnewb,0,0) latnewb=np.append(latnewb,90) #Interpolation of circle parameters newcircle=[0]*len(inputparas[0]) lat10c=np.linspace(-80,80,17) for i in range(len(inputparas[0])): zc=np.polyfit(lat10c,inputparas[0][i],10) fc=np.poly1d(zc) newcircle[i]=fc(latnewc) newcircle[i]=newcircle[i][1:] newcircle[i]=newcircle[i][:-1] #Interpolation of belt parameters newbelt=[0]*len(inputparas[1]) lat10b=np.linspace(-85,85,18) for i in range(len(inputparas[1])): zb=np.polyfit(lat10b,inputparas[1][i],10) fb=np.poly1d(zb) newbelt[i]=fb(latnewb) newbelt[i]=newbelt[i][1:] newbelt[i]=newbelt[i][:-1] return newcircle, newbelt
###Function to interpolate the parameterizations given from sellers, into an interpolated ####output with higher resolution with stepwise interpolation and averaging
[docs]def parameterinterpolatorstepwise(filename,*args,**kwargs): """ An interpolation method stepwise fitting and averaging a polynomial of degree 2 to the parameter distribution. The interpolation method is more advanced compared to ``Configuration.parameterinterpolator``. For each point (over the latitudes) a polynomial fit of degree 2 is made over the point plus the neighbouring points and estimates for the new gridresolution between these neighbouring points are stored. This is done for every point of the original parameters (except the endpoints). Because the interpolations overlap, the values are averaged to obtain a best estimate from multiple interpolations. This function includes the function ``Configuration.parameterimporter`` and takes the same arguments. **Function-call arguments** \n :param string filename: The name of the **parameter.ini-file** * type: string * value: standard: 'SellersParameterization.ini' :param args: :param kwargs: Optional Keyword arguments: * *path*: The directory path where the **parameter.ini-file** is located. * type: string * value: **full path** ('/home/user/dir0/dir1/filedir/') or **relative path** ('../../filedir/') :returns: newcircle, newbelt: List of interpolated parameters defined on a latitudinal circle, and latitudinal belt :rtype: List, List """ path=kwargs.get('path',None) #Importing parameters inputparas=parameterimporter(filename,path=path) #Defining new latitudinal arrays if both_hemispheres==True: Latrange=180 latnewc=np.linspace(-90+spatial_resolution, 90-spatial_resolution,int(Latrange/spatial_resolution-1)) latnewb=np.linspace(-90,90-spatial_resolution, int(Latrange/spatial_resolution))+spatial_resolution/2 else: Latrange=90 latnewc=np.linspace(0,90-spatial_resolution, int(Latrange/spatial_resolution)) latnewb=np.linspace(0,90-spatial_resolution, int(Latrange/spatial_resolution))+spatial_resolution/2 latnewb=np.insert(latnewb,0,0) latnewb=np.append(latnewb,90) ###Interpolation of circle parameters### #Array for output newcircle=np.array([[0]*len(latnewc)]*len(inputparas[0]),dtype=float) #Array with 10° latitudal dependence lat10c=np.linspace(-80,80,17) #Loop over each circleparameter for k in range(len(inputparas[0])): #Loop over the length of latitudes (2nd element to one before last element) for i in range(1,len(lat10c)-1): #Do a polyfit 2nd order over the element +-1 element (left and right) zc=np.polyfit(lat10c[i-1:(i+2)],inputparas[0][k][i-1:(i+2)],2) fc=np.poly1d(zc) #Endpoints are set to the value of the inputparameter (no polyfit here) if i == 1: for l in range(int(10/spatial_resolution)): newcircle[k][l]=inputparas[0][k][0] if i == (len(lat10c)-2): for l in range(int((i+2)*10/spatial_resolution-1),int((i+3)*10/spatial_resolution-1)): newcircle[k][l]=inputparas[0][k][-1] #Write for the new latitudal dependence the corresponding values #from the polyfit into the given outputarray #Loop over the element to the right of i-1 to the element to left of i+1 for j in range(int(2*10/spatial_resolution-1)): if newcircle[k][int(i*10/spatial_resolution+j)] == 0: newcircle[k][int((i)*10/spatial_resolution+j)]= fc(latnewc[int((i)*10/spatial_resolution+j)]) #The inbetween value are calculated twice (from left and right) which are now #averaged to give a smooth new parameterization else: newcircle[k][int((i)*10/spatial_resolution+j)]=np.mean([fc(latnewc [int((i)*10/spatial_resolution+j)]),newcircle[k][int((i)*10/spatial_resolution+j)]]) ###Interpolation of belt parameters### #Array for output newbelt=np.array([[0]*len(latnewb)]*len(inputparas[1]),dtype=float) #Array with 10° latitudal dependence lat10b=np.linspace(-85,85,18) #Loop over each beltparameter for k in range(len(inputparas[1])): #Loop over the length of latitudes (2nd element to one before last element) for i in range(1,len(lat10b)-1): #Do a polyfit 2nd order over the element +-1 element (left and right) zb=np.polyfit(lat10b[i-1:(i+2)],inputparas[1][k][i-1:(i+2)],2) fb=np.poly1d(zb) #Endpoints are set to the value of the inputparameter (no polyfit here) if i == 1: for l in range(int(0.5*10/spatial_resolution)): newbelt[k][l]=inputparas[1][k][0] if i == (len(lat10b)-2): for l in range(int((i+0.5)*10/spatial_resolution),len(newbelt[k])): newbelt[k][l]=inputparas[1][k][-1] #Write for the new latitudal dependence the corresponding values #from the polyfit into the given outputarray #Loop over the element to the right of i-1 to the element to left of i+1 for j in range(int(2*10/spatial_resolution)): if newbelt[k][int((i-0.5)*10/spatial_resolution+j)] == 0: newbelt[k][int((i-0.5)*10/spatial_resolution+j)]= fb(latnewb[int((i-0.5)*10/spatial_resolution+j)]) #The inbetween value are calculated twice (from left and right) which are now #averaged to give a smooth new parameterization else: newbelt[k][int((i-0.5)*10/spatial_resolution+j)]=np.mean([fb(latnewb [int((i-0.5)*10/spatial_resolution+j)]),newbelt[k][int((i-0.5)*10/spatial_resolution+j)]]) return newcircle, newbelt
#Function to rewrite parameters with arrays of parameters from the Sellers parameterinterpolator #Hardcoded! So take care on which index the sellers functions are placed, standard is: #func0 = Incoming Radiation , func1 = Outgoing Radiation, func2 = Transfer, ...
[docs]def add_sellersparameters(config,importer,file,transfernumber,downwardnumber,solar,albedo,*args,**kwargs): """ Overwrites the model setup with one-dimensional sellers parameters. It takes a model configuration with 0D sellers parameters, the filename of new parameters and a method of interpolation. This function uses either the method ``Configuration.parameterinterpolator`` or ``Configuration.parameterinterpolatorstepwise`` which both use the import function ``Configuration.parameterimporter``, therefore it requires their attributes too. **Function-call arguments** \n :param dict config: The original config dictionary to overwrite * type: dictionary * value: created by ``Configuration.importer`` :param function importer: The name of the interpolator method * type: functionname * value: **parameterinterpolator** or **parameterinterpolatorstepwise** :param string file: The name of the **parameter.ini-file** * type: string * value: standard: 'SellersParameterization.ini' :param integer transfernumber: The [func] header-number in the **configuration.ini-file** which describes the transfer flux * type: integer * value: any :param integer incomingnumber: The [func] header-number in the **configuration.ini-file** which describes the downward flux * type: integer * value: any :param boolean solar: Indicates whether the insolation by Sellers is used * type: boolean * value: True / False :param boolean albedo: Indicates whether the albedo parameters by Sellers are used * type: boolean * value: True / False :param args: :param kwargs: Optional Keyword arguments: * *path*: The directory path where the **parameter.ini-file** is located. * type: string * value: **full path** ('/home/user/dir0/dir1/filedir/') or **relative path** ('../../filedir/') :returns: configuration, parameters :rtype: Dictionary, List """ from lowEBMs.Packages.Variables import Vars #solar and albedo are to be set to True or False path=kwargs.get('path',None) #importing the new parameter arrays paras=[[dp,dz,K_h,K_wv,K_o,a],[b,Z,Q]]=importer(file,path=path) #rewriting the transfer parameters with conversion to SI units funct=config['funccomp']['funcparam']['func'+str(transfernumber)] funct['k_wv']=lna(K_wv)*10**5 funct['k_h']=lna(K_h)*10**6 funct['k_o']=lna(K_o)*10**2 funct['a']=lna(a)/100 funct['dp']=lna(dp) funct['dz']=lna(dz)*1000 #rewriting the incoming radiation parameters with conversion + choice to be activated or not funcin=config['funccomp']['funcparam']['func'+str(downwardnumber)] if albedo==True: funcin['albedoparam'][0]=lna(Z) funcin['albedoparam'][1]=lna(b) if solar==True: Vars.Solar=lna(Q)*1.327624658#1.2971# configout=config configout['funccomp']['funcparam']['func'+str(transfernumber)]=funct configout['funccomp']['funcparam']['func'+str(downwardnumber)]=funcin return configout, paras
[docs]def import_parallelparameter(parallelconfig_filename,*args,**kwargs): """ Imports information from a .ini-file to create a setup of parallelized simulations. This shall allow time-efficient creation of ensemble run, focused to run simulations with various parameters to gain best-fit parameters. **Function-call arguments** \n :param string parallelconfig_filename: The name of the **Parallelization.ini-file** for parallelization * type: string * value: standard: 'Parallelization.ini' :param args: :param kwargs: Optional Keyword arguments: * *path*: The directory path where the **Parallelization.ini-file** is located. * type: string * value: **full path** ('/home/user/dir0/dir1/filedir/') or **relative path** ('../../filedir/') :returns: raw parallelization setup :rtype: Dictionary """ path=kwargs.get('path',None) #Importing the configfile.ini from path if path == None: possible_paths=['','Config/Parallelization/','../Config/Parallelization/','/Tutorials/Config/Parallelization/','../Tutorials/Config/Parallelization/'] for i in sys.path: possible_paths.append(i+'/lowEBMs/Tutorials/Config/Parallelization/') for trypath in possible_paths: exists = os.path.isfile(trypath+parallelconfig_filename) if exists: path=trypath print('Loading fit-configuration from: '+path+parallelconfig_filename) fitconfigini=configparser.ConfigParser() fitconfigini.read(path+parallelconfig_filename) break if trypath==possible_paths[-1]: sys.exit('Error: File not found, please specify the path of the fitconfiguration.ini. importer(filename,path= " ... ")') else: #Importing the configfile.ini exists = os.path.isfile(path+parallelconfig_filename) if exists: print('Loading fit-configuration from: '+path) fitconfigini=configparser.ConfigParser() fitconfigini.read(path+parallelconfig_filename) else: sys.exit('Error: File not found, please specify the path of the configuration.ini. importer(filename,path= " ... ")') fitparams={} for i in fitconfigini.sections(): fitparams.update({str(i):dict()}) for j in fitconfigini.options(i): fitparams[i].update({str(j):eval(fitconfigini[i][j])}) return fitparams
[docs]def allocate_parallelparameter(parameter_raw): """ Transforms parameters for parallelization from tuple *[start,end]* to list *[start,...,end]* of length *number_of_cycles*. This shall create lists of parameters to be tested in parallelized simulations. **Function-call arguments** \n :param dict parameter_raw: A dictionary with parameters to allocate. The values of the parameters should have the form [start,end] to create *[start,...,end]* of length *number_of_cycles* * type: dictionary * value: as returned by **configuration.import_parallelparameter** :returns: allocated parallelization setup, parallelization information :rtype: Dictionary, Dictionary """ num_params=parameter_raw['parametersetup']['number_of_parameters'] num_cycles=parameter_raw['parametersetup']['number_of_cycles'] parametersetup=parameter_raw.pop('parametersetup') parametersetup = dict((k,int(v)) for k,v in parametersetup.items()) parameter_raw_minus=parameter_raw parameter_allocated=dict() for i in list(parameter_raw_minus.keys()): parameter_allocated.update({i:dict()}) for j in list(parameter_raw_minus[i].keys()): paramrange=np.linspace(parameter_raw_minus[i][j][0], parameter_raw_minus[i][j][1],num_cycles) parameter_allocated[i].update({j:paramrange}) return parameter_allocated, parametersetup
[docs]def write_parallelparameter(config,parameter,parametersetup): """ Overwrites the single run model setup with a parallelized model setup. This function uses the allocated parallelization setup as returned by ``Configuration.allocate_parallelparameter``. Depending on the number of paramters **n** to parallelize, a **n-dimensional** matrix is created. This matrix will be transformed to a **one-dimensional** list by placing one row after another. **Function-call arguments** \n :param dict config: The original config dictionary to overwrite * type: dictionary * value: created by ``Configuration.importer`` :param dict parameter: A dictionary with allocated parameters for parallelization. First element returned by ``Configuration.allocate_parallelparameter``. * type: dictionary * value: as returned by ``Configuration.allocate_parallelparameter`` :param dict parametersetup: A dictionary with information about parallelization. Second element returned by ``Configuration.allocate_parallelparameter``. * type: dictionary * value: as returned by ``Configuration.allocate_parallelparameter`` :returns: config: Updated dictionary of model setup parameters for parallelization :rtype: Dictionary """ num_params=parametersetup['number_of_parameters'] num_cycles=parametersetup['number_of_cycles'] #for s in range(num_cycles): paralleldict=dict() funckey=list(parameter.keys()) for key in funckey: paralleldict.update({key:dict()}) for paramkey in list(parameter[key].keys()): paralleldict[key].update({paramkey:dict()}) keylen=len(funckey) paramkey=[] for l in funckey: paramkey.append(list(parameter[l].keys())) #for o in range(num_cycles): for n in range(num_cycles): for m in range(num_cycles): #for o in range(num_cycles): num=0 par=0 x=paralleldict[funckey[num]] #if m==0: if n==0 and m==0:# and o==0: x.update({paramkey[num][par]:[]}) x.update({paramkey[num][par]:np.append(x.get(paramkey[num][par]), parameter[funckey[num]][paramkey[num][par]][m])}) paralleldict.update({funckey[num]:x}) num=0 par=1 y=paralleldict[funckey[num]] if n==0 and m==0:# and o==0: y.update({paramkey[num][par]:[]}) y.update({paramkey[num][par]:np.append(y.get(paramkey[num][par]), parameter[funckey[num]][paramkey[num][par]][n])}) paralleldict.update({key[num]:y}) """ num=0 par=2 z=paralleldict[funckey[num]] if n==0 and m==0 and o==0: z.update({paramkey[num][par]:[]}) z.update({paramkey[num][par]:np.append(z.get(paramkey[num][par]), parameter[funckey[num]][paramkey[num][par]][o])}) paralleldict.update({key[num]:z})""" #eq=paralleldict.pop('eqparam') """for eqkey in list(eq.keys()): if bool(eq)==False: break config['eqparam'][eqkey]=eq[eqkey] print('hi')""" for key in funckey: for paramkey in list(paralleldict[key].keys()): config['funccomp']['funcparam'][key][paramkey]=paralleldict[key][paramkey] #for key in parallel # config['funccomp']['funcparam'][funcnumber][parametername]=parameter return config