praiteri commited on
Commit
79484be
·
1 Parent(s): 5cc02e3

tweaks and fixed student ID

Browse files
pyproject.toml CHANGED
@@ -18,7 +18,7 @@ readme = {file = "README.md", content-type = "text/markdown"}
18
  dependencies = [
19
  "numpy",
20
  "scipy",
21
- "lmfit",
22
  "matplotlib",
23
  ]
24
 
 
18
  dependencies = [
19
  "numpy",
20
  "scipy",
21
+ "colorama",
22
  "matplotlib",
23
  ]
24
 
src/pycek_public/bomb_calorimetry.py CHANGED
@@ -18,6 +18,7 @@ class bomb_calorimetry(cek.cek_labs):
18
  self.relaxation_time = 3
19
  self.number_of_values = 100
20
  self.noise_level = 0.1
 
21
 
22
  self.slope_before = np.random.uniform(0., self.noise_level) / 3
23
  self.slope_after = np.random.uniform(0., self.noise_level) / 3
@@ -97,6 +98,8 @@ class bomb_calorimetry(cek.cek_labs):
97
  x = np.linspace(0, self.number_of_values, self.number_of_values)
98
  y = np.random.normal(0, self.noise_level, self.number_of_values)
99
 
 
 
100
  dd = 0.
101
  T = self.temperature
102
  for i in range(self.number_of_values):
@@ -107,6 +110,7 @@ class bomb_calorimetry(cek.cek_labs):
107
  dd = deltaT * (1 - np.exp( - (i - self.ignition_time) / self.relaxation_time) )
108
  y[i] += T + dd
109
 
 
110
  self.data = np.column_stack((x,y))
111
 
112
  return
 
18
  self.relaxation_time = 3
19
  self.number_of_values = 100
20
  self.noise_level = 0.1
21
+ self.precision = 2
22
 
23
  self.slope_before = np.random.uniform(0., self.noise_level) / 3
24
  self.slope_after = np.random.uniform(0., self.noise_level) / 3
 
98
  x = np.linspace(0, self.number_of_values, self.number_of_values)
99
  y = np.random.normal(0, self.noise_level, self.number_of_values)
100
 
101
+ x = self._round_values(x,precision=0)
102
+
103
  dd = 0.
104
  T = self.temperature
105
  for i in range(self.number_of_values):
 
110
  dd = deltaT * (1 - np.exp( - (i - self.ignition_time) / self.relaxation_time) )
111
  y[i] += T + dd
112
 
113
+ y = self._round_values(y)
114
  self.data = np.column_stack((x,y))
115
 
116
  return
src/pycek_public/cek_labs.py CHANGED
@@ -19,7 +19,7 @@ class cek_labs(ABC):
19
  self.NA = 6.022e23
20
  self.temperature = 298
21
 
22
- self.number_of_values = 100
23
  self.output_file = None
24
  self.filename_gen = cek.TempFilenameGenerator()
25
 
@@ -29,6 +29,7 @@ class cek_labs(ABC):
29
  'output_file' : self.output_file,
30
  })
31
 
 
32
  self.logger_level = "ERROR"
33
 
34
  # Define some lab specific parameters
@@ -50,6 +51,8 @@ class cek_labs(ABC):
50
  # Lab specific parameters
51
  self.setup_lab()
52
 
 
 
53
  def __str__(self):
54
  return f'CHEM2000 Lab: {self.__class__.__name__}'
55
 
@@ -57,6 +60,7 @@ class cek_labs(ABC):
57
  if isinstance(student_ID,int):
58
  self.student_ID = student_ID
59
  elif isinstance(student_ID,str):
 
60
  if student_ID.isdigit():
61
  self.student_ID = int(student_ID)
62
  else:
@@ -65,7 +69,7 @@ class cek_labs(ABC):
65
  raise ValueError("student_ID must be an integer")
66
  np.random.seed(self.student_ID)
67
  self.update_metadata_from_attr()
68
- self.logger.debug(f"Initial seed = {np.random.get_state()[1][0]}")
69
 
70
  def set_token(self, token):
71
  self.token = token
@@ -181,6 +185,8 @@ class cek_labs(ABC):
181
  # Write the kwargs as metadata
182
  self.write_metadata(filename)
183
 
 
 
184
  return filename
185
 
186
  def read_data_file(self,filename=None):
@@ -226,17 +232,36 @@ class cek_labs(ABC):
226
  key = key.replace("#","").strip()
227
  metadata[key.strip()] = value.strip()
228
 
 
 
 
 
229
  # Output results
230
  # print("Comments:")
231
  # print("\n".join(comments))
232
  # print("\nExtracted Data:")
233
  # print(data_array)
