def test_move_down_1(self): sm = SampleModel() sm.addItem(Layer(name='0')) sm.addItem(Layer(name='1')) sm.addItem(Layer(name='2')) sm.addItem(Layer(name='3')) sm.move_down_1([3]) #cannot move down more expected_names = ['incoming media', '0', '1', '2', '3', 'substrate'] self.assertEqual( [s.name for s in [sm.incoming_media] + sm.layers + [sm.substrate]], expected_names) sm.move_down_1([1]) expected_names = ['incoming media', '0', '2', '1', '3', 'substrate'] self.assertEqual( [s.name for s in [sm.incoming_media] + sm.layers + [sm.substrate]], expected_names) sm.move_down_1([0, 2]) expected_names = ['incoming media', '2', '0', '3', '1', 'substrate'] self.assertEqual( [s.name for s in [sm.incoming_media] + sm.layers + [sm.substrate]], expected_names) sm.move_up_1([1, 2, 4]) #no effect expected_names = ['incoming media', '2', '0', '3', '1', 'substrate'] self.assertEqual( [s.name for s in [sm.incoming_media] + sm.layers + [sm.substrate]], expected_names)
def bare_silicon_model(ox_thick=18, ox_sld=2.0e-6, ox_rough=3.0, si_rough=3.0): """ Generate a bare silicon substrate in air """ _incoming = Layer(name='air', thickness=np.inf, nsld_real=0, nsld_imaginary=0, msld_rho=0, msld_phi=0, msld_theta=0, roughness=0, roughness_model=RoughnessModel.NONE, sublayers=10) _oxide = Layer(name='SiOx', thickness=ox_thick, nsld_real=ox_sld, nsld_imaginary=0, msld_rho=0, msld_phi=0, msld_theta=0, roughness=ox_rough, roughness_model=RoughnessModel.ERFC, sublayers=10) _oxide._nsld_real.vary = True _oxide._nsld_real.minimum = 1e-6 _oxide._nsld_real.maximum = 4e-6 _oxide._thickness.vary = True _oxide._thickness.minimum = 1 _oxide._thickness.maximum = 50 _oxide._roughness.vary = True _oxide._roughness.minimum = 1 _oxide._roughness.maximum = 8 _substrate = Layer(name='Si', thickness=np.inf, nsld_real=2.07e-006, nsld_imaginary=0, msld_rho=0, msld_phi=0, msld_theta=0, roughness=si_rough, roughness_model=RoughnessModel.ERFC, sublayers=8) _substrate._roughness.vary = True _substrate._roughness.minimum = 1 _substrate._roughness.maximum = 10 return [_incoming, _oxide, _substrate]
class Testchi3_137(unittest.TestCase): Q = np.loadtxt(os.path.join(os.path.dirname(__file__),'data/chi3_137/q.dat'),unpack=True) inc_moment = Q / 2.0 sigma = res_chi3_137(Q) substrate = Layer() substrate.nsld = complex(3.6214e-006, 0.0) layer_info = np.loadtxt(os.path.join(os.path.dirname(__file__), 'data/chi3_137/profile_sublayers.dat')) layer_info = layer_info[:-1] layers = [Layer(name='Incoming media')] for line in layer_info: l = Layer() l.thickness = line[1] l.nsld = complex(line[2], line[3]) msld = [line[4], line[5], line[6]] #l.msld = [msld[0]*np.sin(msld[2])*np.cos(msld[1]), msld[0]*np.sin(msld[2])*np.sin(msld[1]), msld[0]*np.cos(msld[2])] l.msld.rho=msld[0] l.msld.theta=msld[2] l.msld.phi=msld[1] l.NC = 0.0 layers.append(l) layers.append(substrate) R = reflection.reflection(inc_moment, layers) pol_vecs = [[0.98,0.0,0.0], [-0.98,0.0,0.0], [0.98,0.0,0.0], [0.0,0.0,0.0], [0.0,0.0,0.0], [0.0,0.0,0.0]] an_vecs = [[0.98,0.0,0.0], [-0.98,0.0,0.0], [-0.98,0.0,0.0], [0.0,0.0,0.0], [0.0,0.0,0.0], [0.0,0.0,0.0]] norm_factor=[1.0, 1.0, 1.0, 1.0, 1.0, 1.0] background=1.2e-05; pol_eff = np.ones(len(Q), dtype = np.complex128) an_eff = np.ones(len(Q), dtype = np.complex128) n_of_outputs = 3 for k in range(n_of_outputs): RR = reflection.spin_av(R, pol_vecs[k], an_vecs[k], pol_eff, an_eff) RR = np.real(RR) RRr = reflection.resolut(RR, Q, sigma, 3) RRr = RRr * norm_factor[k] + background fig,ax = plt.subplots() ax.semilogy(Q,RRr,label='calculation') #plt.xlim([0.0,0.06]) #plt.ylim([1.0e-4,10.0]) reference_values = np.loadtxt(os.path.join(os.path.dirname(__file__),'data/chi3_137/rtheory'+str(k+1)+'.dat'), unpack=True) assert_array_almost_equal(RRr,reference_values,2) ax.semilogy(Q, reference_values, label='reference') ax.set_xlabel('Momentum Transfer $\AA^{-1}$') ax.set_ylabel('Reflectivity') ax.set_title('Polarization ({},{},{}), Analysis({},{},{})'.format(pol_vecs[k][0],pol_vecs[k][1],pol_vecs[k][2],an_vecs[k][0],an_vecs[k][1],an_vecs[k][2])) ax.legend() fig.savefig('chi3_137_'+str(k+1)+'.pdf') plt.close()
def test_iterate(self): sm = SampleModel() sm.addItem(Layer(name='0')) sm.addItem(Layer(name='1')) sm.addItem(Layer(name='2', thickness=3.14)) sm.addItem(Layer(name='3')) expected_names = ['0', '1', '2', '3'] self.assertEqual([s.name for s in sm], expected_names) expected_thickness = [0, 0, 3.14, 0] self.assertEqual([s.thickness.value for s in sm], expected_thickness) for i, layer in enumerate(sm): layer.nsld = 3 * i + 4j for i in range(4): self.assertEqual(sm.layers[i].nsld_real.value, 3 * i) self.assertEqual(sm.layers[i].nsld_imaginary.value, 4)
def test_reference_results(self): paramfile = open(os.path.join(os.path.dirname(__file__),'data/refl_par.dat'),'r') n_monte_carlo = int(paramfile.readline()) formalism = int(paramfile.readline()) res_mode = int(paramfile.readline()) n_of_outputs = int(paramfile.readline()) pol_vecs = np.array([float(value) for value in paramfile.readline().strip().split()]).reshape(6,3) an_vecs = np.array([float(value) for value in paramfile.readline().strip().split()]).reshape(6,3) pol_fun = [int(value) for value in paramfile.readline().split()] norm_factor = [int(value) for value in paramfile.readline().split()] maxwell = int(paramfile.readline()) glance_angle = int(paramfile.readline()) background = float(paramfile.readline()) percentage = float(paramfile.readline()) nlayers1 = int(paramfile.readline()) substrate_tmp = [float(value) for value in paramfile.readline().split()] substrate=Layer() substrate.nsld = complex(substrate_tmp[0],substrate_tmp[1]) NC = float(paramfile.readline()) layers = [Layer(name='Incoming media')] for i in range(nlayers1): l = Layer() l.thickness = float(paramfile.readline()) nsld_tmp = [float(value) for value in paramfile.readline().split()] l.nsld = complex(nsld_tmp[0], nsld_tmp[1]) msld_xyz = np.array([float(value) for value in paramfile.readline().split()]) l.msld.rho = np.sqrt(msld_xyz.dot(msld_xyz)) l.msld.phi= np.degrees(np.arctan2(msld_xyz[1],msld_xyz[0])) l.msld.theta=0 if l.msld.rho.value!=0: l.msld.theta=np.degrees(np.arccos(np.nan_to_num(msld_xyz[2]/l.msld.rho.value))) l.NC = float(paramfile.readline()) layers.append(l) paramfile.close() q, dq = np.loadtxt(os.path.join(os.path.dirname(__file__),'data/refl_q_dq.dat'),unpack=True) inc_moment = q / 2.0 pol_eff = np.ones(len(q), dtype=np.complex128) an_eff = np.ones(len(q), dtype=np.complex128) layers.append(substrate) R = reflection.reflection(inc_moment, layers) for k in range(n_of_outputs): RR = reflection.spin_av(R, pol_vecs[k], an_vecs[k], pol_eff, an_eff) RR = np.real(RR) for res_mode in range(1,3): RRr = reflection.resolut(RR, q, dq, res_mode) RRr = RRr * norm_factor[k] + background reference_values = np.loadtxt(os.path.join(os.path.dirname(__file__),'data/res_mode'+str(res_mode)+'refl'+str(k+1)+'.dat'), unpack=True) assert_array_almost_equal(reference_values, RRr)
def test_creation_addition_deletion(self): sm = SampleModel() sm.addItem(Layer(name='0')) sm.addItem(Layer(name='1')) sm.addItem(Layer(name='2')) sm.addItem(Layer(name='3')) sm.addItem('4') #should have no effect expected_names = ['incoming media', '0', '1', '2', '3', 'substrate'] self.assertEqual( [s.name for s in [sm.incoming_media] + sm.layers + [sm.substrate]], expected_names) sm.delItem(0) expected_names = ['incoming media', '1', '2', '3', 'substrate'] self.assertEqual( [s.name for s in [sm.incoming_media] + sm.layers + [sm.substrate]], expected_names) sm.delItem(3) expected_names = ['incoming media', '1', '2', '3', 'substrate'] self.assertEqual( [s.name for s in [sm.incoming_media] + sm.layers + [sm.substrate]], expected_names)
def __init__(self, *args): QtWidgets.QWidget.__init__(self, *args) self.sample = [Layer(thickness=np.inf), Layer(thickness=np.inf)] self.setLayout(QtWidgets.QVBoxLayout()) function_options = [ 'NSLD_REAL', 'NSLD_IMAGINARY', 'MSLD_RHO', 'MSLD_THETA', 'MSLD_PHI', 'ROUGHNESS' ] self.combo = QtWidgets.QComboBox(self) for f in function_options: self.combo.addItem(f) self.function = 'NSLD_REAL' self.paintwidget = QtWidgets.QWidget(self) self.paintwidget.setMinimumSize(450, 350) self.canvas = PlotCanvas(self.sample, self.function, self.paintwidget) self.hlayout = QtWidgets.QHBoxLayout() self.hlayout.addStretch(1) self.hlayout.addWidget(self.combo) self.hlayout.addStretch(1) self.layout().addLayout(self.hlayout) self.layout().addWidget(self.paintwidget) self.combo.activated[str].connect(self.functionSelected)
def layer_data_for_testing(): Incoming = Layer(thickness=np.inf, nsld_real=0, nsld_imaginary=0, msld_rho=0, msld_phi=0, msld_theta=0, roughness=0, roughness_model=RoughnessModel.NONE, sublayers=16) Layer1 = Layer(thickness=90., nsld_real=3.e-6, nsld_imaginary=-3e-8, msld_rho=0, msld_phi=0, msld_theta=90, roughness=0., roughness_model=RoughnessModel.NONE, sublayers=10) Layer2 = Layer(thickness=40., nsld_real=3.5e-6, nsld_imaginary=-3e-8, msld_rho=5.31171e-7, msld_phi=11.1877, msld_theta=90, roughness=8., roughness_model=RoughnessModel.TANH, sublayers=10) Layer3 = Layer(thickness=75, nsld_real=2.3e-006, nsld_imaginary=-3e-8, msld_rho=1.96841e-006, msld_phi=10.8359, msld_theta=90, roughness=5, roughness_model=RoughnessModel.TANH, sublayers=10) Layer4 = Layer(thickness=125., nsld_real=2.4347e-006, nsld_imaginary=-3e-8, msld_rho=2.28882e-006, msld_phi=9.48435, msld_theta=90, roughness=4, roughness_model=RoughnessModel.TANH, sublayers=10) Substrate = Layer(thickness=np.inf, nsld_real=3.533e-006, nsld_imaginary=0, msld_rho=0, msld_phi=0, msld_theta=0, roughness=5., roughness_model=RoughnessModel.TANH, sublayers=10) layers = [Incoming, Layer1, Layer2, Layer3, Layer4, Substrate] return layers
def addClicked(self): selected = self.listView.selectionModel().selectedRows() inds = sorted([s.row() for s in selected]) selected = [] if inds: for i, j in enumerate(inds): if j in [0, self.sample_model.rowCount() - 1]: self.invalidSelection.emit( 'Cannot add another substrate or incoming media') else: self.sample_model.addItem( copy.deepcopy(self.sample_model.layers[i - 1 + j]), i + j) selected.append(i + j) else: self.sample_model.addItem(Layer()) self.sampleModelChanged.emit(self.sample_model) self.listView.selectionModel().clear() for selection in selected: self.listView.selectionModel().select( self.sample_model.index(selection), QtCore.QItemSelectionModel.Select)
substrate_index, QtCore.QItemSelectionModel.Select) else: self.listView.selectionModel().select( substrate_index, QtCore.QItemSelectionModel.Deselect) if (incoming_media_index in all_rows) and len(all_rows) > 1: if incoming_media_index in selected: if len(selected) > 1: self.listView.selectionModel().select( incoming_media_index, QtCore.QItemSelectionModel.Deselect) else: self.listView.selectionModel().clear() self.listView.selectionModel().select( incoming_media_index, QtCore.QItemSelectionModel.Select) else: self.listView.selectionModel().select( incoming_media_index, QtCore.QItemSelectionModel.Deselect) if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) sm = SampleModel() sm.addItem(Layer(name='L0')) sm.addItem(Layer(name='L1', thickness=2)) sm.addItem(Layer(name='L2')) sm.addItem(Layer(name='L3')) window = layerselector(sm) window.show() sys.exit(app.exec_())
def layer_data_for_testing(): Incoming = Layer(thickness=np.inf, nsld_real=0, nsld_imaginary=0, msld_rho=0, msld_phi=0, msld_theta=0, roughness=0, roughness_model=RoughnessModel.NONE, sublayers=16) Layer1 = Layer(thickness=95.6772, nsld_real=3.3458e-6, nsld_imaginary=-3e-8, msld_rho=0, msld_phi=0, msld_theta=90, roughness=5., roughness_model=RoughnessModel.TANH, sublayers=10) Layer2 = Layer(thickness=40.6943, nsld_real=3.5159e-6, nsld_imaginary=-3e-8, msld_rho=5.31171e-7, msld_phi=11.1877, msld_theta=90, roughness=5., roughness_model=RoughnessModel.TANH, sublayers=10) Layer3 = Layer(thickness=78.5585, nsld_real=2.3132e-006, nsld_imaginary=-3e-8, msld_rho=1.96841e-006, msld_phi=10.8359, msld_theta=90, roughness=5, roughness_model=RoughnessModel.TANH, sublayers=10) Layer4 = Layer(thickness=124.141, nsld_real=2.4347e-006, nsld_imaginary=-3e-8, msld_rho=2.28882e-006, msld_phi=9.48435, msld_theta=90, roughness=5, roughness_model=RoughnessModel.TANH, sublayers=10) Layer5 = Layer(thickness=65.6139, nsld_real=4.1353e-006, nsld_imaginary=-3e-8, msld_rho=-1.54978e-008, msld_phi=-55.6648, msld_theta=90, roughness=5, roughness_model=RoughnessModel.TANH, sublayers=10) Layer6 = Layer(thickness=254.437, nsld_real=5.7216e-006, nsld_imaginary=-2.5693e-021, msld_rho=0, msld_phi=0, msld_theta=90, roughness=5, roughness_model=RoughnessModel.TANH, sublayers=10) Layer7 = Layer(thickness=59.2843, nsld_real=3.7163e-006, nsld_imaginary=+3.3154e-020, msld_rho=3.65952e-007, msld_phi=-16.3845, msld_theta=90, roughness=5, roughness_model=RoughnessModel.TANH, sublayers=10) Layer8 = Layer(thickness=165.617, nsld_real=3.8014e-006, nsld_imaginary=+4.2572e-020, msld_rho=9.61537e-007, msld_phi=-5.01155, msld_theta=90, roughness=5, roughness_model=RoughnessModel.TANH, sublayers=10) Substrate = Layer(thickness=np.inf, nsld_real=3.533e-006, nsld_imaginary=0, msld_rho=0, msld_phi=0, msld_theta=0, roughness=5., roughness_model=RoughnessModel.TANH, sublayers=10) layers = [ Incoming, Layer1, Layer2, Layer3, Layer4, Layer5, Layer6, Layer7, Layer8, Substrate ] return layers
def rough_sublayer(layer_up, layer_down): """ Function to calculate sublayers when there is roughness at the interface Args: layer_up (Layer): The first layer (closer to surface) layer_down (Layer): The second layer Returns: tuple: list of sublayers, and a list of of ints (0 and 1), both the same length. If the int corresponding to index is 0, the sublayer belongs to layer_up """ #some constants alpha = {"ERFC": sci_sp.erfinv(0.5) * 2., "TANH": np.arctanh(0.5) * 2.} delta = {"ERFC": sci_sp.erfinv(0.97), "TANH": np.arctanh(0.97)} #sigma is multiplied with 1.3 to correspond to Nevot-Croce roughness parameter sigma = layer_down.roughness.value * 1.3 model = layer_down.roughness_model.name N = layer_down.sublayers if (model not in ["ERFC", "TANH"]) or (N < 2) or (sigma == 0): half_layer_up = deepcopy(layer_up) half_layer_down = deepcopy(layer_down) half_layer_up.thickness.value *= 0.5 half_layer_down.thickness.value *= 0.5 return ([half_layer_up, half_layer_down], [0, 1]) scale = alpha[model] / sigma gamma = delta[model] / scale #first/last sublayer values. Only nsld_real,nsld_imaginary, and msld_rho are affected by rougness values_up = np.array([ layer_up.nsld_real.value, layer_up.nsld_imaginary.value, layer_up.msld.rho.value ]) values_down = np.array([ layer_down.nsld_real.value, layer_down.nsld_imaginary.value, layer_down.msld.rho.value ]) #extracting layer thicknesses and calculate interface extent L_up = gamma L_down = L_up thickness_up = layer_up.thickness.value thickness_down = layer_down.thickness.value up_bound = None down_bound = None if gamma < thickness_up / 2.: up_bound = thickness_up / 2. - L_up #this part of the up layer is not changed else: L_up = thickness_up / 2. if gamma < thickness_down / 2.: down_bound = thickness_down / 2. - L_down #this part of the down layer is not changed else: L_down = thickness_down / 2. #adjust the values to account for non-symmetric distribution if (thickness_up < thickness_down) and (gamma > thickness_up / 2): values_up = values_down - (values_down - values_up) * thickness_up / ( L_down + L_up - J(model, -L_up, L_down, scale)) if (thickness_up > thickness_down) and (gamma > thickness_down / 2): values_down = values_up + ( values_down - values_up) * thickness_down / ( L_down + L_up + J(model, -L_up, L_down, scale)) #create sublayers sublayer_thickness = (L_up + L_down) / N sublayer_centers = np.linspace(-L_up + sublayer_thickness / 2, L_down - sublayer_thickness / 2, N) if model == "TANH": new_values = ((values_down - values_up)[:, np.newaxis] * (np.tanh(scale * sublayer_centers) + 1.) / 2.).transpose() + values_up else: new_values = ((values_down - values_up)[:, np.newaxis] * (sci_sp.erf(scale * sublayer_centers) + 1.) / 2.).transpose() + values_up sublayers_nsld_re, sublayers_nsld_im, sublayers_msld_rho = new_values.transpose( ) sublayers_msld_theta = [ layer_up.msld.theta.value if x < 0 else layer_down.msld.theta.value for x in sublayer_centers ] sublayers_msld_phi = [ layer_up.msld.phi.value if x < 0 else layer_down.msld.phi.value for x in sublayer_centers ] sublayer_list = [ Layer(sublayer_thickness, nr, ni, mr, mt, mp, 0, RoughnessModel.NONE, 0) for nr, ni, mr, mt, mp in zip( sublayers_nsld_re, sublayers_nsld_im, sublayers_msld_rho, sublayers_msld_theta, sublayers_msld_phi) ] corresponding_layer = list( np.piecewise(sublayer_centers, [sublayer_centers < 0, sublayer_centers >= 0], [0, 1])) #deal with rest of the half layers, outside of the rough region if up_bound is not None: sublayer_list.insert( 0, Layer(up_bound, layer_up.nsld_real.value, layer_up.nsld_imaginary.value, layer_up.msld.rho.value, layer_up.msld.theta.value, layer_up.msld.phi.value, 0, RoughnessModel.NONE, 0)) corresponding_layer.insert(0, 0) if down_bound is not None: sublayer_list.append( Layer(down_bound, layer_down.nsld_real.value, layer_down.nsld_imaginary.value, layer_down.msld.rho.value, layer_down.msld.theta.value, layer_down.msld.phi.value, 0, RoughnessModel.NONE, 0)) corresponding_layer.append(1) return (sublayer_list, corresponding_layer)
ax.set_xlim(xmin, xmax) ax.axhline(y=0) ax.set_xlabel('Depth') ax.set_ylabel(parameter.replace('_', ' ')) return sublayers, corresponding if __name__ == '__main__': # This is for testing purposes only import sys app = QtWidgets.QApplication(sys.argv) mainForm = layerplot() from licorne.layer import RoughnessModel from licorne.SampleModel import SampleModel newSample = SampleModel() newSample.incoming_media = Layer(thickness=np.inf, nsld_real=1.5) newSample.layers = [ Layer(thickness=20., nsld_real=1.), Layer(thickness=25., nsld_real=3., roughness=5, roughness_model=RoughnessModel.TANH, sublayers=7), Layer(thickness=30., nsld_real=5., msld_rho=7e-7, roughness=3, roughness_model=RoughnessModel.TANH, sublayers=7) ] newSample.substrate = Layer(nsld_real=4., thickness=np.inf)