Coverage for yasfpy/functions/material_handler.py: 45%
88 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-15 20:36 +0100
« prev ^ index » next coverage.py v7.4.1, created at 2024-02-15 20:36 +0100
1import re
2import io
3import pandas as pd
4import yaml
6# import urllib.request
7from urllib.parse import unquote
8import requests as req
10import numpy as np
13def material_handler(links):
14 if not isinstance(links, list):
15 links = [links]
17 data = dict(ref_idx=pd.DataFrame(columns=["wavelength", "n", "k"]), material=None)
18 for link in links:
19 link = link.strip()
20 if link[:4] == "http":
21 if "refractiveindex.info" in link:
22 df, material = handle_refractiveindex_info(link)
23 data["ref_idx"] = pd.concat([data["ref_idx"], df])
24 data["material"] = material
25 elif "http://eodg.atm.ox.ac.uk" in link:
26 df, material = handle_eodg(link)
27 data["ref_idx"] = pd.concat([data["ref_idx"], df])
28 data["material"] = material
29 else:
30 print("No mathing handler found for url")
31 else:
32 if ".csv" in link:
33 df, material = handle_csv(link)
34 data["ref_idx"] = pd.concat([data["ref_idx"], df])
35 data["material"] = material
36 else:
37 print("No mathing handler found for file type")
38 # data['ref_idx'] = data['ref_idx'].sort_values(by=['wavelength'])
39 return data
42def handle_refractiveindex_info(url):
43 url_split = url.replace("=", "/").split("/")
44 material = unquote(url_split[-2])
46 if np.any([("data_csv" in part) or ("data_txt" in part) for part in url_split]):
47 print("Please use the [Full database record] option for refractiveindex.info!")
48 print("Reverting url:")
49 print(f" from: {url}")
50 url_split[3] = "database"
51 url = "/".join(url_split)
52 print(f" to: {url}")
54 # req = urllib.request.Request(url)
55 # with urllib.request.urlopen(req) as resp:
56 resp = req.get(url)
57 if resp.status_code >= 400:
58 raise Exception(f"Failed to retrieve data from {url}")
59 # data = resp.read()
60 # data = data.decode("utf-8")
61 data = resp.text
62 data_yml = yaml.safe_load(data)
63 header_yml = ["wavelength", "n", "k"]
64 data = pd.DataFrame(columns=["wavelength", "n", "k"])
65 for line in data_yml["DATA"]:
66 df = None
67 if "tabulated" in line["type"].lower():
68 # elif line['type'].lower()[-2:] == ' n':
69 # header_yml=['wavelength', 'n']
70 if line["type"].lower()[-2:] == " k":
71 header_yml = ["wavelength", "k", "n"]
72 df = pd.read_csv(
73 io.StringIO(line["data"]),
74 delim_whitespace=True,
75 header=None,
76 names=header_yml,
77 )
78 elif "formula" in line["type"].lower():
79 if line["type"].lower() == "formula 1":
80 wavelengths = [float(c) for c in line["wavelength_range"].split()]
81 wavelengths = np.arange(wavelengths[0], wavelengths[1], 0.1)
82 coefficients = np.array(
83 [float(c) for c in line["coefficients"].split()]
84 )
85 ref_idx = lambda x: np.sqrt(
86 1
87 + np.sum(
88 [
89 coefficients[i]
90 * x**2
91 / (x**2 - coefficients[i + 1] ** 2)
92 for i in range(1, len(coefficients), 2)
93 ],
94 axis=0,
95 )
96 )
97 df = pd.DataFrame(columns=["wavelength", "n", "k"])
98 df["wavelength"] = wavelengths
99 df["n"] = ref_idx(wavelengths)
101 if df is not None:
102 df = df.fillna(0)
103 data = pd.concat([data, df])
105 return data, material
108def handle_eodg(url):
109 url_split = url.split("/")
110 # material = unquote(url_split[-1][:-3]).replace('_', ' ')
111 material = unquote(url_split[6])
113 # req = urllib.request.Request(url)
114 # with urllib.request.urlopen(req) as resp:
115 # data = resp.read()
116 # data = data.decode("iso-8859-1")
117 resp = req.get(url)
118 if resp.status_code >= 400:
119 raise Exception(f"Failed to retrieve data from {url}")
120 data = resp.text
121 data_format = [
122 s.lower() for s in re.search(r"#FORMAT=(.*)\n", data).group(1).split()
123 ]
124 header_yml = ["wavelength", "n", "k"]
125 if "n" not in data_format:
126 header_yml = ["wavelength", "k", "n"]
128 data = re.sub(r"^#.*\n", "", data, flags=re.MULTILINE)
129 data = pd.read_csv(
130 io.StringIO(data), delim_whitespace=True, header=None, names=header_yml
131 )
132 data = data.fillna(0)
133 # eodg uses wavenumbers in cm-1 instead of wavelengths in um, hence um = 1e4 / cm-1
134 if "wavn" in data_format:
135 data["wavelength"] = 1e4 / data["wavelength"]
136 data = data.iloc[::-1]
138 return data, material
141def handle_csv(path):
142 name = re.split(r"\._-", path)
143 material = unquote(name[0])
144 data = pd.read_csv(
145 path, delim_whitespace=False, header=0, names=["wavelength", "n", "k"]
146 )
147 return data, material