234
  return data_array, header, metadata
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
- def process_file(self, filename=None):
237
- self.read_data(filename)
238
- result = self.process_data()
239
- return result
240
 
241
  def _valid_ID(self,ID):
242
  if ID in ["23745411"]:
@@ -355,7 +380,8 @@ class cek_labs(ABC):
355
  y += self._generate_noise(nvalues,noise_level)
356
 
357
  if positive:
358
- y = np.abs(y)
 
359
 
360
  # Note: weights parameter is currently unused
361
  if weights is not None:
 
19
  self.NA = 6.022e23
20
  self.temperature = 298
21
 
22
+ self.number_of_values = 10
23
  self.output_file = None
24
  self.filename_gen = cek.TempFilenameGenerator()
25
 
 
29
  'output_file' : self.output_file,
30
  })
31
 
32
+ self.make_plots = False
33
  self.logger_level = "ERROR"
34
 
35
  # Define some lab specific parameters
 
51
  # Lab specific parameters
52
  self.setup_lab()
53
 
54
+ self.list_of_data_files = []
55
+
56
  def __str__(self):
57
  return f'CHEM2000 Lab: {self.__class__.__name__}'
58
 
 
60
  if isinstance(student_ID,int):
61
  self.student_ID = student_ID
62
  elif isinstance(student_ID,str):
63
+ student_ID = student_ID.strip()
64
  if student_ID.isdigit():
65
  self.student_ID = int(student_ID)
66
  else:
 
69
  raise ValueError("student_ID must be an integer")
70
  np.random.seed(self.student_ID)
71
  self.update_metadata_from_attr()
72
+ self.logger.critical(f"Initial seed = {np.random.get_state()[1][0]}")
73
 
74
  def set_token(self, token):
75
  self.token = token
 
185
  # Write the kwargs as metadata
186
  self.write_metadata(filename)
187
 
188
+ self.list_of_data_files.append( filename )
189
+
190
  return filename
191
 
192
  def read_data_file(self,filename=None):
 
232
  key = key.replace("#","").strip()
233
  metadata[key.strip()] = value.strip()
234
 
235
+ self.logger.debug("-"*50)
236
+ for k,v in metadata.items():
237
+ self.logger.debug(f"{k} = {v}")
238
+ self.logger.debug("-"*50)
239
  # Output results
240
  # print("Comments:")
241
  # print("\n".join(comments))
242
  # print("\nExtracted Data:")
243
  # print(data_array)
244
  return data_array, header, metadata
245
+
246
+ def _cleanup(self, pattern=None):
247
+ from pathlib import Path
248
+ for ff in self.list_of_data_files:
249
+ # Check if file exists before deleting
250
+ file_path = Path(ff)
251
+ if file_path.exists():
252
+ file_path.unlink()
253
+ else:
254
+ print("The file does not exist")
255
+
256
+ # Delete multiple files using a pattern
257
+ if pattern is not None:
258
+ for file_path in Path('.').glob(pattern):
259
+ file_path.unlink()
260
 
261
+ # def process_file(self, filename=None):
262
+ # self.read_data(filename)
263
+ # result = self.process_data()
264
+ # return result
265
 
266
  def _valid_ID(self,ID):
267
  if ID in ["23745411"]:
 
380
  y += self._generate_noise(nvalues,noise_level)
381
 
382
  if positive:
383
+ eps = np.power(10.,-self.precision)
384
+ y = [ max(eps,np.abs(x)) for x in y ]
385
 
386
  # Note: weights parameter is currently unused
387
  if weights is not None:
src/pycek_public/crystal_violet.py CHANGED
@@ -16,7 +16,8 @@ class crystal_violet(cek.cek_labs):
16
  self.expt_time = 1000
17
  self.number_of_values = 501
18
  self.noise_level = 0.1
19
- self.precision = 4
 
20
 
21
  self.activation_energy = 63e3 # J/mol
22
  self.prefactor = 5.9e9 # 1/M/s
@@ -68,7 +69,7 @@ class crystal_violet(cek.cek_labs):
68
  xspacing = 'linear',
69
  noise_level = self.noise_level,
70
  positive = True,
71
- background = 0.1
72
  )
73
 
74
  return
 
16
  self.expt_time = 1000
17
  self.number_of_values = 501
18
  self.noise_level = 0.1
19
+ self.precision = 6
20
+ self.background = 0.01
21
 
22
  self.activation_energy = 63e3 # J/mol
23
  self.prefactor = 5.9e9 # 1/M/s
 
69
  xspacing = 'linear',
70
  noise_level = self.noise_level,
71
  positive = True,
72
+ background = self.background,
73
  )
74
 
75
  return
src/pycek_public/plotting.py CHANGED
@@ -27,8 +27,21 @@ class plotting():
27
  line = [line]
