From 34c7192ab321b5ca64c6677657f5bc16d6a62f7c Mon Sep 17 00:00:00 2001
From: kamischi <karl-michael.schindler@web.de>
Date: Tue, 19 Mar 2024 15:08:36 +0100
Subject: [PATCH] remove obsolete version numbers.

Update the versioned file name to the basic name and remove lower versions.
---
 Python code/libhreels/calcHREELS.py        | 116 ++++++----
 Python code/libhreels/calcHREELS3.py       | 250 ---------------------
 Python code/libhreels/calcHREELS4.py       | 250 ---------------------
 Python code/libhreels/dielectrics.py       | 243 +++++++++++++-------
 Python code/libhreels/dielectrics2.py      | 245 --------------------
 Python code/libhreels/dielectrics2_save.py | 250 ---------------------
 Python code/nice_fitting_code.py           |   4 +-
 7 files changed, 239 insertions(+), 1119 deletions(-)
 delete mode 100755 Python code/libhreels/calcHREELS3.py
 delete mode 100755 Python code/libhreels/calcHREELS4.py
 delete mode 100755 Python code/libhreels/dielectrics2.py
 delete mode 100755 Python code/libhreels/dielectrics2_save.py

diff --git a/Python code/libhreels/calcHREELS.py b/Python code/libhreels/calcHREELS.py
index ef71336..989dd5b 100755
--- a/Python code/libhreels/calcHREELS.py	
+++ b/Python code/libhreels/calcHREELS.py	
@@ -5,6 +5,8 @@ import sys, re, os
 from libhreels.HREELS import myPath
 from copy import deepcopy
 
+import scipy.integrate as integrate
+
 libDir = os.path.dirname(os.path.realpath(__file__)) 
 
 if not (sys.version.startswith('3.6') or sys.version.startswith('3.8')):
