diff --git a/data_analysis/mechanics.py b/data_analysis/mechanics.py
new file mode 100644
index 0000000000000000000000000000000000000000..b21495ab458f27138e87795e77712db31afe477d
--- /dev/null
+++ b/data_analysis/mechanics.py
@@ -0,0 +1,378 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Thu Apr  3 10:42:13 2025
+
+@author: nroisin
+"""
+import numpy as np
+    
+def stress_from_strain(strain_tensor,c11= 165.77,c12= 63.93,c44 = 79.62):
+    strain_voigt=np.zeros((1,6))
+    strain_shape=np.shape(strain_tensor)
+    
+    if len(strain_shape)==2:
+        if strain_shape[0]==3 and strain_shape[1]==3:
+            strain_voigt[0]=strain_tensor[0,0]
+            strain_voigt[1]=strain_tensor[1,1]
+            strain_voigt[2]=strain_tensor[2,2]
+            strain_voigt[3]=strain_tensor[1,2]
+            strain_voigt[4]=strain_tensor[0,2]
+            strain_voigt[5]=strain_tensor[0,1]
+        if strain_shape[0]==1 and strain_shape[1]==6:
+            strain_voigt=strain_tensor
+    else:
+        strain_voigt=np.array([strain_tensor])
+    
+    compliance_tensor=np.array([[c11,c12,c12,0,0,0],
+                                [c12,c11,c12,0,0,0],
+                                [c12,c12,c11,0,0,0],
+                                [0,0,0,c44,0,0],
+                                [0,0,0,0,c44,0],
+                                [0,0,0,0,0,c44]])
+    return compliance_tensor @ strain_tensor
+
+def strain_from_stress(stress_tensor,c11= 165.77,c12= 63.93,c44 = 79.62):
+    stress_voigt=np.zeros((1,6))
+    stress_shape=np.shape(stress_tensor)
+    
+    if len(stress_shape)==2:
+        if stress_shape[0]==3 and stress_shape[1]==3:
+            stress_voigt[0]=stress_tensor[0,0]
+            stress_voigt[1]=stress_tensor[1,1]
+            stress_voigt[2]=stress_tensor[2,2]
+            stress_voigt[3]=stress_tensor[1,2]
+            stress_voigt[4]=stress_tensor[0,2]
+            stress_voigt[5]=stress_tensor[0,1]
+        if stress_shape[0]==1 and stress_shape[1]==6:
+            stress_voigt=stress_tensor
+    else:
+        stress_voigt=np.array([stress_tensor])
+    
+    compliance_tensor=np.array([[c11,c12,c12,0,0,0],
+                                [c12,c11,c12,0,0,0],
+                                [c12,c12,c11,0,0,0],
+                                [0,0,0,c44,0,0],
+                                [0,0,0,0,c44,0],
+                                [0,0,0,0,0,c44]])
+    return np.linalg.inv(compliance_tensor) @ stress_tensor
+    
+def straintensor(direction,cristal_plane,N=11,emin=-0.05,emax=0.05,C11=165.77,C12=63.93,C44=79.62, poisson=True)   : 
+    # Constants
+    retour=np.zeros((3,3,N))
+    
+    eps=np.linspace(emin,emax,N)
+    
+    # Initiation
+    uniepsilon001=np.zeros((3,3,N))
+    uniepsilon110=np.zeros((3,3,N))
+    uniepsilon111=np.zeros((3,3,N))
+    biepsilon001=np.zeros((3,3,N))
+    biepsilon110=np.zeros((3,3,N))
+    biepsilon111=np.zeros((3,3,N))
+    shear001=np.zeros((3,3,N))
+    shear110=np.zeros((3,3,N))
+    shear111=np.zeros((3,3,N))
+    hydro=np.zeros((3,3,N))    
+    # Matrix computation
+    # Uniaxial
+    if poisson:
+      uniepar001=-C12/(C11+C12)*eps
+    else:
+      uniepar001=0
+    
+    uniepsilon001[0][0]=uniepar001
+    uniepsilon001[0][1]=np.zeros(N)
+    uniepsilon001[0][2]=np.zeros(N)
+    uniepsilon001[1][0]=np.zeros(N)
+    uniepsilon001[1][1]=uniepar001
+    uniepsilon001[1][2]=np.zeros(N)
+    uniepsilon001[2][0]=np.zeros(N)
+    uniepsilon001[2][1]=np.zeros(N)
+    uniepsilon001[2][2]=eps
+
+    if poisson:    
+      uniepar110=- ( 4*C12*C44 ) / ( 2*C11*C44+(C11+2*C12)*(C11-C12) )*eps 
+    else:
+      uniepar110=0
+    
+    uniepsilon110[0][0]=0.5*(eps+uniepar110)
+    uniepsilon110[0][1]=0.5*(eps-uniepar110)
+    uniepsilon110[0][2]=np.zeros(N)
+    uniepsilon110[1][0]=0.5*(eps-uniepar110)
+    uniepsilon110[1][1]=0.5*(eps+uniepar110)
+    uniepsilon110[1][2]=np.zeros(N)
+    uniepsilon110[2][0]=np.zeros(N)
+    uniepsilon110[2][1]=np.zeros(N)
+    uniepsilon110[2][2]=uniepar110
+
+    if poisson:     
+      uniepar111 = - (C11 + 2*C12 - 2*C44) / (C11 + 2*C12 + 2*C44)*eps
+    else:
+      uniepar111 = 0
+      
+    uniepsilon111[0][0] = (eps + 2*uniepar111) / 3
+    uniepsilon111[0][1] = (eps - uniepar111) / 3
+    uniepsilon111[0][2] = (eps - uniepar111) / 3
+    uniepsilon111[1][0] = (eps - uniepar111) / 3
+    uniepsilon111[1][1] = (eps + 2*uniepar111) / 3
+    uniepsilon111[1][2] = (eps - uniepar111) / 3
+    uniepsilon111[2][0] = (eps - uniepar111) / 3
+    uniepsilon111[2][1] = (eps - uniepar111) / 3
+    uniepsilon111[2][2] = (eps + 2*uniepar111) / 3
+    
+    # Biaxial
+    if poisson:
+      bieper001 = -2 * C12 / C11 * eps        
+    else:
+      bieper001=0
+          
+    biepsilon001[0][0] = eps
+    biepsilon001[0][1] = np.zeros(N)
+    biepsilon001[0][2] = np.zeros(N)
+    biepsilon001[1][0] = np.zeros(N)
+    biepsilon001[1][1] = eps
+    biepsilon001[1][2] = np.zeros(N)
+    biepsilon001[2][0] = np.zeros(N)
+    biepsilon001[2][1] = np.zeros(N)
+    biepsilon001[2][2] = bieper001
+
+    if poisson:     
+      bieper110 = -(C11+3*C12-2*C44)/(C11+C12+2*C44)*eps
+    else:
+      bieper110 = 0
+    
+    biepsilon110[0][0] = 0.5*(bieper110+eps)
+    biepsilon110[0][1] = 0.5*(bieper110-eps)
+    biepsilon110[0][2] = np.zeros(N)
+    biepsilon110[1][2] = np.zeros(N)
+    biepsilon110[1][1] = 0.5*(bieper110+eps)
+    biepsilon110[1][0] = 0.5*(bieper110-eps)
+    biepsilon110[2][0] = np.zeros(N)
+    biepsilon110[2][1] = np.zeros(N)
+    biepsilon110[2][2] = eps
+    
+    if poisson:     
+      bieper111 = -2*(C11+2*C12-2*C44)/(C11+2*C12+4*C44)* eps
+    else:
+      bieper111=0
+    biepsilon111[0][0] = (bieper111+2*eps)/3 
+    biepsilon111[0][1] = (bieper111-eps)/3 
+    biepsilon111[0][2] = (bieper111-eps)/3 
+    biepsilon111[1][0] = (bieper111-eps)/3 
+    biepsilon111[1][1] = (bieper111+2*eps)/3 
+    biepsilon111[1][2] = (bieper111-eps)/3 
+    biepsilon111[2][0] = (bieper111-eps)/3 
+    biepsilon111[2][1] = (bieper111-eps)/3 
+    biepsilon111[2][2] = (bieper111+2*eps)/3
+
+    # Shear
+
+    shear001[0][2] = eps
+    shear001[2][0] = eps
+
+    shear110[0][2] = eps/np.sqrt(2)
+    shear110[2][0] = eps/np.sqrt(2)
+    shear110[1][2] = eps/np.sqrt(2)
+    shear110[2][2] = eps/np.sqrt(2)
+
+    shear111[0][1] = eps/np.sqrt(3)
+    shear111[0][2] = eps/np.sqrt(3)
+    shear111[1][0] = eps/np.sqrt(3)
+    shear111[1][2] = eps/np.sqrt(3)
+    shear111[2][0] = eps/np.sqrt(3)
+    shear111[2][1] = eps/np.sqrt(3)
+
+    # hydro
+
+    hydro[0][0] = eps/3
+    hydro[1][1] = eps/3
+    hydro[2][2] = eps/3
+    if direction == "uniaxial":
+        if cristal_plane == "001":
+            retour=uniepsilon001
+        elif cristal_plane == "110":
+            retour=uniepsilon110         
+        elif cristal_plane == "111":
+            retour=uniepsilon111      
+    elif direction == "biaxial":
+        if cristal_plane == "001":
+            retour=biepsilon001
+        elif cristal_plane == "110":
+            retour=biepsilon110         
+        elif cristal_plane == "111":
+            retour=biepsilon111
+    elif direction == "shear":
+        if cristal_plane == "001":
+            retour=shear001
+        elif cristal_plane == "110":
+            retour=shear110         
+        elif cristal_plane == "111":
+            retour=shear111
+    elif direction =="hydro" :
+            retour = hydro
+      
+            
+    return retour
+    
+def straintensor_scalar(direction,cristal_plane,eps=0,C11=16.577,C12=6.393,C44=7.962,poisson=True)   : 
+    # Constants
+    retour=np.zeros((3,3))
+    
+    
+    # Initiation
+    uniepsilon001=np.zeros((3,3))
+    uniepsilon110=np.zeros((3,3))
+    uniepsilon111=np.zeros((3,3))
+    biepsilon001=np.zeros((3,3))
+    biepsilon110=np.zeros((3,3))
+    biepsilon111=np.zeros((3,3))
+    shear001=np.zeros((3,3))
+    shear110=np.zeros((3,3))
+    shear111=np.zeros((3,3))
+    hydro=np.zeros((3,3))    
+    # Matrix computation
+    # Uniaxial
+    if poisson:
+      uniepar001=-C12/(C11+C12)*eps
+    else:
+      uniepar001=0
+      
+    uniepsilon001[0][0]=uniepar001
+    uniepsilon001[0][1]=0
+    uniepsilon001[0][2]=0
+    uniepsilon001[1][0]=0
+    uniepsilon001[1][1]=uniepar001
+    uniepsilon001[1][2]=0
+    uniepsilon001[2][0]=0
+    uniepsilon001[2][1]=0
+    uniepsilon001[2][2]=eps
+
+    if poisson:
+      uniepar110=- ( 4*C12*C44 ) / ( 2*C11*C44+(C11+2*C12)*(C11-C12) )*eps 
+    else:
+      uniepar110=0
+          
+
+    uniepsilon110[0][0]=0.5*(eps+uniepar110)
+    uniepsilon110[0][1]=0.5*(eps-uniepar110)
+    uniepsilon110[0][2]=0
+    uniepsilon110[1][0]=0.5*(eps-uniepar110)
+    uniepsilon110[1][1]=0.5*(eps+uniepar110)
+    uniepsilon110[1][2]=0
+    uniepsilon110[2][0]=0
+    uniepsilon110[2][1]=0
+    uniepsilon110[2][2]=uniepar110
+    
+    if poisson:
+      uniepar111 = - (C11 + 2*C12 - 2*C44) / (C11 + 2*C12 + 2*C44)*eps 
+    else:
+      uniepar111=0    
+
+    uniepsilon111[0][0] = (eps + 2*uniepar111) / 3
+    uniepsilon111[0][1] = (eps - uniepar111) / 3
+    uniepsilon111[0][2] = (eps - uniepar111) / 3
+    uniepsilon111[1][0] = (eps - uniepar111) / 3
+    uniepsilon111[1][1] = (eps + 2*uniepar111) / 3
+    uniepsilon111[1][2] = (eps - uniepar111) / 3
+    uniepsilon111[2][0] = (eps - uniepar111) / 3
+    uniepsilon111[2][1] = (eps - uniepar111) / 3
+    uniepsilon111[2][2] = (eps + 2*uniepar111) / 3
+    
+    # Biaxial
+    if poisson:
+      bieper001 = -2 * C12 / C11 * eps
+    else:
+      bieper001=0      
+    
+    
+
+    biepsilon001[0][0] = eps
+    biepsilon001[0][1] = 0
+    biepsilon001[0][2] = 0
+    biepsilon001[1][0] = 0
+    biepsilon001[1][1] = eps
+    biepsilon001[1][2] = 0
+    biepsilon001[2][0] = 0
+    biepsilon001[2][1] = 0
+    biepsilon001[2][2] = bieper001
+    
+    if poisson:
+      bieper110 = -(C11+3*C12-2*C44)/(C11+C12+2*C44)*eps
+    else:
+      bieper110=0      
+        
+    
+    biepsilon110[0][0] = 0.5*(bieper110+eps)
+    biepsilon110[0][1] = 0.5*(bieper110-eps)
+    biepsilon110[0][2] = 0
+    biepsilon110[1][2] = 0
+    biepsilon110[1][1] = 0.5*(bieper110+eps)
+    biepsilon110[1][0] = 0.5*(bieper110-eps)
+    biepsilon110[2][0] = 0
+    biepsilon110[2][1] = 0
+    biepsilon110[2][2] = eps
+
+    if poisson:
+      bieper111 = -2*(C11+2*C12-2*C44)/(C11+2*C12+4*C44)* eps
+    else:
+      bieper111=0     
+          
+    
+    biepsilon111[0][0] = (bieper111+2*eps)/3 
+    biepsilon111[0][1] = (bieper111-eps)/3 
+    biepsilon111[0][2] = (bieper111-eps)/3 
+    biepsilon111[1][0] = (bieper111-eps)/3 
+    biepsilon111[1][1] = (bieper111+2*eps)/3 
+    biepsilon111[1][2] = (bieper111-eps)/3 
+    biepsilon111[2][0] = (bieper111-eps)/3 
+    biepsilon111[2][1] = (bieper111-eps)/3 
+    biepsilon111[2][2] = (bieper111+2*eps)/3
+
+    # Shear
+
+    shear001[0][2] = eps
+    shear001[2][0] = eps
+
+    shear110[0][2] = eps/np.sqrt(2)
+    shear110[2][0] = eps/np.sqrt(2)
+    shear110[1][2] = eps/np.sqrt(2)
+    shear110[2][2] = eps/np.sqrt(2)
+
+    shear111[0][1] = eps/np.sqrt(3)
+    shear111[0][2] = eps/np.sqrt(3)
+    shear111[1][0] = eps/np.sqrt(3)
+    shear111[1][2] = eps/np.sqrt(3)
+    shear111[2][0] = eps/np.sqrt(3)
+    shear111[2][1] = eps/np.sqrt(3)
+
+    # hydro
+
+    hydro[0][0] = eps/3
+    hydro[1][1] = eps/3
+    hydro[2][2] = eps/3
+    if direction == "uni":
+        if cristal_plane == "001":
+            retour=uniepsilon001
+        elif cristal_plane == "110":
+            retour=uniepsilon110         
+        elif cristal_plane == "111":
+            retour=uniepsilon111      
+    elif direction == "bi":
+        if cristal_plane == "001":
+            retour=biepsilon001
+        elif cristal_plane == "110":
+            retour=biepsilon110         
+        elif cristal_plane == "111":
+            retour=biepsilon111
+    elif direction == "shear":
+        if cristal_plane == "001":
+            retour=shear001
+        elif cristal_plane == "110":
+            retour=shear110         
+        elif cristal_plane == "111":
+            retour=shear111
+    elif direction =="hydro" :
+            retour = hydro
+      
+            
+    return retour
\ No newline at end of file
diff --git a/data_analysis/raman.py b/data_analysis/raman.py
index aca71de80535f88590fba2c28a8b097d8ce396bb..6dfa8e4871fd1470b370b30a2ff328f7eb977a0e 100644
--- a/data_analysis/raman.py
+++ b/data_analysis/raman.py
@@ -95,6 +95,7 @@ def plot_with_peaks(x,y,ax=None,height=None, threshold=None, distance=None, widt
         ax.text(position[i],1.2*height[i],"%.2f cm$^{-1}$"%position[i],ha="center",va="bottom",rotation="vertical")
     if ax==None:
         return fig, ax
+    
 def plot_from_file(file_path,ax=None,with_peaks=False,height=None, threshold=None, distance=None, width=None,*ax_kwargs,**plot_kwargs):
     """ Function to plot the Raman spectrum with the peaks indicated
     
