Package reflectometry :: Package reduction :: Module ncnr_ng7

Source Code for Module reflectometry.reduction.ncnr_ng7

  1  # This program is public domain 
  2  """ 
  3  Data file reader for NCNR NG-7 data. 
  4   
  5  """ 
  6   
  7  import os, numpy 
  8  from reflectometry.reduction import icpformat 
  9  from reflectometry.reduction import refldata 
 10  from reflectometry.reduction import properties 
 11   
 12   
 13  # Instrument parameters 
 14  # As instrument parameters change add additional lines to this file 
 15  # indicating the new value and the date of the change.  The order of 
 16  # the entries does not matter.  The timestamp on the file will 
 17  # determine which value will be used. 
 18  # The format of the entries should be: 
 19  #      default.NAME = (VALUE, 'YYYY-MM-DD')  # value in effect after DD/MM/YYYY 
 20  #      default.NAME = (VALUE, '')          # value in effect at commissioning 
 21  default = properties.DatedValues() 
 22  default.wavelength = (4.76,'')  # in case ICP records the wrong value 
 23   
 24  # Detector saturates at 15000 counts/s.  The efficiency curve above 
 25  # 15000 has not been measured. 
 26  default.saturation = (numpy.array([[1,15000,0]]),'') 
 27   
 28   
 29  # NG-1 detector closer than slit 4? 
 30  default.detector_distance = (2000., '') # mm 
 31  default.psd_width = (100, '') # mm 
 32  default.slit1_distance = (-75*25.4, '') # mm 
 33  default.slit2_distance = (-14*25.4, '') # mm 
 34  default.slit3_distance = (9*25.4, '') # mm 
 35  default.slit4_distance = (42*25.4, '') # mm 
 36   
 37  #    rate     correction factor 
 38  saturation = """ 
 39       304     1.0   ; 
 40      1788     1.0074; 
 41      6812     1.0672; 
 42     13536     1.1399; 
 43     19426     1.2151; 
 44     24022     1.2944; 
 45     27771     1.370 ; 
 46     31174     1.429 
 47  """ 
 48  C = numpy.matrix(saturation).A 
 49  C[1,:] = 1/C[1,:] # Use efficiency rather than attenuation 
 50  default.pencil_saturation = (C, '') 
 51  # The following widths don't really matter for point detectors, but 
 52  # for completeness we can put in the values. 
 53  default.pencil_length = (25.4*6,'') # mm TODO: Is NG-7 pencil det. 6" long 
 54  default.pencil_width = (25.4*1,'') # mm TODO: Is NG-7 pencil det. 1" wide? 
 55   
 56  # TODO: NG-7 PSD saturates at 8000 counts/s? 
 57  default.psd_saturation = (numpy.array([1,8000],'f'),'') 
 58  default.psd_minbin = (9,'') 
 59  default.psd_maxbin = (246,'') 
 60  default.psd_width = (100,'') 
 61  default.psd_pixels = (256,'') 
 62  default.monitor_timestep = (60./100,'') # s ; ICP records 1/100ths of min 
 63   
 64  # =================================================================== 
 65   
66 -class NG7Icp(refldata.ReflData):
67 # Instrument description 68 probe = "neutron" 69 format = "NCNR ICP" 70 instrument = "NCNR NG-7" 71 72 # The following allows the user to override the wavelength 73 # all files in a dataset to compensate for an incorrectly 74 # recorded wavelength in ICP. 75 _wavelength_override = {}
76 - def __init__(self, path, *args, **kw):
77 super(NG7Icp,self).__init__(*args, **kw) 78 self.path = os.path.abspath(path) 79 80 81 data = icpformat.summary(path) 82 if data.scantype != 'R': 83 raise TypeError, "Only R-Buffers supported for NG-7" 84 85 self.date = data.date 86 self.name = data.filename 87 self.description = data.comment 88 self.dataset = self.name[:5] 89 90 self.default = default(str(data.date)) 91 self.detector.distance = self.default.detector_distance 92 self.slit1.distance = self.default.slit1_distance 93 self.slit2.distance = self.default.slit2_distance 94 self.slit3.distance = self.default.slit3_distance 95 self.slit4.distance = self.default.slit4_distance 96 self.detector.rotation = 0 # degrees 97 self.monitor.time_step = self.default.monitor_timestep 98 99 #if data.count_type=='TIME': 100 # # Override the default monitor base of 'counts' 101 # self.monitor.base='time' 102 103 if data.PSD: 104 self.instrument = 'NCNR NG-7 PSD' 105 self._psd() 106 else: 107 self.instrument = 'NCNR NG-7' 108 self._pencil_detector() 109 self.display_monitor = 1 110 111 # Set initial Qz 112 self.resetQ() 113 114 # Callback for lazy data 115 self.detector.loadcounts = self.loadcounts
116 117
118 - def _pencil_detector(self):
119 """ 120 Pencil detector on NG-7. 121 """ 122 self.detector.saturation = self.default.pencil_saturation 123 self.detector.width_x = self.default.pencil_length 124 self.detector.width_y = self.default.pencil_width 125 self.detector.center_x = 0 126 self.detector.center_y = 0 127 self.detector.rotation = 0
128
129 - def _psd(self):
130 """ 131 PSD on NG-7. 132 """ 133 self.detector.saturation = self.default.psd_saturation 134 width = self.default.psd_width 135 minbin,maxbin = self.default.psd_minbin,self.default.psd_maxbin 136 pixels = self.default.psd_pixels 137 self.detector.width_x = numpy.ones(pixels,'f')*(width/(maxbin-minbin)) 138 self.detector.center_x = 0 139 self.detector.width_y = self.default.psd_height
140
141 - def loadcounts(self):
142 data = icpformat.read(self.path) 143 return data.counts
144
145 - def load(self):
146 data = icpformat.read(self.path) 147 self.detector.wavelength \ 148 = data.check_wavelength(self.default.wavelength, 149 NG7Icp._wavelength_override) 150 151 if 'qz' in data: 152 # NG7 automatically increases count times as Qz increases 153 monitor, prefactor = data.monitor,data.prefactor 154 Mon1, Exp = data.Mon1,data.Exp 155 Qz = data.column.qz 156 automonitor = prefactor*(monitor + Mon1 * abs(Qz)**Exp) 157 if data.count_type == 'NEUT': 158 self.monitor.counts = automonitor 159 elif data.count_type == 'TIME': 160 self.monitor.count_time = automonitor 161 else: 162 raise ValueError, "Expected count type 'NEUT' or 'TIME' in "+self.path 163 164 if 'monitor' in data: 165 self.monitor.counts = data.column.monitor 166 if 'time' in data: 167 self.monitor.count_time = data.column.time*60 168 169 self.monitor.base = 'counts' if self.monitor.counts is not None else 'time' 170 171 if 's1' in data: self.slit1.x = data.column.s1 172 if 's2' in data: self.slit2.x = data.column.s2 173 if 's3' in data: self.slit3.x = data.column.s3 174 if 's4' in data: self.slit4.x = data.column.s4 175 if 'qz' in data: 176 Qx = data.column.qx if 'qx' in data else 0 177 Qz = data.column.qz 178 A,B = refldata.QxQzL_to_AB(Qx,Qz,self.detector.wavelength) 179 self.sample.angle_x,self.detector.angle_x = A,B 180 181 # Set initial Qz 182 self.resetQ() 183 184 # TODO: if the dataset is large, set up a weak reference instead 185 self.detector.counts = data.counts
186