@@ -12,11 +14,10 @@ if not (sys.version.startswith('3.6') or sys.version.startswith('3.8')):
     have been complied with the proper f2py3 for the right 
     python version!!''') 
 try:
-    from libhreels import myEels2 as LambinEELS   # wrapper for myEels2.f90
-    from libhreels import myBoson as LambinBoson  # wrapper for myBoson.f90
-    from libhreels import myEels3 as LambinEELS3   # wrapper for myEels3.f90
+    from libhreels import DoEELS as LambinEELS   # wrapper for Doeels.f90
+    from libhreels import DoBoson as LambinBoson  # wrapper for Doboson.f90
 except:
-    print('myEels2 and MyBoson are not available here (Check your version)')			
+    print('DoEELS and DoBoson are not available here (Check your version)')
 
 # Experimental setup as dictionary:
 setup = {
@@ -143,25 +144,6 @@ class lambin:
             i += 1
         return wn_array[i-1:], loss_array[i-1:]
 
-    def calcSurfaceLoss3(self,x):
-        ''' Calculate the surface loss spectrum for the array of x, which needs to be an equidistant array. 
-        All parameters are defined in the class __init__() call.'''
-        wmin = min(x)
-        wmax = max(x)-0.001
-        dw = (wmax-wmin)/(len(x)-1)     # assumes that x is an equidistant array
-        wn_array_size = len(x)     # size of array for x and epsilon (wn_array, loss_array)
-        nper = 1.
-        contrl = '{:<10}'.format('None'[:10])   # Can be 'image' to include image charge
-        mode = '{:<10}'.format('kurosawa'[:10])           
-        wn_array,loss_array = LambinEELS3.mod_doeels.doeels(self.e0,self.theta,self.phia,self.phib,
-            wmin,wmax,dw,self.layers,self.neps,nper,self.name,
-            self.thick,self.epsinf,self.listNOsci,self.osc,contrl,mode,wn_array_size)
-        i=0
-        for item in wn_array:
-            if item > 0: break
-            i += 1
-        return wn_array[i-1:], loss_array[i-1:]
-
     def calcHREELS(self,x, normalized=True, areanormalized=False):
         emin = min(x)
         emax = max(x)-0.001
@@ -169,10 +151,11 @@ class lambin:
         xLoss,loss_array = self.calcSurfaceLoss(x)
         wmin = min(xLoss)
         wmax = max(xLoss)
-        xOut,spectrum,n = LambinBoson.doboson3(self.temperature,self.width,self.gauss,self.asym,
+        xOut,spectrum,n = LambinBoson.doboson(self.temperature,self.width,self.gauss,self.asym,
             emin,emax,wmin,wmax,loss_array,self.debug,len(loss_array))
         if normalized:
             norm = max(spectrum[:n])
+            #print("peak normalized, norm=", norm)
             if areanormalized: #edit by HHE
                 try:                    
                     areanormalize_xstart = np.argmin(abs(x+100.)) #seems to be oddly complicated, but is way more stable than x.index(-100.) or where()
@@ -182,8 +165,17 @@ class lambin:
                     areanormalize_xend = np.argmin(abs(x-1000.))
                 except:
                     areanormalize_xend = len(x)
-                norm=spectrum[areanormalize_xstart:areanormalize_xend].sum()
+                #norm=spectrum[areanormalize_xstart:areanormalize_xend].sum()
+                cropped_spectra=spectrum[areanormalize_xstart:areanormalize_xend]
+                cropped_x=x[areanormalize_xstart:areanormalize_xend]
 
+                #norm=cropped_spectra.sum()/len(cropped_x)*(x[areanormalize_xend]-x[areanormalize_xstart])
+                #print(len(cropped_x), len(cropped_spectra), len(x), len(spectrum))
+                #print(cropped_spectra.sum(), len(cropped_x),x[areanormalize_xend]-x[areanormalize_xstart])
+                norm=integrate.simps(cropped_spectra, dx=x[areanormalize_xstart+1]-x[areanormalize_xstart])#/(1100/(max(cropped_x)-min(cropped_x)))
+                #print("areanormalized, norm=", norm, " dx=", x[areanormalize_xstart+1]-x[areanormalize_xstart])
+        else:
+            print("not normalized")
         return xOut[:len(x)], spectrum[:len(x)]/norm
 
     def calcEps(self, x):
@@ -194,29 +186,65 @@ class lambin:
             epsArray.append(yn)
         return np.transpose(np.array(epsArray))
 
-    def calcEps3(self, x):
-        epsArray = []
-        nOsci = len(self.wOsc)
-        for wn in x:
-            yn = LambinEELS3.mod_doeels.seteps(self.listNOsci,nOsci,self.osc,self.epsinf,wn,self.layers)
-            epsArray.append(yn)
-        return np.transpose(np.array(epsArray))
-
 ####################################################################################
 def myMain():
     import matplotlib.pyplot as plt
-    oxide = importMaterials('NiO')
-    substrate = importMaterials('Ag')
-    x = np.linspace(-100.,1000.,1000)
-    for d in [4., 20., 50., 200., 10000.]:
-        film1 = lambin(film=[[oxide,d],[substrate,1000.]])
-        # xs, spectrum = film1.calcSurfaceLoss(x)
-        xs, spectrum = film1.calcHREELS(x, normalized=True, areanormalized=True)
-        plt.plot(xs,spectrum, label='{:.0f}'.format(d))
-    plt.ylabel('HREELS Intensity')
+    import numpy as np
+    from copy import deepcopy
+    import os
+
+    x = np.linspace(-100.,1000,400)
+    x2 = np.linspace(-100.,1000,2400)
+    
+
+    material = {'eps': 4.,
+                'wTO': [0],  'gTO': [20], 'wLO': [598.7], 'gLO': [20],
+                }
+
+    film1 = lambin(film=[[material,10000.]])
+    film1.temperature = 100
+    #xs, spectrum = film1.calcSurfaceLoss(x)
+    xs, spectrum = film1.calcHREELS(x,normalized=False,areanormalized=False)
+    xs1, spectrum1 = film1.calcHREELS(x2,normalized=False,areanormalized=False)
+    xs2, spectrum2 = film1.calcHREELS(x,areanormalized=True)
+    xs3, spectrum3 = film1.calcHREELS(x2,areanormalized=True)
+
+    norm_test=integrate.simps(spectrum, dx=xs[2]-xs[1])/(max(xs)-min(xs))
+    norm_test1=integrate.simps(spectrum1, dx=xs1[2]-xs1[1])/(max(xs1)-min(xs1))
+    norm_test2=integrate.simps(spectrum2, dx=xs2[2]-xs2[1])/(max(xs2)-min(xs2))
+    norm_test3=integrate.simps(spectrum3, dx=xs3[2]-xs3[1])/(max(xs3)-min(xs3))
+    print(norm_test,norm_test1,norm_test2,norm_test3)
+    print(xs[2]-xs[1],xs1[2]-xs1[1],xs2[2]-xs2[1],xs3[2]-xs3[1])
+    
+    plt.plot(xs[:-1],spectrum[:-1], label='normalized=Flase, '+str(len(x))+' points, E0 at '+str(max(spectrum)))
+    plt.plot(xs1[:-2],spectrum1[:-2], label='normalized=Flase, '+str(len(x2))+' points, E0 at '+str(max(spectrum1)))
+    plt.plot(xs2[:-10],spectrum2[:-10],label='area normalized=True, '+str(len(x))+' points, E0 at '+str(max(spectrum2)))
+    plt.plot(xs3[:-20],spectrum3[:-20],label='area normalized=True, '+str(len(x2))+' points, E0 at '+str(max(spectrum3)))
+
+    print('spec2/spec0=', max(spectrum2)/max(spectrum))
+    print('spec3/spec0=', max(spectrum3)/max(spectrum))
+    print('spec0/spec2=', max(spectrum)/max(spectrum2))
+    print('spec0/spec3=', max(spectrum)/max(spectrum3))
+
+    # pureDrude = {'eps': 4.,
+    #             'wTO': [-400],  'gTO': [-20], 'wLO': [0], 'gLO': [0],
+    #             }
+    # film2 = lambin(film=[[pureDrude,10000.]])
+    # film2.temperature = 100
+    # xs, spectrum = film2.calcSurfaceLoss(x)
+    # plt.plot(xs,spectrum,'g-.', label='pure Drude 400')
+
+
+    plt.ylabel('Surface Loss')
     plt.xlabel('Energy Loss (cm$^{-1}$)')
-    plt.legend(title='Thickness in ($\AA$)')
+    plt.legend(title=r'Plasma frequency')
+
+    plt.text(0.99, 0.01,os.path.basename(__file__), fontsize=10, ha='right', va='bottom', transform=plt.gcf().transFigure)
+    output_filename = os.path.splitext(__file__)[0] + '.png'
+    plt.savefig(output_filename)
+
     plt.show()
 
+
 if __name__ == '__main__':
-	myMain()
\ No newline at end of file
+	myMain()
diff --git a/Python code/libhreels/calcHREELS3.py b/Python code/libhreels/calcHREELS3.py
deleted file mode 100755
index c832bde..0000000
--- a/Python code/libhreels/calcHREELS3.py	
+++ /dev/null
@@ -1,250 +0,0 @@
-#!/usr/bin/env python3
-import numpy as np
-import json
-import sys, re, os
-from libhreels.HREELS import myPath
-from copy import deepcopy
-
-import scipy.integrate as integrate
-
-libDir = os.path.dirname(os.path.realpath(__file__)) 
-
-if not (sys.version.startswith('3.6') or sys.version.startswith('3.8')):
-    print('''Make sure the Fortran routines 'myEels2' and 'myBoson' 
-    have been complied with the proper f2py3 for the right 
-    python version!!''') 
-try:
-    from libhreels import myEels3 as LambinEELS3   # wrapper for myEels3.f90
-    from libhreels import myBoson as LambinBoson  # wrapper for myBoson.f90
-except:
-    print('myEels2 and MyBoson are not available here (Check your version)')			
-
-# Experimental setup as dictionary:
-setup = {
-    "e0": 4.0,
-    "theta": 60.,
-    "phia": 0.33,
-    "phib": 2.0,
-    "temperature": 298.,
-    "debug": False
-}
-# Instrumental function describing elastic peak shape:
-instrument = {
-    "width": 18.,
-    "intensity": 100000.,
-    "asym": 0.01,
-    "gauss": 0.88
-}
-
-	
-def importMaterials(string='', path=libDir):
-    ''' Returns a dictionary with all phonon parameters for the material provided 
-    as string argument. If the string is empty or not matching, a list of all available 
-    materials is printed.
-    '''
-    file = os.path.join(myPath(path),'materials.json')
-    with open(file) as json_file:
-        materials = json.load(json_file)
-        try:
-            mat = materials[string]
-        except:
-            print('No data for material >>{}<< found in {} materials.json!!'.format(string, path))
-            print('Available materials:\n{}\n'.format(materials.keys()))
-            mat = 'None'
-    return mat
-
-
-def addDrude(wPlasma, gPlasma, material):
-    ''' Adds a simple Drude response to the materials properties (which are provided 
-    as 3rd argument) and returns a new materials dictionary with all phonon parameters. Note 
-    that at least the eps_infinity has to given before.
-    '''
-    newMaterial = deepcopy(material)
-    # To select the Drude response, the Lambin Fortran code requires a negative first oscillator frequency
-    # which is then interpreted as plasma frequency.
-    # The values of the former LO parameter are irrelevant (but need to be provided). 
-    if not wPlasma > 0:
-        print('Cannot add Drude to material',material)
-        return material
-    try:
-        if len(newMaterial['wTO']) > 0:
-            newMaterial['wTO'] += [-1*wPlasma]
-            newMaterial['gTO'] += [-1*gPlasma]
-            newMaterial['wLO'] += [0]
-            newMaterial['gLO'] += [0]
-            return newMaterial
-    except:
-        print('Cannot add Drude to material',material)
-    return material
-
-################################################################################
-################################################################################
-class lambin:
-    def __init__(self, film, setup=setup, instrument=instrument):
-        self.e0 = setup['e0']
-        self.theta = setup['theta']
-        self.phia = setup['phia']
-        self.phib = setup['phib']
-        self.temperature = setup['temperature']
-        self.debug = setup['debug']
-        self.width = instrument['width']
-        self.gauss = instrument['gauss']
-        self.intensity = instrument['intensity']
-        self.asym = instrument['asym']
-        self.layers = len(film)          # number of layers
-        self.neps = self.layers
-        name_size = self.layers
-        self.name = []; self.thick=[]; self.listNOsci=[]; self.epsinf =[]; Q = []
-        allTO=[]; allgTO=[];  allgLO=[]; nDrude=0
-        name2 = []
-        for layer in film:
-            try:
-                a = layer[0]['name']
-            except:
-                a = 'None'
-            self.name.append('{:<10}'.format(a[:10]))        # film name and material
-            name2.append(a)
-            try:
-                a = layer[1]
-            except:
-                a = 10000.
-            self.thick.append(a)
-            self.epsinf.append(layer[0]['eps'])
-            nTO = 2 * len(layer[0]['wTO'])
-            allTO.extend(layer[0]['wTO'])
-            allgTO.extend(layer[0]['gTO'])
-            allTO.extend(layer[0]['wLO'])
-            allgTO.extend(layer[0]['gLO'])
-            Q.extend(2*len(layer[0]['wTO'])*[10.])
-            self.listNOsci.append(nTO)
-        
-        if len(allTO)!=sum(self.listNOsci) or len(allgTO)!=sum(self.listNOsci):
-            print('Error in materials: ', layer[0])
-        self.wOsc = np.array(allTO)
-        self.gOsc = np.array(allgTO)
-        self.osc = np.array([self.wOsc, np.array(Q), self.gOsc])
-        return
-
-    def calcSurfaceLoss(self,x):
-        ''' Calculate the surface loss spectrum for the array of x, which needs to be an equidistant array. 
-        All parameters are defined in the class __init__() call.'''
-        wmin = min(x)
-        wmax = max(x)-0.001
-        dw = (wmax-wmin)/(len(x)-1)     # assumes that x is an equidistant array
-        wn_array_size = len(x)     # size of array for x and epsilon (wn_array, loss_array)
-        nper = 1.
-        contrl = '{:<10}'.format('None'[:10])   # Can be 'image' to include image charge
-        mode = '{:<10}'.format('kurosawa'[:10])           
-        wn_array,loss_array = LambinEELS3.mod_doeels.doeels(self.e0,self.theta,self.phia,self.phib,
-            wmin,wmax,dw,self.layers,self.neps,nper,self.name,
-            self.thick,self.epsinf,self.listNOsci,self.osc,contrl,mode,wn_array_size)
-        i=0
-        for item in wn_array:
-            if item > 0: break
-            i += 1
-        return wn_array[i-1:], loss_array[i-1:]
-
-    def calcHREELS(self,x, normalized=True, areanormalized=False):
-        emin = min(x)
-        emax = max(x)-0.001
-        norm = 1
-        xLoss,loss_array = self.calcSurfaceLoss(x)
-        wmin = min(xLoss)
-        wmax = max(xLoss)
-        xOut,spectrum,n = LambinBoson.doboson3(self.temperature,self.width,self.gauss,self.asym,
-            emin,emax,wmin,wmax,loss_array,self.debug,len(loss_array))
-        if normalized:
-            norm = max(spectrum[:n])
-            #print("peak normalized, norm=", norm)
-            if areanormalized: #edit by HHE
-                try:                    
-                    areanormalize_xstart = np.argmin(abs(x+100.)) #seems to be oddly complicated, but is way more stable than x.index(-100.) or where()
-                except:
-                    areanormalize_xstart = 0
-                try:
-                    areanormalize_xend = np.argmin(abs(x-1000.))
-                except:
-                    areanormalize_xend = len(x)
-                #norm=spectrum[areanormalize_xstart:areanormalize_xend].sum()
-                cropped_spectra=spectrum[areanormalize_xstart:areanormalize_xend]
-                cropped_x=x[areanormalize_xstart:areanormalize_xend]
-
-                #norm=cropped_spectra.sum()/len(cropped_x)*(x[areanormalize_xend]-x[areanormalize_xstart])
-                #print(len(cropped_x), len(cropped_spectra), len(x), len(spectrum))
-                #print(cropped_spectra.sum(), len(cropped_x),x[areanormalize_xend]-x[areanormalize_xstart])
-                norm=integrate.simps(cropped_spectra, dx=x[areanormalize_xstart+1]-x[areanormalize_xstart])#/(1100/(max(cropped_x)-min(cropped_x)))
-                #print("areanormalized, norm=", norm, " dx=", x[areanormalize_xstart+1]-x[areanormalize_xstart])
-        else:
-            print("not normalized")
-        return xOut[:len(x)], spectrum[:len(x)]/norm
-
-    def calcEps(self, x):
-        epsArray = []
-        nOsci = len(self.wOsc)
-        for wn in x:
-            yn = LambinEELS3.mod_doeels.seteps(self.listNOsci,nOsci,self.osc,self.epsinf,wn,self.layers)
-            epsArray.append(yn)
-        return np.transpose(np.array(epsArray))
-
-####################################################################################
-def myMain():
-    import matplotlib.pyplot as plt
-    import numpy as np
-    from copy import deepcopy
-    import os
-
-    x = np.linspace(-100.,1000,400)
-    x2 = np.linspace(-100.,1000,2400)
-    
-
-    material = {'eps': 4.,
-                'wTO': [0],  'gTO': [20], 'wLO': [598.7], 'gLO': [20],
-                }
-
-    film1 = lambin(film=[[material,10000.]])
-    film1.temperature = 100
-    #xs, spectrum = film1.calcSurfaceLoss(x)
-    xs, spectrum = film1.calcHREELS(x,normalized=False,areanormalized=False)
-    xs1, spectrum1 = film1.calcHREELS(x2,normalized=False,areanormalized=False)
-    xs2, spectrum2 = film1.calcHREELS(x,areanormalized=True)
-    xs3, spectrum3 = film1.calcHREELS(x2,areanormalized=True)
-
-    norm_test=integrate.simps(spectrum, dx=xs[2]-xs[1])/(max(xs)-min(xs))
-    norm_test1=integrate.simps(spectrum1, dx=xs1[2]-xs1[1])/(max(xs1)-min(xs1))
-    norm_test2=integrate.simps(spectrum2, dx=xs2[2]-xs2[1])/(max(xs2)-min(xs2))
-    norm_test3=integrate.simps(spectrum3, dx=xs3[2]-xs3[1])/(max(xs3)-min(xs3))
-    print(norm_test,norm_test1,norm_test2,norm_test3)
-    print(xs[2]-xs[1],xs1[2]-xs1[1],xs2[2]-xs2[1],xs3[2]-xs3[1])
-    
-    plt.plot(xs,spectrum, label='normalized=Flase, '+str(len(x))+' points, E0 at '+str(max(spectrum)))
-    plt.plot(xs1,spectrum1, label='normalized=Flase, '+str(len(x2))+' points, E0 at '+str(max(spectrum1)))
-    plt.plot(xs2,spectrum2,label='area normalized=True, '+str(len(x))+' points, E0 at '+str(max(spectrum2)))
-    plt.plot(xs3,spectrum3,label='area normalized=True, '+str(len(x2))+' points, E0 at '+str(max(spectrum3)))
-
-    print('spec2/spec0=', max(spectrum2)/max(spectrum))
-    print('spec3/spec0=', max(spectrum3)/max(spectrum))
-    print('spec0/spec2=', max(spectrum)/max(spectrum2))
-    print('spec0/spec3=', max(spectrum)/max(spectrum3))
-
-    # pureDrude = {'eps': 4.,
-    #             'wTO': [-400],  'gTO': [-20], 'wLO': [0], 'gLO': [0],
-    #             }
-    # film2 = lambin(film=[[pureDrude,10000.]])
-    # film2.temperature = 100
-    # xs, spectrum = film2.calcSurfaceLoss(x)
-    # plt.plot(xs,spectrum,'g-.', label='pure Drude 400')
-
-
-    plt.ylabel('Surface Loss')
-    plt.xlabel('Energy Loss (cm$^{-1}$)')
-    plt.legend(title=r'Plasma frequency')
-
-    plt.text(0.99, 0.01,os.path.basename(__file__), fontsize=10, ha='right', va='bottom', transform=plt.gcf().transFigure)
-    output_filename = os.path.splitext(__file__)[0] + '.png'
-    plt.savefig(output_filename)
-
-    plt.show()
-
-
-if __name__ == '__main__':
-	myMain()
\ No newline at end of file
diff --git a/Python code/libhreels/calcHREELS4.py b/Python code/libhreels/calcHREELS4.py
deleted file mode 100755
index ea3c233..0000000
--- a/Python code/libhreels/calcHREELS4.py	
+++ /dev/null
@@ -1,250 +0,0 @@
-#!/usr/bin/env python3
-import numpy as np
-import json
-import sys, re, os
-from libhreels.HREELS import myPath
-from copy import deepcopy
-
-import scipy.integrate as integrate
-
-libDir = os.path.dirname(os.path.realpath(__file__)) 
-
-if not (sys.version.startswith('3.6') or sys.version.startswith('3.8')):
-    print('''Make sure the Fortran routines 'myEels2' and 'myBoson' 
-    have been complied with the proper f2py3 for the right 
-    python version!!''') 
-try:
-    from libhreels import myEels4 as LambinEELS4   # wrapper for myEels4.f90
-    from libhreels import myBoson as LambinBoson  # wrapper for myBoson.f90
-except:
-    print('myEels2 and MyBoson are not available here (Check your version)')			
-
-# Experimental setup as dictionary:
-setup = {
-    "e0": 4.0,
-    "theta": 60.,
-    "phia": 0.33,
-    "phib": 2.0,
-    "temperature": 298.,
-    "debug": False
-}
-# Instrumental function describing elastic peak shape:
-instrument = {
-    "width": 18.,
-    "intensity": 100000.,
-    "asym": 0.01,
-    "gauss": 0.88
-}
-
-	
-def importMaterials(string='', path=libDir):
-    ''' Returns a dictionary with all phonon parameters for the material provided 
-    as string argument. If the string is empty or not matching, a list of all available 
-    materials is printed.
-    '''
-    file = os.path.join(myPath(path),'materials.json')
-    with open(file) as json_file:
-        materials = json.load(json_file)
-        try:
-            mat = materials[string]
-        except:
-            print('No data for material >>{}<< found in {} materials.json!!'.format(string, path))
-            print('Available materials:\n{}\n'.format(materials.keys()))
-            mat = 'None'
-    return mat
-
-
-def addDrude(wPlasma, gPlasma, material):
-    ''' Adds a simple Drude response to the materials properties (which are provided 
-    as 3rd argument) and returns a new materials dictionary with all phonon parameters. Note 
-    that at least the eps_infinity has to given before.
-    '''
-    newMaterial = deepcopy(material)
-    # To select the Drude response, the Lambin Fortran code requires a negative first oscillator frequency
-    # which is then interpreted as plasma frequency.
-    # The values of the former LO parameter are irrelevant (but need to be provided). 
-    if not wPlasma > 0:
-        print('Cannot add Drude to material',material)
-        return material
-    try:
-        if len(newMaterial['wTO']) > 0:
-            newMaterial['wTO'] += [-1*wPlasma]
-            newMaterial['gTO'] += [-1*gPlasma]
-            newMaterial['wLO'] += [0]
-            newMaterial['gLO'] += [0]
-            return newMaterial
-    except:
-        print('Cannot add Drude to material',material)
-    return material
-
-################################################################################
-################################################################################
-class lambin:
-    def __init__(self, film, setup=setup, instrument=instrument):
-        self.e0 = setup['e0']
-        self.theta = setup['theta']
-        self.phia = setup['phia']
-        self.phib = setup['phib']
-        self.temperature = setup['temperature']
-        self.debug = setup['debug']
-        self.width = instrument['width']
-        self.gauss = instrument['gauss']
-        self.intensity = instrument['intensity']
-        self.asym = instrument['asym']
-        self.layers = len(film)          # number of layers
-        self.neps = self.layers
-        name_size = self.layers
-        self.name = []; self.thick=[]; self.listNOsci=[]; self.epsinf =[]; Q = []
-        allTO=[]; allgTO=[];  allgLO=[]; nDrude=0
-        name2 = []
-        for layer in film:
-            try:
-                a = layer[0]['name']
-            except:
-                a = 'None'
-            self.name.append('{:<10}'.format(a[:10]))        # film name and material
-            name2.append(a)
-            try:
-                a = layer[1]
-            except:
-                a = 10000.
-            self.thick.append(a)
-            self.epsinf.append(layer[0]['eps'])
-            nTO = 2 * len(layer[0]['wTO'])
-            allTO.extend(layer[0]['wTO'])
-            allgTO.extend(layer[0]['gTO'])
-            allTO.extend(layer[0]['wLO'])
-            allgTO.extend(layer[0]['gLO'])
-            Q.extend(2*len(layer[0]['wTO'])*[10.])
-            self.listNOsci.append(nTO)
-        
-        if len(allTO)!=sum(self.listNOsci) or len(allgTO)!=sum(self.listNOsci):
-            print('Error in materials: ', layer[0])
-        self.wOsc = np.array(allTO)
-        self.gOsc = np.array(allgTO)
-        self.osc = np.array([self.wOsc, np.array(Q), self.gOsc])
-        return
-
-    def calcSurfaceLoss(self,x):
-        ''' Calculate the surface loss spectrum for the array of x, which needs to be an equidistant array. 
-        All parameters are defined in the class __init__() call.'''
-        wmin = min(x)
-        wmax = max(x)-0.001
-        dw = (wmax-wmin)/(len(x)-1)     # assumes that x is an equidistant array
-        wn_array_size = len(x)     # size of array for x and epsilon (wn_array, loss_array)
-        nper = 1.
-        contrl = '{:<10}'.format('None'[:10])   # Can be 'image' to include image charge
-        mode = '{:<10}'.format('kurosawa'[:10])           
-        wn_array,loss_array = LambinEELS4.mod_doeels.doeels(self.e0,self.theta,self.phia,self.phib,
-            wmin,wmax,dw,self.layers,self.neps,nper,self.name,
-            self.thick,self.epsinf,self.listNOsci,self.osc,contrl,mode,wn_array_size)
-        i=0
-        for item in wn_array:
-            if item > 0: break
-            i += 1
-        return wn_array[i-1:], loss_array[i-1:]
-
-    def calcHREELS(self,x, normalized=True, areanormalized=False):
-        emin = min(x)
-        emax = max(x)-0.001
-        norm = 1
-        xLoss,loss_array = self.calcSurfaceLoss(x)
-        wmin = min(xLoss)
-        wmax = max(xLoss)
-        xOut,spectrum,n = LambinBoson.doboson3(self.temperature,self.width,self.gauss,self.asym,
-            emin,emax,wmin,wmax,loss_array,self.debug,len(loss_array))
-        if normalized:
-            norm = max(spectrum[:n])
-            #print("peak normalized, norm=", norm)
-            if areanormalized: #edit by HHE
-                try:                    
-                    areanormalize_xstart = np.argmin(abs(x+100.)) #seems to be oddly complicated, but is way more stable than x.index(-100.) or where()
-                except:
-                    areanormalize_xstart = 0
-                try:
-                    areanormalize_xend = np.argmin(abs(x-1000.))
-                except:
-                    areanormalize_xend = len(x)
-                #norm=spectrum[areanormalize_xstart:areanormalize_xend].sum()
-                cropped_spectra=spectrum[areanormalize_xstart:areanormalize_xend]
-                cropped_x=x[areanormalize_xstart:areanormalize_xend]
-
-                #norm=cropped_spectra.sum()/len(cropped_x)*(x[areanormalize_xend]-x[areanormalize_xstart])
-                #print(len(cropped_x), len(cropped_spectra), len(x), len(spectrum))
-                #print(cropped_spectra.sum(), len(cropped_x),x[areanormalize_xend]-x[areanormalize_xstart])
-                norm=integrate.simps(cropped_spectra, dx=x[areanormalize_xstart+1]-x[areanormalize_xstart])#/(1100/(max(cropped_x)-min(cropped_x)))
-                #print("areanormalized, norm=", norm, " dx=", x[areanormalize_xstart+1]-x[areanormalize_xstart])
-        else:
-            print("not normalized")
-        return xOut[:len(x)], spectrum[:len(x)]/norm
-
-    def calcEps(self, x):
-        epsArray = []
-        nOsci = len(self.wOsc)
-        for wn in x:
-            yn = LambinEELS4.mod_doeels.seteps(self.listNOsci,nOsci,self.osc,self.epsinf,wn,self.layers)
-            epsArray.append(yn)
-        return np.transpose(np.array(epsArray))
-
-####################################################################################
-def myMain():
-    import matplotlib.pyplot as plt
-    import numpy as np
-    from copy import deepcopy
-    import os
-
-    x = np.linspace(-100.,1000,400)
-    x2 = np.linspace(-100.,1000,2400)
-    
-
-    material = {'eps': 4.,
-                'wTO': [0],  'gTO': [20], 'wLO': [598.7], 'gLO': [20],
-                }
-
-    film1 = lambin(film=[[material,10000.]])
-    film1.temperature = 100
-    #xs, spectrum = film1.calcSurfaceLoss(x)
-    xs, spectrum = film1.calcHREELS(x,normalized=False,areanormalized=False)
-    xs1, spectrum1 = film1.calcHREELS(x2,normalized=False,areanormalized=False)
-    xs2, spectrum2 = film1.calcHREELS(x,areanormalized=True)
-    xs3, spectrum3 = film1.calcHREELS(x2,areanormalized=True)
-
-    norm_test=integrate.simps(spectrum, dx=xs[2]-xs[1])/(max(xs)-min(xs))
-    norm_test1=integrate.simps(spectrum1, dx=xs1[2]-xs1[1])/(max(xs1)-min(xs1))
-    norm_test2=integrate.simps(spectrum2, dx=xs2[2]-xs2[1])/(max(xs2)-min(xs2))
-    norm_test3=integrate.simps(spectrum3, dx=xs3[2]-xs3[1])/(max(xs3)-min(xs3))
-    print(norm_test,norm_test1,norm_test2,norm_test3)
-    print(xs[2]-xs[1],xs1[2]-xs1[1],xs2[2]-xs2[1],xs3[2]-xs3[1])
-    
-    plt.plot(xs[:-1],spectrum[:-1], label='normalized=Flase, '+str(len(x))+' points, E0 at '+str(max(spectrum)))
-    plt.plot(xs1[:-2],spectrum1[:-2], label='normalized=Flase, '+str(len(x2))+' points, E0 at '+str(max(spectrum1)))
-    plt.plot(xs2[:-10],spectrum2[:-10],label='area normalized=True, '+str(len(x))+' points, E0 at '+str(max(spectrum2)))
-    plt.plot(xs3[:-20],spectrum3[:-20],label='area normalized=True, '+str(len(x2))+' points, E0 at '+str(max(spectrum3)))
-
-    print('spec2/spec0=', max(spectrum2)/max(spectrum))
-    print('spec3/spec0=', max(spectrum3)/max(spectrum))
-    print('spec0/spec2=', max(spectrum)/max(spectrum2))
-    print('spec0/spec3=', max(spectrum)/max(spectrum3))
-
-    # pureDrude = {'eps': 4.,
-    #             'wTO': [-400],  'gTO': [-20], 'wLO': [0], 'gLO': [0],
-    #             }
-    # film2 = lambin(film=[[pureDrude,10000.]])
-    # film2.temperature = 100
-    # xs, spectrum = film2.calcSurfaceLoss(x)
-    # plt.plot(xs,spectrum,'g-.', label='pure Drude 400')
-
-
-    plt.ylabel('Surface Loss')
-    plt.xlabel('Energy Loss (cm$^{-1}$)')
-    plt.legend(title=r'Plasma frequency')
-
-    plt.text(0.99, 0.01,os.path.basename(__file__), fontsize=10, ha='right', va='bottom', transform=plt.gcf().transFigure)
-    output_filename = os.path.splitext(__file__)[0] + '.png'
-    plt.savefig(output_filename)
-
-    plt.show()
-
-
-if __name__ == '__main__':
-	myMain()
\ No newline at end of file
diff --git a/Python code/libhreels/dielectrics.py b/Python code/libhreels/dielectrics.py
index ab35bca..6438a9f 100755
--- a/Python code/libhreels/dielectrics.py	
+++ b/Python code/libhreels/dielectrics.py	
@@ -2,16 +2,26 @@
 import matplotlib.pyplot as plt
 import numpy as np
 from numpy import real, imag, sqrt
+from scipy import constants
 
-#from scipy.constants import physical_constants
 
-# Thz = 100*physical_constants['speed of light in vacuum'][0] # conversion from cm^-1 to Hz 
+def doping2chargecarrierdensity(doping): #use doping in percentage by mass, not volume
+    '''Returns the charge carrier density for a given doping in percentage of mass.'''
+    return float(doping*3.31664067935517E+020*1E6) # doping[%] * charge carrier/cm^3 * 1E6 = n_e [m^-3] 
 
-def doping2plasmaFrequency(doping,epsInfinity=1.):
-    '''Returns the bulk plasma frequency in cm-1 for a doping 
-       given by the argument in cm-3.
-       Check if eps_Infinity handling is correct.'''
-    return np.sqrt(doping)*1.8817885780819758e-06/np.sqrt(epsInfinity)
+def doping2plasmaFrequency(doping,epsInfinity=1.): #use doping in percentage by mass, not volume
+    '''Returns the plasma frequency for a given doping in percentage of mass.'''
+    eps_0 = constants.value("vacuum electric permittivity")
+    e = constants.value('elementary charge')
+    m_e = constants.value('electron mass')
+    c = constants.value('speed of light in vacuum') 
+    eps_r = epsInfinity
+    n_e = doping2chargecarrierdensity(doping)
+
+    w_P = np.sqrt(n_e*e*e/(eps_r*eps_0*m_e)) #Hz
+    w_P = w_P /1E+12 * 33.35641 #Hz -> THz -> cm^-1
+    return w_P 
+    
 
 def doping2surfacePlasma(doping,epsInfinity=1.):
     '''Returns the surface plasma frequency in cm-1 for a doping 
