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

1import re 

2import io 

3import pandas as pd 

4import yaml 

5 

6# import urllib.request 

7from urllib.parse import unquote 

8import requests as req 

9 

10import numpy as np 

11 

12 

13def material_handler(links): 

14 if not isinstance(links, list): 

15 links = [links] 

16 

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 

40 

41 

42def handle_refractiveindex_info(url): 

43 url_split = url.replace("=", "/").split("/") 

44 material = unquote(url_split[-2]) 

45 

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}") 

53 

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) 

100 

101 if df is not None: 

102 df = df.fillna(0) 

103 data = pd.concat([data, df]) 

104 

105 return data, material 

106 

107 

108def handle_eodg(url): 

109 url_split = url.split("/") 

110 # material = unquote(url_split[-1][:-3]).replace('_', ' ') 

111 material = unquote(url_split[6]) 

112 

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"] 

127 

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] 

137 

138 return data, material 

139 

140 

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