diff --git a/data_analysis/semiconductor.py b/data_analysis/semiconductor.py
index db73e45d37f389e7ba1b933e2c30cf939f25deda..0df22c543303f8feb176f56ec95b84a5a6cb6f0d 100644
--- a/data_analysis/semiconductor.py
+++ b/data_analysis/semiconductor.py
@@ -1,9 +1,44 @@
 import numpy as np
 import matplotlib.pyplot as plt
 
-def mobility_extraction:
+def mos_parameter_extraction:
+    # linear fit
     
-def transistor_current:
+def threshold_voltage_extraction:
     
-def mobility_strain_silicon(strain_tensor, pi11, pi12, pi44):
+def bjt_transistor_current:
+
+def mos_transistor_current:
+    
+def diode_current:
+    
+def schottky_current:
+    
+def photodiode_current:
+    
+def piezoresitivity_semiconductor(stress_tensor, pi11, pi12, pi44):
+    stress_voigt=np.zeros((1,6))
+    stress_shape=np.shape(stress_tensor)
+    
+    if len(stress_shape)==2:
+        if stress_shape[0]==3 and stress_shape[1]==3:
+            stress_voigt[0]=stress_tensor[0,0]
+            stress_voigt[1]=stress_tensor[1,1]
+            stress_voigt[2]=stress_tensor[2,2]
+            stress_voigt[3]=stress_tensor[1,2]
+            stress_voigt[4]=stress_tensor[0,2]
+            stress_voigt[5]=stress_tensor[0,1]
+        if stress_shape[0]==1 and stress_shape[1]==6:
+            stress_voigt=stress_tensor
+    else:
+        stress_voigt=np.array([stress_tensor])
+    
+    piezo_tensor=np.array([[pi11,pi12,pi12,0,0,0],
+                                [pi12,pi11,pi12,0,0,0],
+                                [pi12,pi12,pi11,0,0,0],
+                                [0,0,0,pi44,0,0],
+                                [0,0,0,0,pi44,0],
+                                [0,0,0,0,0,pi44]])
+    
+    return piezo_tensor @ stress_tensor
     
\ No newline at end of file