@@ -19,140 +29,217 @@ def doping2surfacePlasma(doping,epsInfinity=1.):
     return np.sqrt(doping)*1.8817885780819758e-06/np.sqrt(1+epsInfinity)
 
 def loss(eps):
-    return np.imag(1/eps)
+    '''Returns the loss function for a given eps'''
+    return np.imag(eps) #HHE changed former sign
 
 def surfaceLoss(eps):
-    return np.imag(1/(1+eps))
+    '''Returns the surface loss function for a given eps'''
+    return np.imag(-1/(1+eps)) #HHE changed former sign, according to Phd of FSc
 
 def reflectivity(eps):  # IR reflectivity
-    #print("eps in reflect: ",eps[1])
+    '''Returns the reflectivity for a given eps'''
     sq = np.sqrt(eps)
-    a =np.abs((sq-1)/(sq+1))
-    #print("a in reflect: ",a[1])
+    a = np.abs((sq-1)/(sq+1))
     return a*a
 
-def sigma(eps,w,eps_Infinity=1):       # Complex conductivity 
-    return np.imag((eps-eps_Infinity)*w)
+def sigma(eps,w):       
+    '''Returns the complex conductivity for a given eps'''
+    return (eps-1)*w/1j
 
-def plotDielectrics(x,eps,titlee=" ", flag_plot_show=True):
-    fig, axs = plt.subplots(3, 1, sharex=True, figsize=(6,6))
-    axs[0].plot(x, -np.imag(eps), label='-Im $\epsilon (\omega )$')
-    axs[0].plot(x, np.real(eps), label='Re $\epsilon (\omega )$')    
+def plotDielectrics(x,eps, title=" ", plot_show=True):
+    '''This method plots a given (x,eps)-dataset as Re/Im(eps), SurfaceLoss and Reflectivity 
+    '''
+    fig, axs = plt.subplots(3, 1, sharex=True)
+    fig.suptitle(str(title), fontsize=16)
+    axs[0].plot(x, np.imag(eps), label='Im( $\epsilon (\omega )$ )')
+    axs[0].plot(x, np.real(eps), label='Re( $\epsilon (\omega )$ )')
     axs[0].legend()
     axs[0].set_ylabel('Dielectric Function')
 
