Package reflectometry :: Package reduction :: Module nexusref

Source Code for Module reflectometry.reduction.nexusref

  1  # This program is public domain 
  2   
  3  """ 
  4  Load a NeXus file into a reflectometry data structure. 
  5  """ 
  6  import os 
  7   
  8  from reflectometry.reduction import refldata, nexus 
  9   
10 -def load_entries(filename):
11 """ 12 Load the summary info for all entries in a NeXus file. 13 """ 14 tree = nexus.read(filename) 15 measurements = [] 16 for name,entry in tree.nodes(): 17 if entry.nxclass == 'NXentry': 18 measurements.append(NeXusRefl(entry,filename)) 19 return measurements
20 21
22 -class NeXusRefl(refldata.ReflData):
23 """ 24 NeXus reflectometry entry. 25 26 See `reflectometry.reduction.refldata.ReflData` for details. 27 """ 28 format = "NeXus" 29
30 - def __init__(self, entry, filename):
31 super(NeXusRefl,self).__init__() 32 self.filename = os.path.abspath(filename) 33 34 if entry.definition.value == "TOFRAW": 35 self.entry = entry 36 else: 37 raise ValueError, "NeXusRefl only supports TOFRAW format" 38 39 # Callback for lazy data 40 self.detector.loadcounts = self.loadcounts 41 42 # Set initial Qz 43 self.resetQ()
44 45
46 - def loadcounts(self):
47 # Load the counts from the data file 48 counts = self.entry.NXinstrument.NXdetector.data.read() 49 return counts
50
51 - def _load_slits(self, instrument):
52 """ 53 Slit names have not been standardized. Instead sort the 54 NXaperature components by distance and assign them according 55 to serial order, negative aperatures first and positive second. 56 """ 57 slits = instrument.find('NXaperature') 58 # Note: only supports to aperatures before and after. 59 # Assumes x and y aperatures are coupled in the same 60 # component. This will likely be wrong for some instruments, 61 # but we won't deal with that until we have real NeXus files 62 # to support. 63 # Assume the file writer was sane and specified all slit 64 # distances in the same units so that sorting is simple. 65 # Currently only slit distance is recorded, not slit opening. 66 slits.sort(lambda a,b: -1 if a.distance < b.distance else 1) 67 index = 0 68 for slit in slits: 69 d = slit.distance.value('meters') 70 if d <= 0: 71 # process first two slits only 72 if index == 0: 73 self.slit1.distance = d 74 index += 1 75 elif index == 1: 76 self.slit2.distance = d 77 index += 1 78 elif d > 0: 79 # skip leading slits 80 if index < 2: index = 2 81 if index == 2: 82 self.slit3.distance = d 83 index += 1 84 elif index == 3: 85 self.slit4.distance = d 86 index += 1
87
88 - def load(self):
89 entry = self.entry 90 self.instrument = entry.NXinstrument.name.value 91 self.probe = 'neutron' 92 # Use proton charge as a proxy for monitor; we will use the 93 # real monitor when it comes available. 94 self.monitor.source_power_units = 'coulombs' 95 self.monitor.source_power \ 96 = entry.proton_charge.read(self.monitor.source_power_units) 97 self.monitor.count_time = entry.duration.read('seconds') 98 self.monitor.base = 'power' 99 100 # TODO: we are not yet reading the monitor values for the 101 # reflectometers since they are not yet in place. When they 102 # are in place, it will be problematic since it will not 103 # be clear to the reduction software whether it should be 104 # using monitor 1 or monitor 2, and how it should normalize 105 # if it is using one or the other without hardcoding details 106 # of SNS Liquids into the reduction process. 107 108 sample = entry.NXsample 109 self.sample.description = sample.name.value 110 111 # TODO: entry has sample changer position, which is a 112 # way of saying we have no idea what sample is in the 113 # beam. I hope the control software handles this 114 # properly! 115 116 instrument = entry.NXinstrument 117 self._load_slits(instrument) 118 moderator = instrument.NXmoderator 119 self.moderator.distance = moderator.distance.read('meters') 120 self.moderator.type = moderator.type.value 121 self.moderator.temperature = moderator.temperature.read('kelvin')
122