28
 
29
  # Plot the observed data points as a scatter plot
 
30
  for ds in scatter:
31
- plt.scatter(ds[:,0],ds[:,1], color='blue', label='Data')
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
  # Add labels and title to the plot
34
  plt.xlabel(columns[0])
 
27
  line = [line]
28
 
29
  # Plot the observed data points as a scatter plot
30
+ idx = 0
31
  for ds in scatter:
32
+ if ds is not None:
33
+ plt.scatter(ds[:,0],ds[:,1],label="Data "+str(idx)),
34
+ idx += 1
35
+ # ymin = np.min(ds[:,1] - 0.1*np.abs(np.min(ds[:,1])))
36
+ # ymax = np.max(ds[:,1] + 0.1*np.abs(np.max(ds[:,1])))
37
+
38
+ # ax = plt.gca()
39
+ # ax.set_ylim([ymin, ymax])
40
+
41
+ for ds in line:
42
+ if ds is not None:
43
+ plt.plot(ds[:,0],ds[:,1],color='red',label="Data "+str(idx)),
44
+ idx += 1
45
 
46
  # Add labels and title to the plot
47
  plt.xlabel(columns[0])
src/pycek_public/statistics_lab.py CHANGED
@@ -11,6 +11,8 @@ class stats_lab(cek.cek_labs):
11
  columns = ["X","Y"]
12
  )
13
 
 
 
14
  self.available_samples = [
15
  'Averages',
16
  'Propagation of uncertainty',
@@ -25,7 +27,8 @@ class stats_lab(cek.cek_labs):
25
  (1.0, 0.1),
26
  (12., 2.0)
27
  ],
28
- 'exp_values' : (1.0,9.0),
 
29
  }
30
 
31
  self.sample_parameters['Propagation of uncertainty'] = {
@@ -33,6 +36,7 @@ class stats_lab(cek.cek_labs):
33
  (15.0, 1.0),
34
  (133., 2.0)
35
  ],
 
36
  }
37
 
38
  self.sample_parameters['Comparison of averages'] = {
@@ -40,19 +44,23 @@ class stats_lab(cek.cek_labs):
40
  (15.0, 1.0),
41
  (13.2, 2.0)
42
  ],
 
43
  }
44
 
45
  self.sample_parameters['Linear fit'] = {
46
  "function" : lambda x,m,q: m*x + q,
47
  "gen_values" : {'m':12.3 , 'q':1.0},
48
- "xrange" : [0.0 , 10.0]
 
 
49
  }
50
 
51
  self.sample_parameters['Non linear fit'] = {
52
  "nval" : 10,
53
  "function" : lambda x,E0,K0,Kp,V0: E0 + K0 * x / Kp * ( (V0/x)**Kp / (Kp-1)+1) - K0*V0/(Kp-1),
54
  "gen_values" : {"E0":-634.2, "K0":12.43, "Kp":4.28, "V0":99.11},
55
- "xrange" : [50 , 140]
 
56
  }
57
 
58
  self.sample_parameters['Detection of outliers'] = {
@@ -60,6 +68,7 @@ class stats_lab(cek.cek_labs):
60
  "gen_values" : {'m':2.3 , 'q':0.1},
61
  "xrange" : [10.0 , 20.0],
62
  "shift" : 2,
 
63
  }
64
 
65
  def create_data(self):
@@ -75,6 +84,9 @@ class stats_lab(cek.cek_labs):
75
  number_of_values = self.number_of_values,
76
  )
77
 
 
 
 
78
  if "noise" in prm:
79
  self.set_parameters( noise_level = prm["noise"] )
80
 
@@ -87,6 +99,8 @@ class stats_lab(cek.cek_labs):
87
  data = self._generate_normal_random(self.number_of_values, prm['gen_values'])
88
 
89
  elif self.sample in ["Linear fit"]:
 
 
90
  data = self.generate_data_from_function(
91
  prm["function"],
92
  prm['gen_values'],
@@ -96,6 +110,8 @@ class stats_lab(cek.cek_labs):
96
  )
97
 
98
  elif self.sample in ["Non linear fit"]:
 
 
99
  data = self.generate_data_from_function(
100
  prm["function"],
101
  prm['gen_values'],
@@ -115,7 +131,6 @@ class stats_lab(cek.cek_labs):
115
  i = np.random.randint(self.number_of_values)
116
  data[i,1] += prm['shift']
117
 
118
-
119
  self.data = data
120
  return data
121
 
 
11
  columns = ["X","Y"]
12
  )
13
 
14
+ self.number_of_values = 10
15
+
16
  self.available_samples = [
17
  'Averages',
18
  'Propagation of uncertainty',
 
27
  (1.0, 0.1),
28
  (12., 2.0)
29
  ],