-    axs[1].plot(x, surfaceLoss(eps), linestyle='-')    
+    axs[1].plot(x, surfaceLoss(eps), lineStyle='-', label='Loss function')    
     axs[1].set_ylabel('Surface Loss Function')
-    axs[1].set_ylim([0,None])
+    axs[1].set_ylim([-0.10,None])
 
     axs[2].plot(x, reflectivity(eps))
     axs[2].set_ylabel('Reflectivity')
     axs[2].set_xlabel('Frequency')
-    axs[2].set_ylim([0,1])
+    axs[2].set_ylim([0.0,1])
     axs[0].set_xlim(left=0, right=max(x))
 
-    fig.suptitle(str(titlee), fontsize=16)
-    if flag_plot_show == True:
+    if plot_show==True:
         plt.show()
+
 class oscillator:
-    #print("class oscillator is called") #added by HHe
-    def __init__(self, wTO, wLO, gammaTO=20, gammaLO=20):
+    '''This defines epsilon of an oscillator with a given (wTO, gTO, wLO, gLO)
+    '''
+    def __init__(self, wTO=177., gTO=20., wLO=184., gLO=20.):
         self.wTO = wTO
         self.wLO = wLO
-        self.gammaTO = gammaTO
-        self.gammaLO = gammaLO
-
-        #print("wTO, wLO, gTO, gLO",wTO,wLO,gammaTO,gammaLO) #added by HHe
+        self.gammaTO = gTO
+        self.gammaLO = gLO
 
     def eps(self,w):
