Changeset 9a5097c in sasview for src/sas/sascalc/calculator
- Timestamp:
- Mar 26, 2017 11:33:16 PM (8 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- ed2276f
- Parents:
- 9146ed9
- Location:
- src/sas/sascalc/calculator
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sascalc/calculator/BaseComponent.py
rdeddda1 r9a5097c 9 9 from collections import OrderedDict 10 10 11 import numpy 11 import numpy as np 12 12 #TO DO: that about a way to make the parameter 13 13 #is self return if it is fittable or not … … 119 119 Then get :: 120 120 121 q = n umpy.sqrt(qx_prime^2+qy_prime^2)121 q = np.sqrt(qx_prime^2+qy_prime^2) 122 122 123 123 that is a qr in 1D array; :: … … 150 150 151 151 # calculate q_r component for 2D isotropic 152 q = n umpy.sqrt(qx**2+qy**2)152 q = np.sqrt(qx**2+qy**2) 153 153 # vectorize the model function runXY 154 v_model = n umpy.vectorize(self.runXY, otypes=[float])154 v_model = np.vectorize(self.runXY, otypes=[float]) 155 155 # calculate the scattering 156 156 iq_array = v_model(q) … … 160 160 elif qdist.__class__.__name__ == 'ndarray': 161 161 # We have a simple 1D distribution of q-values 162 v_model = n umpy.vectorize(self.runXY, otypes=[float])162 v_model = np.vectorize(self.runXY, otypes=[float]) 163 163 iq_array = v_model(qdist) 164 164 return iq_array -
src/sas/sascalc/calculator/instrument.py
rb699768 r9a5097c 3 3 control instrumental parameters 4 4 """ 5 import numpy 5 import numpy as np 6 6 7 7 # defaults in cgs unit … … 168 168 self.spectrum = self.get_default_spectrum() 169 169 # intensity in counts/sec 170 self.intensity = n umpy.interp(self.wavelength,170 self.intensity = np.interp(self.wavelength, 171 171 self.spectrum[0], 172 172 self.spectrum[1], … … 203 203 """ 204 204 spectrum = self.spectrum 205 intensity = n umpy.interp(self.wavelength,205 intensity = np.interp(self.wavelength, 206 206 spectrum[0], 207 207 spectrum[1], … … 244 244 self.wavelength = wavelength 245 245 validate(wavelength) 246 self.intensity = n umpy.interp(self.wavelength,246 self.intensity = np.interp(self.wavelength, 247 247 self.spectrum[0], 248 248 self.spectrum[1], … … 305 305 get default spectrum 306 306 """ 307 return n umpy.array(_LAMBDA_ARRAY)307 return np.array(_LAMBDA_ARRAY) 308 308 309 309 def get_band(self): … … 345 345 get list of the intensity wrt wavelength_list 346 346 """ 347 out = n umpy.interp(self.wavelength_list,347 out = np.interp(self.wavelength_list, 348 348 self.spectrum[0], 349 349 self.spectrum[1], -
src/sas/sascalc/calculator/resolution_calculator.py
rb699768 r9a5097c 12 12 from math import sqrt 13 13 import math 14 import numpy 14 import numpy as np 15 15 import sys 16 16 import logging … … 393 393 dx_size = (self.qx_max - self.qx_min) / (1000 - 1) 394 394 dy_size = (self.qy_max - self.qy_min) / (1000 - 1) 395 x_val = n umpy.arange(self.qx_min, self.qx_max, dx_size)396 y_val = n umpy.arange(self.qy_max, self.qy_min, -dy_size)397 q_1, q_2 = n umpy.meshgrid(x_val, y_val)395 x_val = np.arange(self.qx_min, self.qx_max, dx_size) 396 y_val = np.arange(self.qy_max, self.qy_min, -dy_size) 397 q_1, q_2 = np.meshgrid(x_val, y_val) 398 398 #q_phi = numpy.arctan(q_1,q_2) 399 399 # check whether polar or cartesian … … 887 887 x_value = x_val - x0_val 888 888 y_value = y_val - y0_val 889 phi_i = n umpy.arctan2(y_val, x_val)889 phi_i = np.arctan2(y_val, x_val) 890 890 891 891 # phi correction due to the gravity shift (in phi) … … 893 893 phi_i = phi_i - phi_0 + self.gravity_phi 894 894 895 sin_phi = n umpy.sin(self.gravity_phi)896 cos_phi = n umpy.cos(self.gravity_phi)895 sin_phi = np.sin(self.gravity_phi) 896 cos_phi = np.cos(self.gravity_phi) 897 897 898 898 x_p = x_value * cos_phi + y_value * sin_phi … … 908 908 nu_value = -0.5 * (new_x * new_x + new_y * new_y) 909 909 910 gaussian = n umpy.exp(nu_value)910 gaussian = np.exp(nu_value) 911 911 # normalizing factor correction 912 912 gaussian /= gaussian.sum() … … 954 954 nu_value *= nu_value 955 955 nu_value *= -0.5 956 gaussian *= n umpy.exp(nu_value)956 gaussian *= np.exp(nu_value) 957 957 gaussian /= sigma 958 958 # normalize … … 1026 1026 offset_x, offset_y) 1027 1027 # distance [cm] from the beam center on detector plane 1028 detector_ind_x = n umpy.arange(detector_pix_nums_x)1029 detector_ind_y = n umpy.arange(detector_pix_nums_y)1028 detector_ind_x = np.arange(detector_pix_nums_x) 1029 detector_ind_y = np.arange(detector_pix_nums_y) 1030 1030 1031 1031 # shif 0.5 pixel so that pix position is at the center of the pixel … … 1041 1041 detector_ind_y = detector_ind_y * pix_y_size 1042 1042 1043 qx_value = n umpy.zeros(len(detector_ind_x))1044 qy_value = n umpy.zeros(len(detector_ind_y))1043 qx_value = np.zeros(len(detector_ind_x)) 1044 qy_value = np.zeros(len(detector_ind_y)) 1045 1045 i = 0 1046 1046 … … 1061 1061 1062 1062 # p min and max values among the center of pixels 1063 self.qx_min = n umpy.min(qx_value)1064 self.qx_max = n umpy.max(qx_value)1065 self.qy_min = n umpy.min(qy_value)1066 self.qy_max = n umpy.max(qy_value)1063 self.qx_min = np.min(qx_value) 1064 self.qx_max = np.max(qx_value) 1065 self.qy_min = np.min(qy_value) 1066 self.qy_max = np.max(qy_value) 1067 1067 1068 1068 # Appr. min and max values of the detector display limits … … 1088 1088 from sas.sascalc.dataloader.data_info import Data2D 1089 1089 output = Data2D() 1090 inten = n umpy.zeros_like(qx_value)1090 inten = np.zeros_like(qx_value) 1091 1091 output.data = inten 1092 1092 output.qx_data = qx_value … … 1107 1107 plane_dist = dx_size 1108 1108 # full scattering angle on the x-axis 1109 theta = n umpy.arctan(plane_dist / det_dist)1110 qx_value = (2.0 * pi / wavelength) * n umpy.sin(theta)1109 theta = np.arctan(plane_dist / det_dist) 1110 qx_value = (2.0 * pi / wavelength) * np.sin(theta) 1111 1111 return qx_value 1112 1112 -
src/sas/sascalc/calculator/sas_gen.py
rd2fd8fc r9a5097c 7 7 from periodictable import formula 8 8 from periodictable import nsf 9 import numpy 9 import numpy as np 10 10 import os 11 11 import copy … … 80 80 ## Parameter details [units, min, max] 81 81 self.details = {} 82 self.details['scale'] = ['', 0.0, n umpy.inf]83 self.details['background'] = ['[1/cm]', 0.0, n umpy.inf]84 self.details['solvent_SLD'] = ['1/A^(2)', -n umpy.inf, numpy.inf]85 self.details['total_volume'] = ['A^(3)', 0.0, n umpy.inf]82 self.details['scale'] = ['', 0.0, np.inf] 83 self.details['background'] = ['[1/cm]', 0.0, np.inf] 84 self.details['solvent_SLD'] = ['1/A^(2)', -np.inf, np.inf] 85 self.details['total_volume'] = ['A^(3)', 0.0, np.inf] 86 86 self.details['Up_frac_in'] = ['[u/(u+d)]', 0.0, 1.0] 87 87 self.details['Up_frac_out'] = ['[u/(u+d)]', 0.0, 1.0] 88 self.details['Up_theta'] = ['[deg]', -n umpy.inf, numpy.inf]88 self.details['Up_theta'] = ['[deg]', -np.inf, np.inf] 89 89 # fixed parameters 90 90 self.fixed = [] … … 171 171 msg = "Not a 1D." 172 172 raise ValueError, msg 173 i_out = n umpy.zeros_like(x[0])173 i_out = np.zeros_like(x[0]) 174 174 # 1D I is found at y =0 in the 2D pattern 175 175 out = self._gen(x[0], [], i_out) … … 187 187 """ 188 188 if x.__class__.__name__ == 'list': 189 i_out = n umpy.zeros_like(x[0])189 i_out = np.zeros_like(x[0]) 190 190 out = self._gen(x[0], x[1], i_out) 191 191 return out … … 237 237 self.omfdata = omfdata 238 238 length = int(omfdata.xnodes * omfdata.ynodes * omfdata.znodes) 239 pos_x = n umpy.arange(omfdata.xmin,239 pos_x = np.arange(omfdata.xmin, 240 240 omfdata.xnodes*omfdata.xstepsize + omfdata.xmin, 241 241 omfdata.xstepsize) 242 pos_y = n umpy.arange(omfdata.ymin,242 pos_y = np.arange(omfdata.ymin, 243 243 omfdata.ynodes*omfdata.ystepsize + omfdata.ymin, 244 244 omfdata.ystepsize) 245 pos_z = n umpy.arange(omfdata.zmin,245 pos_z = np.arange(omfdata.zmin, 246 246 omfdata.znodes*omfdata.zstepsize + omfdata.zmin, 247 247 omfdata.zstepsize) 248 self.pos_x = n umpy.tile(pos_x, int(omfdata.ynodes * omfdata.znodes))248 self.pos_x = np.tile(pos_x, int(omfdata.ynodes * omfdata.znodes)) 249 249 self.pos_y = pos_y.repeat(int(omfdata.xnodes)) 250 self.pos_y = n umpy.tile(self.pos_y, int(omfdata.znodes))250 self.pos_y = np.tile(self.pos_y, int(omfdata.znodes)) 251 251 self.pos_z = pos_z.repeat(int(omfdata.xnodes * omfdata.ynodes)) 252 252 self.mx = omfdata.mx 253 253 self.my = omfdata.my 254 254 self.mz = omfdata.mz 255 self.sld_n = n umpy.zeros(length)255 self.sld_n = np.zeros(length) 256 256 257 257 if omfdata.mx == None: 258 self.mx = n umpy.zeros(length)258 self.mx = np.zeros(length) 259 259 if omfdata.my == None: 260 self.my = n umpy.zeros(length)260 self.my = np.zeros(length) 261 261 if omfdata.mz == None: 262 self.mz = n umpy.zeros(length)262 self.mz = np.zeros(length) 263 263 264 264 self._check_data_length(length) 265 265 self.remove_null_points(False, False) 266 mask = n umpy.ones(len(self.sld_n), dtype=bool)266 mask = np.ones(len(self.sld_n), dtype=bool) 267 267 if shape.lower() == 'ellipsoid': 268 268 try: … … 328 328 """ 329 329 if remove: 330 is_nonzero = (n umpy.fabs(self.mx) + numpy.fabs(self.my) +331 n umpy.fabs(self.mz)).nonzero()330 is_nonzero = (np.fabs(self.mx) + np.fabs(self.my) + 331 np.fabs(self.mz)).nonzero() 332 332 if len(is_nonzero[0]) > 0: 333 333 self.pos_x = self.pos_x[is_nonzero] … … 369 369 """ 370 370 desc = "" 371 mx = n umpy.zeros(0)372 my = n umpy.zeros(0)373 mz = n umpy.zeros(0)371 mx = np.zeros(0) 372 my = np.zeros(0) 373 mz = np.zeros(0) 374 374 try: 375 375 input_f = open(path, 'rb') … … 389 389 _my = mag2sld(_my, valueunit) 390 390 _mz = mag2sld(_mz, valueunit) 391 mx = n umpy.append(mx, _mx)392 my = n umpy.append(my, _my)393 mz = n umpy.append(mz, _mz)391 mx = np.append(mx, _mx) 392 my = np.append(my, _my) 393 mz = np.append(mz, _mz) 394 394 except: 395 395 # Skip non-data lines … … 501 501 :raise RuntimeError: when the file can't be opened 502 502 """ 503 pos_x = n umpy.zeros(0)504 pos_y = n umpy.zeros(0)505 pos_z = n umpy.zeros(0)506 sld_n = n umpy.zeros(0)507 sld_mx = n umpy.zeros(0)508 sld_my = n umpy.zeros(0)509 sld_mz = n umpy.zeros(0)510 vol_pix = n umpy.zeros(0)511 pix_symbol = n umpy.zeros(0)503 pos_x = np.zeros(0) 504 pos_y = np.zeros(0) 505 pos_z = np.zeros(0) 506 sld_n = np.zeros(0) 507 sld_mx = np.zeros(0) 508 sld_my = np.zeros(0) 509 sld_mz = np.zeros(0) 510 vol_pix = np.zeros(0) 511 pix_symbol = np.zeros(0) 512 512 x_line = [] 513 513 y_line = [] … … 543 543 _pos_y = float(line[38:46].strip()) 544 544 _pos_z = float(line[46:54].strip()) 545 pos_x = n umpy.append(pos_x, _pos_x)546 pos_y = n umpy.append(pos_y, _pos_y)547 pos_z = n umpy.append(pos_z, _pos_z)545 pos_x = np.append(pos_x, _pos_x) 546 pos_y = np.append(pos_y, _pos_y) 547 pos_z = np.append(pos_z, _pos_z) 548 548 try: 549 549 val = nsf.neutron_sld(atom_name)[0] 550 550 # sld in Ang^-2 unit 551 551 val *= 1.0e-6 552 sld_n = n umpy.append(sld_n, val)552 sld_n = np.append(sld_n, val) 553 553 atom = formula(atom_name) 554 554 # cm to A units 555 555 vol = 1.0e+24 * atom.mass / atom.density / NA 556 vol_pix = n umpy.append(vol_pix, vol)556 vol_pix = np.append(vol_pix, vol) 557 557 except: 558 558 print "Error: set the sld of %s to zero"% atom_name 559 sld_n = n umpy.append(sld_n, 0.0)560 sld_mx = n umpy.append(sld_mx, 0)561 sld_my = n umpy.append(sld_my, 0)562 sld_mz = n umpy.append(sld_mz, 0)563 pix_symbol = n umpy.append(pix_symbol, atom_name)559 sld_n = np.append(sld_n, 0.0) 560 sld_mx = np.append(sld_mx, 0) 561 sld_my = np.append(sld_my, 0) 562 sld_mz = np.append(sld_mz, 0) 563 pix_symbol = np.append(pix_symbol, atom_name) 564 564 elif line[0:6].strip().count('CONECT') > 0: 565 565 toks = line.split() … … 630 630 """ 631 631 try: 632 pos_x = n umpy.zeros(0)633 pos_y = n umpy.zeros(0)634 pos_z = n umpy.zeros(0)635 sld_n = n umpy.zeros(0)636 sld_mx = n umpy.zeros(0)637 sld_my = n umpy.zeros(0)638 sld_mz = n umpy.zeros(0)632 pos_x = np.zeros(0) 633 pos_y = np.zeros(0) 634 pos_z = np.zeros(0) 635 sld_n = np.zeros(0) 636 sld_mx = np.zeros(0) 637 sld_my = np.zeros(0) 638 sld_mz = np.zeros(0) 639 639 try: 640 640 # Use numpy to speed up loading 641 input_f = n umpy.loadtxt(path, dtype='float', skiprows=1,641 input_f = np.loadtxt(path, dtype='float', skiprows=1, 642 642 ndmin=1, unpack=True) 643 pos_x = n umpy.array(input_f[0])644 pos_y = n umpy.array(input_f[1])645 pos_z = n umpy.array(input_f[2])646 sld_n = n umpy.array(input_f[3])647 sld_mx = n umpy.array(input_f[4])648 sld_my = n umpy.array(input_f[5])649 sld_mz = n umpy.array(input_f[6])643 pos_x = np.array(input_f[0]) 644 pos_y = np.array(input_f[1]) 645 pos_z = np.array(input_f[2]) 646 sld_n = np.array(input_f[3]) 647 sld_mx = np.array(input_f[4]) 648 sld_my = np.array(input_f[5]) 649 sld_mz = np.array(input_f[6]) 650 650 ncols = len(input_f) 651 651 if ncols == 8: 652 vol_pix = n umpy.array(input_f[7])652 vol_pix = np.array(input_f[7]) 653 653 elif ncols == 7: 654 654 vol_pix = None … … 669 669 _sld_my = float(toks[5]) 670 670 _sld_mz = float(toks[6]) 671 pos_x = n umpy.append(pos_x, _pos_x)672 pos_y = n umpy.append(pos_y, _pos_y)673 pos_z = n umpy.append(pos_z, _pos_z)674 sld_n = n umpy.append(sld_n, _sld_n)675 sld_mx = n umpy.append(sld_mx, _sld_mx)676 sld_my = n umpy.append(sld_my, _sld_my)677 sld_mz = n umpy.append(sld_mz, _sld_mz)671 pos_x = np.append(pos_x, _pos_x) 672 pos_y = np.append(pos_y, _pos_y) 673 pos_z = np.append(pos_z, _pos_z) 674 sld_n = np.append(sld_n, _sld_n) 675 sld_mx = np.append(sld_mx, _sld_mx) 676 sld_my = np.append(sld_my, _sld_my) 677 sld_mz = np.append(sld_mz, _sld_mz) 678 678 try: 679 679 _vol_pix = float(toks[7]) 680 vol_pix = n umpy.append(vol_pix, _vol_pix)680 vol_pix = np.append(vol_pix, _vol_pix) 681 681 except: 682 682 vol_pix = None … … 712 712 sld_n = data.sld_n 713 713 if sld_n == None: 714 sld_n = n umpy.zeros(length)714 sld_n = np.zeros(length) 715 715 sld_mx = data.sld_mx 716 716 if sld_mx == None: 717 sld_mx = n umpy.zeros(length)718 sld_my = n umpy.zeros(length)719 sld_mz = n umpy.zeros(length)717 sld_mx = np.zeros(length) 718 sld_my = np.zeros(length) 719 sld_mz = np.zeros(length) 720 720 else: 721 721 sld_my = data.sld_my … … 893 893 if self.is_data: 894 894 # For data, put the value to only the pixels w non-zero M 895 is_nonzero = (n umpy.fabs(self.sld_mx) +896 n umpy.fabs(self.sld_my) +897 n umpy.fabs(self.sld_mz)).nonzero()898 self.sld_n = n umpy.zeros(len(self.pos_x))895 is_nonzero = (np.fabs(self.sld_mx) + 896 np.fabs(self.sld_my) + 897 np.fabs(self.sld_mz)).nonzero() 898 self.sld_n = np.zeros(len(self.pos_x)) 899 899 if len(self.sld_n[is_nonzero]) > 0: 900 900 self.sld_n[is_nonzero] = sld_n … … 903 903 else: 904 904 # For non-data, put the value to all the pixels 905 self.sld_n = n umpy.ones(len(self.pos_x)) * sld_n905 self.sld_n = np.ones(len(self.pos_x)) * sld_n 906 906 else: 907 907 self.sld_n = sld_n … … 912 912 """ 913 913 if sld_mx.__class__.__name__ == 'float': 914 self.sld_mx = n umpy.ones(len(self.pos_x)) * sld_mx914 self.sld_mx = np.ones(len(self.pos_x)) * sld_mx 915 915 else: 916 916 self.sld_mx = sld_mx 917 917 if sld_my.__class__.__name__ == 'float': 918 self.sld_my = n umpy.ones(len(self.pos_x)) * sld_my918 self.sld_my = np.ones(len(self.pos_x)) * sld_my 919 919 else: 920 920 self.sld_my = sld_my 921 921 if sld_mz.__class__.__name__ == 'float': 922 self.sld_mz = n umpy.ones(len(self.pos_x)) * sld_mz922 self.sld_mz = np.ones(len(self.pos_x)) * sld_mz 923 923 else: 924 924 self.sld_mz = sld_mz 925 925 926 sld_m = n umpy.sqrt(sld_mx * sld_mx + sld_my * sld_my + \926 sld_m = np.sqrt(sld_mx * sld_mx + sld_my * sld_my + \ 927 927 sld_mz * sld_mz) 928 928 self.sld_m = sld_m … … 936 936 return 937 937 if symbol.__class__.__name__ == 'str': 938 self.pix_symbol = n umpy.repeat(symbol, len(self.sld_n))938 self.pix_symbol = np.repeat(symbol, len(self.sld_n)) 939 939 else: 940 940 self.pix_symbol = symbol … … 950 950 self.vol_pix = vol 951 951 elif vol.__class__.__name__.count('float') > 0: 952 self.vol_pix = n umpy.repeat(vol, len(self.sld_n))952 self.vol_pix = np.repeat(vol, len(self.sld_n)) 953 953 else: 954 954 self.vol_pix = None … … 993 993 for x_pos in self.pos_x: 994 994 if xpos_pre != x_pos: 995 self.xstepsize = n umpy.fabs(x_pos - xpos_pre)995 self.xstepsize = np.fabs(x_pos - xpos_pre) 996 996 break 997 997 for y_pos in self.pos_y: 998 998 if ypos_pre != y_pos: 999 self.ystepsize = n umpy.fabs(y_pos - ypos_pre)999 self.ystepsize = np.fabs(y_pos - ypos_pre) 1000 1000 break 1001 1001 for z_pos in self.pos_z: 1002 1002 if zpos_pre != z_pos: 1003 self.zstepsize = n umpy.fabs(z_pos - zpos_pre)1003 self.zstepsize = np.fabs(z_pos - zpos_pre) 1004 1004 break 1005 1005 #default pix volume 1006 self.vol_pix = n umpy.ones(len(self.pos_x))1006 self.vol_pix = np.ones(len(self.pos_x)) 1007 1007 vol = self.xstepsize * self.ystepsize * self.zstepsize 1008 1008 self.set_pixel_volumes(vol) … … 1071 1071 y2 = output.pos_y+output.sld_my/max_m * gap 1072 1072 z2 = output.pos_z+output.sld_mz/max_m * gap 1073 x_arrow = n umpy.column_stack((output.pos_x, x2))1074 y_arrow = n umpy.column_stack((output.pos_y, y2))1075 z_arrow = n umpy.column_stack((output.pos_z, z2))1073 x_arrow = np.column_stack((output.pos_x, x2)) 1074 y_arrow = np.column_stack((output.pos_y, y2)) 1075 z_arrow = np.column_stack((output.pos_z, z2)) 1076 1076 unit_x2 = output.sld_mx / max_m 1077 1077 unit_y2 = output.sld_my / max_m 1078 1078 unit_z2 = output.sld_mz / max_m 1079 color_x = n umpy.fabs(unit_x2 * 0.8)1080 color_y = n umpy.fabs(unit_y2 * 0.8)1081 color_z = n umpy.fabs(unit_z2 * 0.8)1082 colors = n umpy.column_stack((color_x, color_y, color_z))1079 color_x = np.fabs(unit_x2 * 0.8) 1080 color_y = np.fabs(unit_y2 * 0.8) 1081 color_z = np.fabs(unit_z2 * 0.8) 1082 colors = np.column_stack((color_x, color_y, color_z)) 1083 1083 plt.show() 1084 1084 … … 1103 1103 model = GenSAS() 1104 1104 model.set_sld_data(foutput.output) 1105 x = n umpy.arange(1000)/10000. + 1e-51106 y = n umpy.arange(1000)/10000. + 1e-51107 i = n umpy.zeros(1000)1105 x = np.arange(1000)/10000. + 1e-5 1106 y = np.arange(1000)/10000. + 1e-5 1107 i = np.zeros(1000) 1108 1108 model.runXY([x, y, i]) 1109 1109
Note: See TracChangeset
for help on using the changeset viewer.