import subprocess
import re
import numpy as np
import csv
import time
from refractiveindex import RefractiveIndexMaterial as nMat
def adda_spectrum(shape="ellipsoid",
wavelength=500, #wavelength of the incoming light in nm
radius=20, #Radius of the particle in nm
nPart=1.5 + 0.2j, #RI of the particles
euler = (0, 0, 0), #euler angles
granulRI = 1.4 + 0.1j, #RI of the internal granules
nMedium=1.333, #RI of the medium
dpl=None, #number of dipoles
test=True, #if test, do not run command
verbose=True, #if verbose, print command
**kwargs):
if dpl is None:
dpl = int(np.ceil(min(50, 20 * abs(nPart)))) #automatic scaling of dpl in case no argument is given
cmd = (
fr"C:\Users\innoFSPEC\Desktop\Amsterdam_DDA\win64_executables\adda -shape {shape} " #TODO make independent of path and implement other shapes
f"-orient {euler[0]} {euler[1]} {euler[2]} "
f"-lambda {wavelength * 1e-3 / nMedium} "
f"-dpl {dpl} "
f"-size {2 * round(int(radius) * 1e-3, 5)} "
f"-m {np.real(nPart) / nMedium} {np.imag(nPart) / nMedium} {np.real(granulRI)/nMedium} {np.imag(granulRI)/nMedium} " #TODO: currently, granul is required or error occurs. make independent, make this row a variable and insert it as an f-string
)
# append additional kwargs
if kwargs:
extras = " ".join(f"-{k} {v}" for k, v in kwargs.items())
cmd += extras
if verbose:
print("Command:", cmd)
if test:
Cext = 0
Cabs = 0
Csca = 0
return Cext, Cabs, Csca, cmd
# run command
start_time = time.time()
result = subprocess.run(cmd, shell=True, capture_output=True, text=True) #automatically waits for loop to complete
end_time = time.time()
elapsed_time = end_time - start_time
print(f'Iteration done @ wavelength = {wavelength} nm. Time taken = {round(elapsed_time,1)}s ')
output = result.stdout.splitlines()
# extract numerical values
def extract_vals(keyword):
line = next((l for l in output if keyword in l), "")
nums = re.findall(r"[-+]?\d*\.\d+|\d+", line)
return list(map(float, nums))
Cext = extract_vals("Cext")
Cabs = extract_vals("Cabs")
Csca = [Cext[i] - Cabs[i] for i in range(len(Cext))]
return Cext[0], Cabs[0], Csca[0], cmd
# example usage
MedMat = nMat('main', 'H2O', 'Daimon-21.5C')
PartMat = nMat('main', 'SiO2', 'Arosa')
GranulMat = nMat('main', 'Ag', 'Ferrera-298K')
resultFile = open(fr'C:\Users\innoFSPEC\Desktop\Python programs\OutPut\output.csv', 'w')
writer = csv.writer(resultFile, delimiter='\t')
writer.writerow(['Wavelength /nm', 'Cext', 'Cabs', 'Csca'])
for wl in range(400, 1001, 10):
nMed = MedMat.get_refractive_index(wl)
nPart = PartMat.get_refractive_index(wl)
nGranulReal = GranulMat.get_refractive_index(wl)
nGranulIm = GranulMat.get_extinction_coefficient(wl)
TotalRi = f'{nPart} 0 {nGranulReal} {nGranulIm}'
Cext, Cabs, Csca, cmd = adda_spectrum(test=False, shape ="sphere", wavelength = wl, radius = 175, nPart = nPart, granulRI= complex(nGranulReal,nGranulIm), nMedium = nMed, dpl = 100, verbose = True, granul= '0.10 0.08', asym ='')
writer.writerow([wl, Cext, Cabs, Csca])
resultFile.close()