-        nom = self.wLO*self.wLO - w*w + 1j*self.gammaLO*w
-        denom = self.wTO*self.wTO - w*w + 1j*self.gammaTO*w
+        nom = self.wLO*self.wLO - w*w - 1j*w*self.gammaLO   #sign changed according to gervais paper, formular 2 -> neg im(eps), therefore changed back to lambins kurosawa
+        denom = self.wTO*self.wTO - w*w - 1j*w*self.gammaTO #sign changed according to gervais paper, formular 2 -> neg im(eps), therefore changed back to lambins kurosawa
         return nom/denom
 
     def __call__(self, w):
         return self.eps(w)
 
-class simpleOsci:#(oscillator): #added by HHe
-    #print("class simpleOsci is called") #added by HHe
-    def __init__(self, wTO, Q, gammaTO=20):
-        self.wTO = wTO
-        self.Q = Q
-        self.gammaTO = gammaTO
+class drude:
+    '''This defines an additive Drude component to a dielectric function: 
+    eps_drude = drude2(omega_p, gamma_p, gamma_0)
+    ... eps(omega) + eps_drude(omega)
+    '''
+    def __init__(self, omega_p, gamma_p, gamma_0):
 
-        print("wTO, Q, gTO",wTO,Q,gammaTO) #added by HHe
+        self.omega_p = omega_p
+        self.gamma_p = gamma_p
+        self.gamma_0 = gamma_0
+
+        print("called drude with w_P, g_P, g_0:", omega_p, gamma_p, gamma_0)
+        
 
     def eps(self,w):
-        nom = self.wTO*self.wTO*self.Q
-        denom = self.wTO*self.wTO - w*w + 1j*self.gammaTO*w
-        return nom/denom
+        newW = np.where(w==0, 0.000567894, w)   # Avoid zeros to avoid devision by zero 
+        w = newW
+        #print("Drude (x,y): ", w, -((self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p))/(w*w + 1j*w*self.gamma_0)))
 
-    def __call__(self, w): #added by HHe
-        return self.eps(w)
+        nom = self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p)
+        denom = w*w + 1j*w*self.gamma_0 #sign changed according to Lambin notation
 
+        return -(nom/denom) #HHE changed 
 
-class drude:
-    '''Returns the additive Drude response with plasma frequency and damping as parameters. Note that for the
-    full dielctric response, this Drude contribution has to be added to eps_infinity and any phonon
-    contribution.
+    def __call__(self, w):
+        return self.eps(w)
+
+    
+class cole_davidson:
+    '''This defines an additive Cole-Davidson component to a dielectric function: 
+    eps_cole_davidson = cole_davidson(omega_p, gamma_p, gamma_0)
+    ... eps(omega) + eps_drude(omega)
     '''
-    def __init__(self, wPL, gamma):
-        self.wPL = wPL
-        self.gamma = gamma
+    def __init__(self, omega_p, gamma_p, gamma_0, beta):
 
-    def eps(self,w):
-        # Starting from libhreels version 1.1.4, it has been corrected:
-        return -(self.wPL*self.wPL)/(w*w - 1j*self.gamma*w)
+        self.omega_p = omega_p
+        self.gamma_p = gamma_p
+        self.gamma_0 = gamma_0
+        self.beta = beta
+
+        print("called coledavidson with w_P, g_P, g_0, beta:", omega_p, gamma_p, gamma_0, beta)
     
 
+    def eps(self,w):
+        newW = np.where(w==0, 0.000567894, w)   # Avoid zeros to avoid devision by zero 
+        w = newW
+        #print("Drude (x,y): ", w, -((self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p))/(w*w + 1j*w*self.gamma_0)))
+        #return -((self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p))/(w*w + 1j*w*self.gamma_0)) #HHE changed 
+        
+        #nom = self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p) #very simple approach by just putting an exponent to denominator (works only for gamma_0=gamma_P)
+        #denom = (w*w - 1j*w*self.gamma_0)**self.beta  #sign changed according to gervais paper, formular 7
+
+        hilf = 1j * w * self.gamma_0 * (1-1j*w*(1/self.gamma_0))**(self.beta)
+
+        nom = self.omega_p**2 - 1j*w*(self.gamma_p) - w*w + hilf #unfortunately also the nominator changes due to cole-davidson
+        denom = hilf   #sign changed according to gervais paper, formular 7 -> did not match, changed back to lambin formularism
+
+
+        return -(nom/denom)
+
     def __call__(self, w):
         return self.eps(w)
 
-class drude2:
-    '''Returns the additive extended Drude response with three arguments: plasma frequency and two damping
-    parameters. The first damping parameter is the plasma damping and the second the damping at frequency
-    zero. Note that for the full dielectric response, this Drude contribution has to be added to eps_infinity
-    and any phonon contribution. 
-
-        eps = drude2(omega_p, gamma_p, gamma_0)
+class cole_cole:
+    '''This defines an additive Cole-Davidson component to a dielectric function: 
+    eps_cole_cole = cole_cole(omega_p, gamma_p, gamma_0, beta)
+    ... 
     '''
-    def __init__(self, omega_p, gamma_p, gamma_0=None):
+    def __init__(self, omega_p, gamma_p, gamma_0, beta):
+
         self.omega_p = omega_p
         self.gamma_p = gamma_p
-        if gamma_0:
-            self.gamma_0 = gamma_0
-        else:
-            self.gamma_0 = gamma_p
+        self.gamma_0 = gamma_0
+        self.beta = beta
+
+        print("called colecole with w_P, g_P, g_0, beta:", omega_p, gamma_p, gamma_0, beta)
 
     def eps(self,w):
         newW = np.where(w==0, 0.000567894, w)   # Avoid zeros to avoid devision by zero 
         w = newW
