77import configparser as ConfigParser
88import pathlib
99import inspect
10+ from importlib import import_module
1011
1112import numpy as np
1213from Stoner import Data
@@ -29,7 +30,7 @@ def load_config(self):
2930 f"Could not find the fitting ini file { inifile } !"
3031 )
3132
32- tmp = cfg_data_from_ini (inifile , filename = False )
33+ tmp = cfg_data_from_ini (inifile )
3334 self .setas = tmp .setas .clone
3435 self .column_headers = tmp .column_headers
3536 self .metadata = tmp .metadata
@@ -77,7 +78,22 @@ def RescaleV(self):
7778 vscale = self .config .getfloat ("Data" , "v_scale" )
7879 self .data [:, self .vcol ] *= vscale
7980 print (f"Rescaled voltage data by { vscale } " )
80- return self
81+ return self
82+
83+ def Preprocess (self ):
84+ """Run an arbitart function over the data if the option is specified."""
85+ preprocessor_name = self .config .get (
86+ "Options" , "preprocessor" , fallback = "_pass"
87+ )
88+ if "." in preprocessor_name :
89+ module = "." .join (preprocessor_name .split ("." )[:- 1 ])
90+ preprocessor = preprocessor_name .split ("." )[- 1 ]
91+ module = import_module (module )
92+ preprocessor = getattr (module , preprocessor )
93+ else :
94+ preprocessor = globals ()[preprocessor_name ]
95+
96+ return preprocessor (self )
8197
8298 def Normalise (self ):
8399 """Normalise the data if the relevant options are turned on in the config file.
@@ -92,24 +108,39 @@ def Normalise(self):
92108 if self .config .has_option (
93109 "Options" , "fancy_normaliser"
94110 ) and self .config .getboolean ("Options" , "fancy_normaliser" ):
111+ fraction = 1 - self .config .getfloat (
112+ "Data" , "background_fraction" , fallback = 0.1
113+ )
114+ normaliser_name = self .config .get (
115+ "Options" , "normaliser_function" , fallback = "quadratic"
116+ )
117+ if "." in normaliser_name :
118+ module = "." .join (normaliser_name .split ("." )[:- 1 ])
119+ normaliser = normaliser_name .split ("." )[- 1 ]
120+ module = import_module (module )
121+ normaliser = getattr (module , normaliser )
122+ else :
123+ normaliser = globals ()[normaliser_name ]
95124 vmax , _ = self .max (self .vcol )
96125 vmin , _ = self .min (self .vcol )
97126 p , pv = self .curve_fit (
98- quadratic ,
99- bounds = lambda x , y : (x > 0.9 * vmax ) or (x < 0.9 * vmin ),
127+ normaliser ,
128+ bounds = lambda x , y : (x > fraction * vmax )
129+ or (x < fraction * vmin ),
100130 )
131+ normaliser_repr = getattr (
132+ normaliser ,
133+ "representation" ,
134+ f"{ normaliser_name } (V,{ ',' .join (p )} )" ,
135+ ).format (p )
101136 print (
102- "Fitted normal conductance background of G="
103- + str (p [0 ])
104- + "V^2 +"
105- + str (p [1 ])
106- + "V+"
107- + str (p [2 ])
137+ f"Fitted normal conductance background of G={ normaliser_repr } "
108138 )
109139 self ["normalise.coeffs" ] = p
110140 self ["normalise.coeffs_err" ] = np .sqrt (np .diag (pv ))
141+ self ["normaliser_name" ] = normaliser_name
111142 self .apply (
112- lambda x : x [self .gcol ] / quadratic (x [self .vcol ], * p ),
143+ lambda x : x [self .gcol ] / normaliser (x [self .vcol ], * p ),
113144 self .gcol ,
114145 header = self .column_headers [self .gcol ],
115146 )
@@ -192,7 +223,7 @@ def plot_results(self):
192223 def Fit (self ):
193224 """Run the fitting code."""
194225 # Run a pre-fitting data munge chain
195- self .RescaleV ().Discard ().offset_correct ().Decompose ().Normalise ()
226+ self .Preprocess (). RescaleV ().Discard ().offset_correct ().Decompose ().Normalise ()
196227 chi2 = self .p0 .shape [0 ] > 1
197228
198229 method = getattr (self , self .method )
@@ -227,6 +258,29 @@ def Fit(self):
227258 fit .save (False )
228259
229260
261+ def quadratic_abs (x , a , b , c ):
262+ """A function that returns a quadratic expression, but in terms of abs(x)."""
263+ x = np .abs (x )
264+ return c + x * (b + a * x )
265+
266+
267+ def _pass (x ):
268+ """A do nothing preprocess function."""
269+ return x
270+
271+
272+ def down_only (data ):
273+ """Selects only the down sweep data - this is a hack that works becuase Set V is not noisy"""
274+ ix = np .where (np .diff (np .sign (np .diff (data ["Set V" ]))) != 0 )[:2 ][0 ]
275+ dix = np .diff (ix ) > 10
276+ dix = np .append (dix , True )
277+ ix = ix [dix ]
278+ ix = ix [:2 ]
279+
280+ data .data = data .data [slice (* ix )]
281+ return data
282+
283+
230284if __name__ == "__main__" :
231285 d = working ()
232286 d .load_config ()
0 commit comments