30
+ 'exp_values' : (1.0,10.0),
31
+ "precision" : 3,
32
  }
33
 
34
  self.sample_parameters['Propagation of uncertainty'] = {
 
36
  (15.0, 1.0),
37
  (133., 2.0)
38
  ],
39
+ "precision" : 3,
40
  }
41
 
42
  self.sample_parameters['Comparison of averages'] = {
 
44
  (15.0, 1.0),
45
  (13.2, 2.0)
46
  ],
47
+ "precision" : 3,
48
  }
49
 
50
  self.sample_parameters['Linear fit'] = {
51
  "function" : lambda x,m,q: m*x + q,
52
  "gen_values" : {'m':12.3 , 'q':1.0},
53
+ "xrange" : [0.0 , 10.0],
54
+ "exp_values" : 11.3,
55
+ "precision" : 3,
56
  }
57
 
58
  self.sample_parameters['Non linear fit'] = {
59
  "nval" : 10,
60
  "function" : lambda x,E0,K0,Kp,V0: E0 + K0 * x / Kp * ( (V0/x)**Kp / (Kp-1)+1) - K0*V0/(Kp-1),
61
  "gen_values" : {"E0":-634.2, "K0":12.43, "Kp":4.28, "V0":99.11},
62
+ "xrange" : [50 , 140],
63
+ "precision" : 3,
64
  }
65
 
66
  self.sample_parameters['Detection of outliers'] = {
 
68
  "gen_values" : {'m':2.3 , 'q':0.1},
69
  "xrange" : [10.0 , 20.0],
70
  "shift" : 2,
71
+ "precision" : 3,
72
  }
73
 
74
  def create_data(self):
 
84
  number_of_values = self.number_of_values,
85
  )
86
 
87
+ if "precision" in prm:
88
+ self.set_parameters( precision = prm["precision"] )
89
+
90
  if "noise" in prm:
91
  self.set_parameters( noise_level = prm["noise"] )
92
 
 
99
  data = self._generate_normal_random(self.number_of_values, prm['gen_values'])
100
 
101
  elif self.sample in ["Linear fit"]:
102
+ self.noise_level = 5
103
+
104
  data = self.generate_data_from_function(
105
  prm["function"],
106
  prm['gen_values'],
 
110
  )
111
 
112
  elif self.sample in ["Non linear fit"]:
113
+ self.noise_level = 5
114
+
115
  data = self.generate_data_from_function(
116
  prm["function"],
117
  prm['gen_values'],
 
131
  i = np.random.randint(self.number_of_values)
132
  data[i,1] += prm['shift']
133
 
 
134
  self.data = data
135
  return data
136
 
src/pycek_public/surface_adsorption.py CHANGED
@@ -25,7 +25,7 @@ class surface_adsorption(cek.cek_labs):
25
  }
26
 
27
  self.number_of_values = 100
28
- self.noise_level = 1e-6
29
  self.precision = 10
30
 
31
  def create_data(self):
@@ -38,7 +38,7 @@ class surface_adsorption(cek.cek_labs):
38
  )
39
 
40
  self.add_metadata(**{
41
- "Temperature (K)" : self.temperature,
42
  "Volume (L)" : self.volume,
43
  "Molar mass (g/mol)" : self.sample_parameters["molarMass"],
44
  "MinDye (mg)" : self.minDye,
@@ -65,19 +65,6 @@ class surface_adsorption(cek.cek_labs):
65
  )
66
 
67
  self.data[:,0] *= conversion_factor
68
- # grams of dye added
69
- # x = np.linspace(self.minDye, self.maxDye, self.number_of_values) / 1000
70
- # moles = x / self.params["molarMass"] # g
71
- # initial_concentration = moles / self.volume # mol/L
72
- # y = self.measure(K, self.params["Q"], initial_concentration)
73
-
74
- # # Because noise is added to the concentration in solution, but
75
- # # the concentration on the surface is required in post-processing, which
76
- # # is very small, we divide by 1000
77
-
78
- # y = cek.add_noise(y, self.uncertainty/1000)
79
-
80
- # data_array = np.column_stack((x, y))
81
 
82
  return self.data
83
 
 
25
  }
26
 
27
  self.number_of_values = 100
28
+ self.noise_level = 0.5e-5
29
  self.precision = 10
30
 
31
  def create_data(self):
 
38
  )
39
 
40
  self.add_metadata(**{
41
+ "Temperature (C)" : self.temperature - 273.15,
42
  "Volume (L)" : self.volume,
43
  "Molar mass (g/mol)" : self.sample_parameters["molarMass"],
44
  "MinDye (mg)" : self.minDye,
 
65
  )
66
 
67
  self.data[:,0] *= conversion_factor
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  return self.data
70