-        return -((self.omega_p**2 + 1j*(self.gamma_p-self.gamma_0)*w)/(w*(w - 1j *self.gamma_0)))
+        #nom = self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p) #very simple approach by just putting an exponent to denominator (works only for gamma_0=gamma_P)
+        #denom = w*w + w*(1j*self.gamma_0)**self.beta
+
+        hilf = 1j**(self.beta+1) * w**(self.beta+1) * self.gamma_0**(1-self.beta)
+
+        nom = self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p) - w*w - hilf #unfortunately also the nominator changes due to cole-cole 
+        denom = 1j*w*(self.gamma_0) - hilf   #sign changed according to lambin formularism
+
+        return -(nom/denom)
 
     def __call__(self, w):
         return self.eps(w)
 
+
+class simpleOscillator(oscillator):
+    '''This defines epsilon of an oscillator with a given (wPl, Q and gTO)
+    '''
+    def __init__(self, wPl, Q, gTO=20):
+        self.wPl = wPl
+        self.Q = Q
+        self.gammaTO = gTO
+
+    def eps(self,w):
+        nom = self.wPl*self.wPl*self.Q
+        denom = self.wPl*self.wPl - w*w - 1j*self.gammaTO*w #HHE changed, wrong sign of Im
+        return nom/denom
+
+class simpleDrude:
+    '''This defines epsilon of an oscillator with a given (wPl, gamma). gamma = gammaTO = gammaLO
+    '''
+    def __init__(self, wPL, gamma):
+        self.wPL = wPL
+        self.gamma = gamma
+
+    def eps(self,w):
+        return -(self.wPL*self.wPL)/(w*w-1j*w*self.gamma) #HHE changed 
+
+    def __call__(self, w):
+        return self.eps(w)
+
+
+
 def myMain():
     # BaTiO3
-    data = [
+    simple_data = [
         [178.6, 8.02, 3.09800E-02],
         [270.6, 24.00, 10.0800E-02],
         [522.9, 1.20, 6.97200E-02]]
-   # Width (3rd parameter) is given in fraction of TO frequency
 
-    oscis = [simpleOsci(TO, Q, f*TO) for (TO, Q, f) in data]
+    data = [
+        [177.4 , 1.9262 , 184.003 , 9.718],
+        [272.84 , 93.3091 , 470.972 ,  14.31 ],
+        [506.379 , 42.60 , 739.651 , 33.044],
+    ]  
         
-    x = np.linspace(5,1000,num=1200)
+    x = np.linspace(0,1000,num=1200)
     epsInfinity = 5.25
+
+    simpleoscis = [simpleOscillator(TO, Q, f*TO) for (TO, Q, f) in simple_data]
     eps = epsInfinity
-    for each in oscis:
-        eps += each(x)
+    for each in simpleoscis:
+        eps += each(x) #sum
+    plotDielectrics(x, eps, title="Eps of BaTiO calced with simpleOscillator", plot_show=False)
 
-    # Now add Drude contribution:
-    eps += drude2(1200,60)(x)
-    plotDielectrics(x, eps)
+    oscis = [oscillator(wTO=a, wLO=c, gTO=b, gLO=d) for (a, b, c, d) in data]
+    eps2 = epsInfinity
+    for each in oscis:
+        eps2 *= each(x) #kurosawa
+    plotDielectrics(x, eps2, title="Eps of BaTiO calced with oscillator", plot_show=False)
 
-    print("hallo:")
-    print(doping2plasmaFrequency(1E19,epsInfinity=5.2))
+    plt.show()
 
 if __name__ == '__main__':
-	myMain()
+    print(doping2plasmaFrequency(0.05,3.024434))
+    print(doping2plasmaFrequency(0.1,4.57655596))
+
+    myMain()
diff --git a/Python code/libhreels/dielectrics2.py b/Python code/libhreels/dielectrics2.py
deleted file mode 100755
index 6438a9f..0000000
--- a/Python code/libhreels/dielectrics2.py	
+++ /dev/null
@@ -1,245 +0,0 @@
-# Testing dielectric models and their surface loss function
-import matplotlib.pyplot as plt
-import numpy as np
-from numpy import real, imag, sqrt
-from scipy import constants
-
-
-def doping2chargecarrierdensity(doping): #use doping in percentage by mass, not volume
-    '''Returns the charge carrier density for a given doping in percentage of mass.'''
-    return float(doping*3.31664067935517E+020*1E6) # doping[%] * charge carrier/cm^3 * 1E6 = n_e [m^-3] 
-
-def doping2plasmaFrequency(doping,epsInfinity=1.): #use doping in percentage by mass, not volume
-    '''Returns the plasma frequency for a given doping in percentage of mass.'''
-    eps_0 = constants.value("vacuum electric permittivity")
-    e = constants.value('elementary charge')
-    m_e = constants.value('electron mass')
-    c = constants.value('speed of light in vacuum') 
-    eps_r = epsInfinity
-    n_e = doping2chargecarrierdensity(doping)
-
-    w_P = np.sqrt(n_e*e*e/(eps_r*eps_0*m_e)) #Hz
-    w_P = w_P /1E+12 * 33.35641 #Hz -> THz -> cm^-1
-    return w_P 
-    
-
-def doping2surfacePlasma(doping,epsInfinity=1.):
-    '''Returns the surface plasma frequency in cm-1 for a doping 
-       given by the argument in cm-3'''
-    return np.sqrt(doping)*1.8817885780819758e-06/np.sqrt(1+epsInfinity)
-
-def loss(eps):
-    '''Returns the loss function for a given eps'''
-    return np.imag(eps) #HHE changed former sign
-
-def surfaceLoss(eps):
-    '''Returns the surface loss function for a given eps'''
-    return np.imag(-1/(1+eps)) #HHE changed former sign, according to Phd of FSc
-
-def reflectivity(eps):  # IR reflectivity
-    '''Returns the reflectivity for a given eps'''
-    sq = np.sqrt(eps)
-    a = np.abs((sq-1)/(sq+1))
-    return a*a
-
-def sigma(eps,w):       
-    '''Returns the complex conductivity for a given eps'''
-    return (eps-1)*w/1j
-
-def plotDielectrics(x,eps, title=" ", plot_show=True):
-    '''This method plots a given (x,eps)-dataset as Re/Im(eps), SurfaceLoss and Reflectivity 
-    '''
-    fig, axs = plt.subplots(3, 1, sharex=True)
-    fig.suptitle(str(title), fontsize=16)
-    axs[0].plot(x, np.imag(eps), label='Im( $\epsilon (\omega )$ )')
-    axs[0].plot(x, np.real(eps), label='Re( $\epsilon (\omega )$ )')
-    axs[0].legend()
-    axs[0].set_ylabel('Dielectric Function')
-
-    axs[1].plot(x, surfaceLoss(eps), lineStyle='-', label='Loss function')    
-    axs[1].set_ylabel('Surface Loss Function')
-    axs[1].set_ylim([-0.10,None])
-
-    axs[2].plot(x, reflectivity(eps))
-    axs[2].set_ylabel('Reflectivity')
-    axs[2].set_xlabel('Frequency')
-    axs[2].set_ylim([0.0,1])
-    axs[0].set_xlim(left=0, right=max(x))
-
-    if plot_show==True:
-        plt.show()
-
-class oscillator:
-    '''This defines epsilon of an oscillator with a given (wTO, gTO, wLO, gLO)
-    '''
-    def __init__(self, wTO=177., gTO=20., wLO=184., gLO=20.):
-        self.wTO = wTO
-        self.wLO = wLO
-        self.gammaTO = gTO
-        self.gammaLO = gLO
-
-    def eps(self,w):
-        nom = self.wLO*self.wLO - w*w - 1j*w*self.gammaLO   #sign changed according to gervais paper, formular 2 -> neg im(eps), therefore changed back to lambins kurosawa
-        denom = self.wTO*self.wTO - w*w - 1j*w*self.gammaTO #sign changed according to gervais paper, formular 2 -> neg im(eps), therefore changed back to lambins kurosawa
-        return nom/denom
-
-    def __call__(self, w):
-        return self.eps(w)
-
-class drude:
-    '''This defines an additive Drude component to a dielectric function: 
-    eps_drude = drude2(omega_p, gamma_p, gamma_0)
-    ... eps(omega) + eps_drude(omega)
-    '''
-    def __init__(self, omega_p, gamma_p, gamma_0):
-
-        self.omega_p = omega_p
-        self.gamma_p = gamma_p
-        self.gamma_0 = gamma_0
-
-        print("called drude with w_P, g_P, g_0:", omega_p, gamma_p, gamma_0)
-        
-
-    def eps(self,w):
-        newW = np.where(w==0, 0.000567894, w)   # Avoid zeros to avoid devision by zero 
-        w = newW
-        #print("Drude (x,y): ", w, -((self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p))/(w*w + 1j*w*self.gamma_0)))
-
-        nom = self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p)
-        denom = w*w + 1j*w*self.gamma_0 #sign changed according to Lambin notation
-
-        return -(nom/denom) #HHE changed 
-
-    def __call__(self, w):
-        return self.eps(w)
-
-    
-class cole_davidson:
-    '''This defines an additive Cole-Davidson component to a dielectric function: 
-    eps_cole_davidson = cole_davidson(omega_p, gamma_p, gamma_0)
-    ... eps(omega) + eps_drude(omega)
-    '''
-    def __init__(self, omega_p, gamma_p, gamma_0, beta):
-
-        self.omega_p = omega_p
-        self.gamma_p = gamma_p
-        self.gamma_0 = gamma_0
-        self.beta = beta
-
-        print("called coledavidson with w_P, g_P, g_0, beta:", omega_p, gamma_p, gamma_0, beta)
-    
-
-    def eps(self,w):
-        newW = np.where(w==0, 0.000567894, w)   # Avoid zeros to avoid devision by zero 
-        w = newW
-        #print("Drude (x,y): ", w, -((self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p))/(w*w + 1j*w*self.gamma_0)))
-        #return -((self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p))/(w*w + 1j*w*self.gamma_0)) #HHE changed 
-        
-        #nom = self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p) #very simple approach by just putting an exponent to denominator (works only for gamma_0=gamma_P)
-        #denom = (w*w - 1j*w*self.gamma_0)**self.beta  #sign changed according to gervais paper, formular 7
-
-        hilf = 1j * w * self.gamma_0 * (1-1j*w*(1/self.gamma_0))**(self.beta)
-
-        nom = self.omega_p**2 - 1j*w*(self.gamma_p) - w*w + hilf #unfortunately also the nominator changes due to cole-davidson
-        denom = hilf   #sign changed according to gervais paper, formular 7 -> did not match, changed back to lambin formularism
-
-
-        return -(nom/denom)
-
-    def __call__(self, w):
-        return self.eps(w)
-
-class cole_cole:
-    '''This defines an additive Cole-Davidson component to a dielectric function: 
-    eps_cole_cole = cole_cole(omega_p, gamma_p, gamma_0, beta)
-    ... 
-    '''
-    def __init__(self, omega_p, gamma_p, gamma_0, beta):
-
-        self.omega_p = omega_p
-        self.gamma_p = gamma_p
-        self.gamma_0 = gamma_0
-        self.beta = beta
-
-        print("called colecole with w_P, g_P, g_0, beta:", omega_p, gamma_p, gamma_0, beta)
-
-    def eps(self,w):
-        newW = np.where(w==0, 0.000567894, w)   # Avoid zeros to avoid devision by zero 
-        w = newW
-        #nom = self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p) #very simple approach by just putting an exponent to denominator (works only for gamma_0=gamma_P)
-        #denom = w*w + w*(1j*self.gamma_0)**self.beta
-
-        hilf = 1j**(self.beta+1) * w**(self.beta+1) * self.gamma_0**(1-self.beta)
-
-        nom = self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p) - w*w - hilf #unfortunately also the nominator changes due to cole-cole 
-        denom = 1j*w*(self.gamma_0) - hilf   #sign changed according to lambin formularism
-
-        return -(nom/denom)
-
-    def __call__(self, w):
-        return self.eps(w)
-
-
-class simpleOscillator(oscillator):
-    '''This defines epsilon of an oscillator with a given (wPl, Q and gTO)
-    '''
-    def __init__(self, wPl, Q, gTO=20):
-        self.wPl = wPl
-        self.Q = Q
-        self.gammaTO = gTO
-
-    def eps(self,w):
-        nom = self.wPl*self.wPl*self.Q
-        denom = self.wPl*self.wPl - w*w - 1j*self.gammaTO*w #HHE changed, wrong sign of Im
-        return nom/denom
-
-class simpleDrude:
-    '''This defines epsilon of an oscillator with a given (wPl, gamma). gamma = gammaTO = gammaLO
-    '''
-    def __init__(self, wPL, gamma):
-        self.wPL = wPL
-        self.gamma = gamma
-
-    def eps(self,w):
-        return -(self.wPL*self.wPL)/(w*w-1j*w*self.gamma) #HHE changed 
-
-    def __call__(self, w):
-        return self.eps(w)
-
-
-
-def myMain():
-    # BaTiO3
-    simple_data = [
-        [178.6, 8.02, 3.09800E-02],
-        [270.6, 24.00, 10.0800E-02],
-        [522.9, 1.20, 6.97200E-02]]
-
-    data = [
-        [177.4 , 1.9262 , 184.003 , 9.718],
-        [272.84 , 93.3091 , 470.972 ,  14.31 ],
-        [506.379 , 42.60 , 739.651 , 33.044],
-    ]  
-        
-    x = np.linspace(0,1000,num=1200)
-    epsInfinity = 5.25
-
-    simpleoscis = [simpleOscillator(TO, Q, f*TO) for (TO, Q, f) in simple_data]
-    eps = epsInfinity
-    for each in simpleoscis:
-        eps += each(x) #sum
-    plotDielectrics(x, eps, title="Eps of BaTiO calced with simpleOscillator", plot_show=False)
-
-    oscis = [oscillator(wTO=a, wLO=c, gTO=b, gLO=d) for (a, b, c, d) in data]
-    eps2 = epsInfinity
-    for each in oscis:
-        eps2 *= each(x) #kurosawa
-    plotDielectrics(x, eps2, title="Eps of BaTiO calced with oscillator", plot_show=False)
-
-    plt.show()
-
-if __name__ == '__main__':
-    print(doping2plasmaFrequency(0.05,3.024434))
-    print(doping2plasmaFrequency(0.1,4.57655596))
-
-    myMain()
diff --git a/Python code/libhreels/dielectrics2_save.py b/Python code/libhreels/dielectrics2_save.py
deleted file mode 100755
index e4dabbd..0000000
--- a/Python code/libhreels/dielectrics2_save.py	
+++ /dev/null
@@ -1,250 +0,0 @@
-# Testing dielectric models and their surface loss function
-import matplotlib.pyplot as plt
-import numpy as np
-from numpy import real, imag, sqrt
-from scipy import constants
-
-
-def doping2chargecarrierdensity(doping): #use doping in percentage by mass, not volume
-    '''Returns the charge carrier density for a given doping in percentage of mass.'''
-    return float(doping*3.31664067935517E+020*1E6) # doping[%] * charge carrier/cm^3 * 1E6 = n_e [m^-3] 
-
-def doping2plasmaFrequency(doping,epsInfinity=1.): #use doping in percentage by mass, not volume
-    '''Returns the plasma frequency for a given doping in percentage of mass.'''
-    eps_0 = constants.value("vacuum electric permittivity")
-    e = constants.value('elementary charge')
-    m_e = constants.value('electron mass')
-    c = constants.value('speed of light in vacuum') 
-    eps_r = epsInfinity
-    n_e = doping2chargecarrierdensity(doping)
-
-    w_P = np.sqrt(n_e*e*e/(eps_r*eps_0*m_e)) #Hz
-    w_P = w_P /1E+12 * 33.35641 #Hz -> THz -> cm^-1
-    return w_P 
-    
-
-def doping2surfacePlasma(doping,epsInfinity=1.):
-    '''Returns the surface plasma frequency in cm-1 for a doping 
-       given by the argument in cm-3'''
-    return np.sqrt(doping)*1.8817885780819758e-06/np.sqrt(1+epsInfinity)
-
-def loss(eps):
-    '''Returns the loss function for a given eps'''
-    return np.imag(eps) #HHE changed former sign
-
-def surfaceLoss(eps):
-    '''Returns the surface loss function for a given eps'''
-    return np.imag(-1/(1+eps)) #HHE changed former sign, according to Phd of FSc
-
-def reflectivity(eps):  # IR reflectivity
-    '''Returns the reflectivity for a given eps'''
-    sq = np.sqrt(eps)
-    a = np.abs((sq-1)/(sq+1))
-    return a*a
-
-def sigma(eps,w):       
-    '''Returns the complex conductivity for a given eps'''
-    return (eps-1)*w/1j
-
-def plotDielectrics(x,eps, title=" ", plot_show=True):
-    '''This method plots a given (x,eps)-dataset as Re/Im(eps), SurfaceLoss and Reflectivity 
-    '''
-    fig, axs = plt.subplots(3, 1, sharex=True)
-    fig.suptitle(str(title), fontsize=16)
-    axs[0].plot(x, np.imag(eps), label='Im( $\epsilon (\omega )$ )')
-    axs[0].plot(x, np.real(eps), label='Re( $\epsilon (\omega )$ )')
-    axs[0].legend()
-    axs[0].set_ylabel('Dielectric Function')
-
-    axs[1].plot(x, surfaceLoss(eps), lineStyle='-', label='Loss function')    
-    axs[1].set_ylabel('Surface Loss Function')
-    axs[1].set_ylim([-0.10,None])
-
-    axs[2].plot(x, reflectivity(eps))
-    axs[2].set_ylabel('Reflectivity')
-    axs[2].set_xlabel('Frequency')
-    axs[2].set_ylim([0.0,1])
-    axs[0].set_xlim(left=0, right=max(x))
-
-    if plot_show==True:
-        plt.show()
-
-class oscillator:
-    '''This defines epsilon of an oscillator with a given (wTO, gTO, wLO, gLO)
-    '''
-    def __init__(self, wTO=177., gTO=20., wLO=184., gLO=20.):
-        self.wTO = wTO
-        self.wLO = wLO
-        self.gammaTO = gTO
-        self.gammaLO = gLO
-
-    def eps(self,w):
-        nom = self.wLO*self.wLO - w*w - 1j*w*self.gammaLO   #HHE changed, wrong sign of Im
-        denom = self.wTO*self.wTO - w*w - 1j*w*self.gammaTO #HHE changed, wrong sign of Im
-        return nom/denom
-
-    def __call__(self, w):
-        return self.eps(w)
-
-class drude:
-    '''This defines an additive Drude component to a dielectric function: 
-    eps_drude = drude2(omega_p, gamma_p, gamma_0)
-    ... eps(omega) + eps_drude(omega)
-    '''
-    def __init__(self, omega_p, gamma_p, gamma_0):
-
-        self.omega_p = omega_p
-        self.gamma_p = gamma_p
-        self.gamma_0 = gamma_0
-
-        print("called drude with w_P, g_P, g_0:", omega_p, gamma_p, gamma_0)
-        
-
-    def eps(self,w):
-        newW = np.where(w==0, 0.000567894, w)   # Avoid zeros to avoid devision by zero 
-        w = newW
-        #print("Drude (x,y): ", w, -((self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p))/(w*w + 1j*w*self.gamma_0)))
-
-        nom = self.omega_p**2 + 1j*w*(self.gamma_p-self.gamma_0)
-        denom = w*w - 1j*w*self.gamma_0 #sign changed according to gervais paper, formular 7
-
-        return -(nom/denom) #HHE changed 
-
-    def __call__(self, w):
-        return self.eps(w)
-
-    
-class cole_davidson:
-    '''This defines an additive Cole-Davidson component to a dielectric function: 
-    eps_cole_davidson = cole_davidson(omega_p, gamma_p, gamma_0)
-    ... eps(omega) + eps_drude(omega)
-    '''
-    def __init__(self, omega_p, gamma_p, gamma_0, beta):
-
-        self.omega_p = omega_p
-        self.gamma_p = gamma_p
-        self.gamma_0 = gamma_0
-        self.beta = beta
-
-        print("called coledavidson with w_P, g_P, g_0, beta:", omega_p, gamma_p, gamma_0, beta)
-    
-
-    def eps(self,w):
-        newW = np.where(w==0, 0.000567894, w)   # Avoid zeros to avoid devision by zero 
-        w = newW
-        #print("Drude (x,y): ", w, -((self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p))/(w*w + 1j*w*self.gamma_0)))
-        #return -((self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p))/(w*w + 1j*w*self.gamma_0)) #HHE changed 
-        
-        #nom = self.omega_p**2 * self.gamma_p**(1-self.beta)
-        #denom = 1j*w*(self.gamma_p-1j*w)**self.beta
-        #return -(nom/denom)
-
-        nom = self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p)**(1-self.beta) #just a try to recreate the drude with two gammas -> works only for gamma-0=gamma_p
-        denom =  1j*w*(self.gamma_0-1j*w)**self.beta
-        #return -(nom/denom)
-
-        #nom = self.omega_p**2 + 1j*w*(self.gamma_0**(1/self.beta)+self.gamma_p**(1/self.beta))**(self.beta) #seems to be correct analytically, but does not work at all
-        #denom =  1j*w*(self.gamma_0**(1/self.beta)+self.gamma_p**(1/self.beta))**self.beta
-
-        nom = self.omega_p**2 + +1j*w*self.gamma_p*(1-1j*w*self.gamma_p)**(1-self.beta) #lacking second gamma again, but works ok
-        denom = 1j*w*self.gamma_p*(1-1j*w*self.gamma_p)**(1-self.beta)
-
-        nom = self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p) #very simple approach by just putting an exponent to denominator (works only for gamma_0=gamma_P)
-        denom = (w*w - 1j*w*self.gamma_0)**self.beta  #sign changed according to gervais paper, formular 7
-        return -(nom/denom)
-
-    def __call__(self, w):
-        return self.eps(w)
-
-class cole_cole:
-    '''This defines an additive Cole-Davidson component to a dielectric function: 
-    eps_cole_cole = cole_cole(omega_p, gamma_p, gamma_0, beta)
-    ... 
-    '''
-    def __init__(self, omega_p, gamma_p, gamma_0, beta):
-
-        self.omega_p = omega_p
-        self.gamma_p = gamma_p
-        self.gamma_0 = gamma_0
-        self.beta = beta
-
-        print("called colecole with w_P, g_P, g_0, beta:", omega_p, gamma_p, gamma_0, beta)
-
-    def eps(self,w):
-        newW = np.where(w==0, 0.000567894, w)   # Avoid zeros to avoid devision by zero 
-        w = newW
-        #nom = self.omega_p**2 + 1j*w*(self.gamma_0-self.gamma_p) #very simple approach by just putting an exponent to denominator (works only for gamma_0=gamma_P)
-        #denom = w*w + w*(1j*self.gamma_0)**self.beta
-
-        nom = self.omega_p**2 + 1j*w*(self.gamma_p-self.gamma_0) - w*w + w**(1+self.beta)*self.gamma_0**(1-self.beta) #unfortunately also the nominator changes due to cole-cole 
-        denom = w**(1+self.beta)*self.gamma_0**(1-self.beta) - 1j*w*self.gamma_0  #sign changed according to gervais paper, formular 7
-
-        return -(nom/denom)
-
-    def __call__(self, w):
-        return self.eps(w)
-
-
-class simpleOscillator(oscillator):
-    '''This defines epsilon of an oscillator with a given (wPl, Q and gTO)
-    '''
-    def __init__(self, wPl, Q, gTO=20):
-        self.wPl = wPl
-        self.Q = Q
-        self.gammaTO = gTO
-
-    def eps(self,w):
-        nom = self.wPl*self.wPl*self.Q
-        denom = self.wPl*self.wPl - w*w - 1j*self.gammaTO*w #HHE changed, wrong sign of Im
-        return nom/denom
-
-class simpleDrude:
-    '''This defines epsilon of an oscillator with a given (wPl, gamma). gamma = gammaTO = gammaLO
-    '''
-    def __init__(self, wPL, gamma):
-        self.wPL = wPL
-        self.gamma = gamma
-
-    def eps(self,w):
-        return -(self.wPL*self.wPL)/(w*w-1j*w*self.gamma) #HHE changed 
-
-    def __call__(self, w):
-        return self.eps(w)
-
-
-
-def myMain():
-    # BaTiO3
-    simple_data = [
-        [178.6, 8.02, 3.09800E-02],
-        [270.6, 24.00, 10.0800E-02],
-        [522.9, 1.20, 6.97200E-02]]
-
-    data = [
-        [177.4 , 1.9262 , 184.003 , 9.718],
-        [272.84 , 93.3091 , 470.972 ,  14.31 ],
-        [506.379 , 42.60 , 739.651 , 33.044],
-    ]  
-        
-    x = np.linspace(0,1000,num=1200)
-    epsInfinity = 5.25
-
-    simpleoscis = [simpleOscillator(TO, Q, f*TO) for (TO, Q, f) in simple_data]
-    eps = epsInfinity
-    for each in simpleoscis:
-        eps += each(x) #sum
-    plotDielectrics(x, eps, title="Eps of BaTiO calced with simpleOscillator", plot_show=False)
-
-    oscis = [oscillator(wTO=a, wLO=c, gTO=b, gLO=d) for (a, b, c, d) in data]
-    eps2 = epsInfinity
-    for each in oscis:
-        eps2 *= each(x) #kurosawa
-    plotDielectrics(x, eps2, title="Eps of BaTiO calced with oscillator", plot_show=False)
-
-    plt.show()
-
-if __name__ == '__main__':
-    print(doping2plasmaFrequency(0.05,3.024434))
-    print(doping2plasmaFrequency(0.1,4.57655596))
-
-    myMain()
diff --git a/Python code/nice_fitting_code.py b/Python code/nice_fitting_code.py
index c52ca8e..cf5886b 100755
--- a/Python code/nice_fitting_code.py	
+++ b/Python code/nice_fitting_code.py	
@@ -2,7 +2,7 @@
 from os import truncate
 import matplotlib.pyplot as plt
 import numpy as np
-from libhreels import calcHREELS4 as ch4
+from libhreels import calcHREELS as ch
 from libhreels.HREELS import HREELS
 from copy import deepcopy
 import lmfit 
@@ -58,7 +58,7 @@ def lossFunction(x, **par):
     extended_stack = [[stack_with_2nd_drude,par['DrudeThickness']],[stack_without_drude,par['STOthickness']]]  #STO+Drude+drude
     
     #################### Calculate HREELS sepctra with Lambin-Code
-    film1 = ch4.lambin(film=extended_stack, setup=setup)
+    film1 = ch.lambin(film=extended_stack, setup=setup)
     film1.gauss = par['gauss'] 
     film1.width = par['width']         
     if FlagAsymSetOneMinusGauss==True:
-- 
GitLab