1
2 """
3 Reflectometry data representation.
4
5 Need to support collections of data from TOF, monochromatic
6 and white beam instruments.
7
8 Conceptually each data point is a tuple::
9
10 incident angles (sample tilt and rotation)
11 reflected angles (polar angle of detector pixel)
12 slit distances and openings
13 detector pixel distance and size
14 incident/reflected polarization
15 wavelength distribution
16 measurement start and duration
17 monitor and detector counts
18 sample environment
19
20 Reflectometers are either vertical or horizontal geometry.
21 For vertical geometry (sample surface parallel to gravity),
22 x refers to horizontal slit opening and horizontal detector
23 pixels. For horizontal geometry (sample surface perpendicular
24 to gravity) x refers to vertical slit opening and vertical
25 detector pixels. Other than gravitational corrections to
26 resolution and detector pixels, the analysis for the two
27 instrument types should be identical.
28
29 Monochromatic reflectometers have a single wavelength per
30 measurement but scan the measurements. Time-of-flight and
31 polychromatic reflectometers have multiple wavelengths per
32 measurement but perform one measurement. In either case
33 a dataset consists of detector frames versus Q. We will
34 ignore scans on multichannel instruments since these can
35 be treated as combined independent scans with non-overlapping
36 data, and handled outside this data structure.
37
38 Data points are gathered together into measurements. Some
39 files may have multiple measurements, and other measurements
40 may be spread over multiple files. Files may be local or
41 remote, ascii or binary. It is up to the individual format
42 reader to assign map measurements to files.
43
44 Different polarization states will be treated as belonging
45 to different measurements. These will need to be aligned
46 before polarization correction can be performed. Multiple
47 measurements may occur on the same detector. In this
48 case each measurement should have a separate 'region of
49 interest' to isolate it from the others, presenting a virtual
50 detector to the reduction and analysis program.
51
52 Some information about the measurements may be missing
53 from the files, or recorded incorrectly. Changes and
54 additions to the metadata must be recorded in any reduced
55 data file format, along with a list of transformations
56 that went into the reduction.
57
58 See notes in properties.py regarding dated values.
59 """
60 __all__ = ['ReflData']
61
62 import datetime
63 import weakref
64
65 import numpy
66 from numpy import inf, pi, sin, cos, arcsin, arctan2, sqrt
67
68 from qxqz import ABL_to_QxQz
69
70
71
72
74 """
75 Define a slit for the instrument. This is needed for correct resolution
76 calculations and for ab initio footprint calculations.
77
78 distance (inf millimetre)
79 Distance from sample. Positive numbers are after the sample,
80 negative numbers are before the sample along the beam path.
81 offset (4 x 0 millimetre)
82 Offset of the slit blades relative to the distance from the sample.
83 For vertical geometry, this is left, right, up, down. For horizontal
84 geometry this is up, down, left, right. Offset + distance gives the
85 distances of the individual blades from the sample, with negative
86 numbers occurring before the sample position and positive numbers
87 after.
88 shape (shape='rectangular')
89 Whether we have slit blades ('rectangular') or a circular
90 aperature ('circular').
91 x (n x inf millimetre)
92 Slit opening in the primary direction. For vertical geometry
93 this is the horizontal opening, for horizontal geometry this is
94 the vertical opening. This may be a constant (fixed slits) or
95 of length n for the number of measurements.
96 y (n x inf millimetre)
97 Slit opening in the secondary direction. This may be a constant
98 (fixed slits) or of length n for the number of measurements.
99 """
100 properties = ['distance','offset','x','y','shape']
101 distance = inf
102 offset = [0.]*4
103 x = inf
104 y = inf
105 shape = "rectangular"
106
107 - def __init__(self, **kw): _set(self,kw)
108 - def __str__(self): return _str(self)
109
111 """
112 Define the sample geometry. Size and shape areneeded for correct
113 resolution calculations and for ab initio footprint calculations.
114 Angles are needed for correct calculation of Q. Rotation and
115 environment are for display to the user.
116
117 description ("")
118 Sample description, if available from the file.
119 width (inf millimetre)
120 Width of the sample in the primary direction. For fixed slits
121 the footprint of the beam on the sample decreases with angle
122 in this direction.
123 length (inf millimetre)
124 Width of the sample in the secondary direction. The footprint
125 is independent of angle in this direction.
126 thickness (inf millimetre)
127 Thickness of the sample.
128 substrate_sld (10^-6 Angstrom^-2)
129 To plot Fresnel reflectivity we need to know the substrate
130 scattering length density. The default is to assume silicon.
131 shape ('rectangular')
132 Shape is 'circular' or 'rectangular'
133 angle_x (n x 0 degree)
134 Angle between neutron beam and sample surface in the primary
135 direction. This may be constant or an array of length n for
136 the number of measurements.
137 angle_y (n x 0 degree)
138 Angle between the neutron beam and sample surface in the
139 secondary direction. This may be constant or an array of
140 length n for the number of measurements. This is known as
141 tilt on some instruments.
142 rotation (n x 0 degree)
143 For off-specular reflectivity the orientation of the patterned
144 array on the surface of the sample affects the computed theory.
145 This value is not needed for data reduction, but it should be
146 reported to the user during reduction and carried through to
147 the reduced file for correct analysis.
148 environment ({})
149 Sample environment data. See Environment class for a list of
150 common environment data.
151 """
152 properties = ['description','width','length','thickness','shape',
153 'angle_x','angle_y','rotation','substrate_sld']
154 description = ''
155 width = inf
156 length = inf
157 thickness = inf
158 shape = 'rectangular'
159 angle_x = 0
160 angle_y = 0
161 rotation = 0
162 substrate_sld = 2.07
163
165 self.environment = {}
166 _set(self,kw)
167 - def __str__(self): return _str(self)
168
169
170
172 """
173 Define sample environment data for the measurements such as
174 temperature (kelvin)
175 pressure (pascal)
176 relative_humidity (%)
177 electric_field (V/m)
178 magnetic_field (tesla)
179 stress_field (pascal)
180
181 The data may be a constant, a series of values equal to
182 the number of scan points, or a series of values and times.
183 The average, max and min over all scan points, and the
184 value, max and min for a particular scan point may be
185 available.
186
187 Some measurements are directional, and will have a polar
188 and azimuthal angle associated with them. This may be
189 constant for the entire scan, or stored separately with
190 each magnitude measurement.
191
192 name
193 Name of environment variable
194 units
195 Units to report on graphs
196 average, minimum, maximum
197 Statistics on all measurements
198 value
199 Magnitude of the measurement
200 start
201 Start time for log
202 time (seconds)
203 Measurement time relative to start
204 polar_angle (degree)
205 azimuthal_angle (degree)
206 Provide orientation relative to the sample surface for
207 directional parameters:
208 * x is polar 0, azimuthal 0
209 * y is polar 90, azimuthal 0
210 * z is azimuthal 90
211 """
212 pass
213
214
216 """
217 Define the geometry of the beamstop. This is used by the
218 detector class to compute the shadow of the beamstop on the
219 detector. The beamstop is assumed to be centered on the
220 direct beam regardless of the position of the detector.
221
222 distance (0 millimetre)
223 Distance from sample to beamstop. Note: this will need to
224 be subtracted from the distance from detector to beamstop.
225 shape ('rectangular')
226 Shape is 'circular' or 'rectangular'
227 width (0 millimetre)
228 Width of the beamstop in the primary direction. For circular
229 beamstops, this is the diameter.
230 length (0 millimetre)
231 Width of the beamstop in the secondary direction. For circular
232 beamstops, this is the diameter.
233 offset (2 x millimetre)
234 Offset of the beamstop from the center of the beam.
235 ispresent (False)
236 True if beamstop is present in the experiment.
237 """
238 properties = ['distance','width','length','shape',
239 'x_offset','y_offset','ispresent']
240 distance = 0
241 width = 0
242 length = 0
243 shape = 'rectangular'
244 offset = [0,0]
245 ispresent = False
246
247 - def __init__(self, **kw): _set(self,kw)
248 - def __str__(self): return _str(self)
249
251 """
252 Define the detector properties. Note that this defines a virtual
253 detector. The real detector may have e.g., multiple beam paths
254 incident upon it, and be split into two virtual detectors when
255 the file is loaded.
256
257 Direction x refers to the primary direction, and direction y to
258 the secondary direction. For vertical geometry, the primary
259 direction is in the horizontal plane and the secondary direction
260 is in the vertical plane. For horizontal geometry these are
261 reversed. This allows the reduction software to be simpler,
262 but may complicate file loading from formats which store values
263 in absolute geometry.
264
265 Geometry
266 ========
267 dims (2 x pixels)
268 Dimensions of the detector, [nx,ny]. For pencil detectors this
269 should be [1,1]. For position sensitive detectors, this should be
270 [nx,1]. For area detectors, this should be [nx,ny].
271 distance (millimetre)
272 Distance from the sample to the detector.
273 size (2 x millimetre)
274 Detector size, [x,y]. Default is 1 mm x 1 mm.
275 solid_angle (2 x radian)
276 Detector solid angle [x,y], calculated from distance and size.
277 center (2 x millimetre)
278 Location of the center pixel [x,y] relative to the detector arm.
279 widths_x (nx x millimetre)
280 widths_y (ny x millimetre)
281 Pixel widths in x and y. We assume no space between the pixels.
282 angle_x (n x degree)
283 angle_y (n x degree)
284 Angle of the detector arm relative to the main beam in x and y.
285 This may be constant or an array of length n for the number of
286 measurements in the scan.
287 rotation (degree)
288 Angle of rotation of the detector relative to the beam. This
289 will affect how vertical integration in the region of interest
290 is calculated. Ideally the detector would not be rotated, though
291 misalignment can sometimes occur.
292
293 Efficiency
294 ==========
295 efficiency (nx x ny %)
296 Efficiency of the individual pixels; this is an array of the same
297 shape as the detector, giving the relative efficiency of each pixel,
298 or 1 if the efficiency is unknown.
299 TODO: do we need variance?
300 saturation (k [%, counts/second, uncertainty])
301 Given a measurement of a given number of counts versus expected
302 number of counts on the detector (e.g., as estimated by scanning
303 a narrow slit across the detector to measure the beam profile,
304 then measuring increasingly large portions of the beam profile),
305 this can be converted to an efficiency correction per count rate
306 which can be applied to all data read with this detector. The
307 value for deadtime should be a tuple of three vectors: efficiency,
308 uncertainty and count rate. Below the lowest count rate the
309 detector is considered to be 100% efficient (any baseline
310 inefficiency will be normalized when comparing the measured
311 reflection to the measured beam). Beyond the highest count
312 rate, the detector is considered saturated. The uncertainty
313 is just the sqrt(counts)/time.
314
315
316 Note: Given the nature of the detectors (detecting ionization
317 caused by neutron capture) there is undoubtably a local
318 saturation level, but this is likely masked by the usual
319 detector electronics which can only detect one event at a
320 time regardless of where it occurs on the detector.
321
322 Measurement
323 ===========
324 wavelength (k nanometre)
325 Wavelength for each channel
326 wavelength_resolution (k %)
327 Wavelength resolution of the beam for each channel using 1-sigma
328 gaussian approximation dL, expressed as 100*dL/L. The actual
329 wavelength distribution is considerably more complicated, being
330 approximately square for multi-sheet monochromators and highly
331 skewed on TOF machines.
332 time_of_flight (k+1 millisecond)
333 Time boundaries for time-of-flight measurement
334 counts (nx x ny x k counts OR n x nx x ny counts)
335 nx x ny detector pixels
336 n number of measurements
337 k time/wavelength channels
338
339 Runtime Facilities
340 ==================
341 loadcounts (function returning counts)
342 Counts can be assigned using
343 data.detector.counts = weakref.ref(counts)
344 When the counts field is accessed, the reference will be resolved.
345 If it yields None, then loadcounts will be called and assigned to
346 counts as a weak reference. In this way large datasets can be
347 removed from memory when not in active use.
348 """
349 properties=["dims",'distance','size','center','widths_x','widths_y',
350 'angle_x','angle_y','rotation','efficiency','saturation',
351 'wavelength','time_of_flight','counts']
352 dims = [1,1]
353 distance = None
354 size = [1,1]
355 center = [0,0]
356 widths_x = 1
357 widths_y = 1
358 angle_x = 0
359 angle_y = 0
360 rotation = 0
361 efficiency = 1
362 saturation = inf
363 wavelength = 1
364 time_of_flight = None
365
367 """Detector solid angle [x,y] (radians)"""
368 return 2*arctan2(numpy.asarray(self.size)/2.,self.distance)
369 solid_angle = property(_solid_angle,doc=_solid_angle.__doc__)
370
371
372
373
374
375
377 """Load the data"""
378 raise NotImplementedError,\
379 "Data format must set detector.counts or detector.loadcounts"
381 """Simulated empty weak reference"""
382 return None
390
391
392
393 if isinstance(value,weakref.ref):
394 self._pcounts = value
395 else:
396 def static(): return value
397 self._pcounts = static
398
400 _pcounts = lambda:None
401 counts = property(_getcounts,_setcounts,_delcounts)
402
403
404 - def __init__(self, **kw): _set(self,kw)
405 - def __str__(self): return _str(self)
406
407
409 """
410 Detector region of interest.
411
412 Defines a rectangular region of interest on the detector which
413 is used for defining frames. This can be used for example to
414 split a single detector with both polarization states (via
415 transmission and reflection off a supermirror) into two virtual
416 detectors.
417
418 xlo, xhi (pixels)
419 ylo, yhi (pixels)
420 """
421 properties = ['xlo','xhi','ylo','yhi']
422 xlo = None
423 xhi = None
424 ylo = None
425 yhi = None
426
427 - def __init__(self, **kw): _set(self,kw)
428 - def __str__(self): return _str(self)
429
431 """
432 Define the monitor properties.
433
434 The monitor is essential to the normalization of reflectometry data.
435 Reflectometry is the number of neutrons detected divided by the
436 number of neutrons incident on the sample. To compute this ratio,
437 the incident and detected neutrons must be normalized to the neutron
438 rate, either counts per monitor count, counts per second or counts
439 per unit of source power (e.g., coulombs of protons incident on the
440 detector, or megawatt hours of reactor power).
441
442 counts (n x k counts)
443 Number of counts measured. For scanning instruments there is
444 a separate count for each of the n measurements. For TOF
445 instruments there is a separate count for each of k time
446 channels. Counts may be absent, in which case normalization
447 must be by time or by monitor. In some circumstances the
448 user may generate a counts vector, for example by estimating
449 the count rate by other means, in order to combine data
450 measured by time with data measured by monitor when the
451 monitor values are otherwise unreliable. Variance is assumed
452 to be the number of counts, after any necessary rebinning.
453 count_time (n seconds)
454 Duration of the measurement. For scanning instruments, there is
455 a separate duration for each measurement. For TOF, this is a
456 single value equal to the duration of the entire measurement.
457 source_power (n source_power_units)
458 The source power for each measurement. For situations when the
459 monitor cannot be trusted (which can happen from time to time on
460 some instruments), we can use the number of protons incident on
461 the target (proton charge) or the energy of the source (reactor
462 power integrated over the duration of each measurement) as a proxy
463 for the monitor. So long as the we normalize both the slit
464 measurement and the reflectivity measurement by the power, this
465 should give us a reasonable estimate of the reflectivity. If
466 the information is available, this will be a better proxy for
467 monitor than measurement duration.
468 base ('time' | 'counts' | 'power')
469 The measurement rate basis which should be used to normalize
470 the data. This is initialized by the file loader, but may
471 be overridden during reduction.
472 time_step (seconds)
473 The count_time timer has a reporting unit, e.g. second, or
474 millisecond, or in the case of NCNR ICP files, hundredths of
475 a minute. The measurement uncertainty for the count time
476 is assumed to be uniform over the time_step, centered on
477 the reported time, with a gaussian approximation of uncertainty
478 being sqrt(time_step/12).
479 start_time (n seconds)
480 For scanning instruments the start of each measurement relative
481 to start of the scan. Note that this is not simply sum of the
482 count times because there may be motor movement between
483 measurements. The start time is required to align the measurement
484 values with environment parameters, and for calculation of He3
485 polarization. For TOF, this should be zero.
486 distance (metre)
487 Distance from the sample. This is not used by reduction but
488 may be of interest to the user.
489 sampled_fraction ([0,1])
490 Portion of the neutrons that are sampled by the monitor. If the
491 monitor is after the second slit, the monitor value can be used to
492 estimate the the counts on the detector, scaled by the sampled
493 fraction. Otherwise a full slit scan is required to normalize
494 the reflectivity. This is the inverse of the detector to monitor
495 ratio used to normalize data on some instruments.
496 time_of_flight (k+1 millisecond)
497 Time boundaries for the time-of-flight measurement
498 source_power_units ('coulombs' | 'megawatthours')
499 Units for source power.
500 source_power_variance (n source_power_units)
501 Variance in the measured source power
502 monitor_rate (counts/second)
503 For normalizing by counts when only count time is recorded, we
504 need an estimate of the monitor rate during the measurement.
505 """
506 properties = ['distance','sampled_fraction','counts','start_time',
507 'count_time','time_step','time_of_flight','base',
508 'monitor_rate','source_power','source_power_units']
509 distance = None
510 sampled_fraction = None
511 counts = None
512 start_time = None
513 count_time = None
514 time_step = 1
515 time_of_flight = None
516 base = 'counts'
517 source_power = 1
518 source_power_units = "MW"
519 source_power_variance = 0
520 monitor_rate = 0
521
522 - def __init__(self, **kw): _set(self,kw)
523 - def __str__(self): return _str(self)
524
526 """
527 Time of flight calculations require information about the moderator.
528 Primarily this is the length of the flight path from moderator to
529 monitor or detector required to compute wavelength.
530
531 Moderator temperature is also recorded. The user should probably
532 be warned when working with datasets with different moderator
533 temperatures since this is likely to affect the wavelength
534 spectrum of the beam.
535
536 distance (metre)
537 Distance from moderator to sample. This is negative since the
538 monitor is certainly before the sample.
539 temperature (kelvin)
540 Temperature of the moderator
541 type (string)
542 For information only at this point.
543 """
544 properties = ['distance','temperature','type']
545 distance = None
546 temperature = None
547 type = 'Unknown'
548
549 - def __init__(self, **kw): _set(self, kw)
550 - def __str__(self): return _str(self)
551
553 """
554 A warning is an information message and a possible set of actions to
555 take in response to the warning.
556
557 The user interface can query the message and the action list, generate
558 a dialog on the basis of the information. Actions may have associated
559 attributes that need to be set for the action to complete.
560 """
561 pass
562
564 """
565 Unexpected wavelength warning.
566
567 This warning is attached to any dataset which has an unexpected
568 wavelength stored in the file (more than 1% different from the
569 default wavelength for the instrument).
570
571 Various actions can be done in response to the warning, including
572 always taking the default value for this instrument, overriding for
573 every value in the dataset
574 """
575 pass
576
578 """
579 slit1,slit2 (Slit)
580 Presample slits
581 slit3,slit4 (Slit)
582 Post sample slits
583 sample
584 Sample geometry
585 detector
586 Detector geometry, efficiency and counts
587 monitor
588 Counts and/or durations
589 polarization
590 '' unpolarized
591 '+' spin up
592 '-' spin down
593 '++','--' non-spin-flip
594 '-+','+-' spin flip
595 points
596 For scanning instruments, the number of measurements.
597 channels
598 For time of flight, the number of time channels. For white
599 beam instruments, the number of analysers.
600 reversed (False)
601 True if the measurement is reversed, in which case sample
602 and detector angles need to be negated and pixel directions
603 reversed when computing pixel coordinates.
604 roi
605 Region of interest on the detector.
606 display_monitor (counts)
607 Default monitor to use when displaying data from this dataset
608
609 File details
610 ============
611 instrument (string)
612 Name of a particular instrument
613 probe ('neutron' or 'xray')
614 Type of radiation used to probe the sample.
615 path (string)
616 Location of the datafile
617 entry (string)
618 Entry identifier if more than one entry per file
619 name (string)
620 Name of the dataset. This may be a combination of filename and
621 entry number.
622 description (string)
623 Description of the entry.
624 date (timestamp)
625 Starting date and time of the measurement.
626 duration (second)
627 Duration of the measurement.
628 warnings
629 List of warnings generated when the file was loaded
630 intent (string)
631 Purpose of the measurement.
632 intensity: Normalization scan for computing absolute reflection
633 specular: Specular intensity measurement
634 q_offset: Background measurement, offset from Qx=0 in Q
635 sample_offset: Background measurement, sample rotated
636 detector_offset: Background measurement, detector moved
637 slice: Slice through Qx-Qz
638 area: Measurement of a region of Qx-Qz plane
639 alignment: Sample alignment measurement
640 other: Some other kind of measurement
641
642 Format specific fields (ignored by reduction software)
643 ======================
644 file (handle)
645 Format specific file handle, for actions like showing the summary,
646 updating the data and reading the frames.
647 """
648 properties = ['instrument','geometry','probe','points','channels',
649 'name','description','date','duration','attenuator',
650 'polarization','reversed','warnings','path','entry']
651 geometry = "vertical"
652 probe = "unknown"
653 format = "unknown"
654 path = "unknown"
655 entry = ""
656 points = 1
657 channels = 1
658 name = ""
659 description = ""
660 date = datetime.datetime(1970,1,1)
661 duration = 0
662 file = None
663 attenuator = 1.
664 polarization = ''
665 reversed = False
666 warnings = None
667 messages = None
668
670 - def _setdR(self, dR): self.varR = dR**2
671 dR = property(_getdR,_setdR)
672
673
674
675 - def _getx(self): return self.Qz
676 - def _gety(self): return self.Qx
677 - def _getz(self): return self.Qy
678 - def _getv(self): return self.R
680 x,xlabel,xunits = property(_getx),"Qx","inv A"
681 y,ylabel,yunits = property(_gety),"Qy","inv A"
682 z,zlabel,zunits = property(_getz),"Qz","inv A"
683 v,dv = property(_getv),property(_getdv)
684
685
687
688
689
690 _set(self,kw)
691 self.sample = Sample()
692 self.slit1 = Slit()
693 self.slit2 = Slit()
694 self.slit3 = Slit()
695 self.slit4 = Slit()
696 self.detector = Detector()
697 self.monitor = Monitor()
698 self.moderator = Moderator()
699 self.warnings = []
700 self.roi = ROI()
701 self.messages = []
702
704 base = [_str(self)]
705 others = [str(s) for s in [self.slit1,self.slit2,self.slit3,self.slit4,
706 self.sample,self.detector,self.monitor,
707 self.roi]]
708 return "\n".join(base+others)
709
710 - def warn(self,msg):
711 """Record a warning that should be displayed to the user"""
712 self.warnings.append(msg)
713
715 """Record corrections that have been applied to the data"""
716 self.messages.append(msg)
717
718 - def apply(self,correction):
722
724 """Recompute Qx,Qz from geometry and wavelength"""
725 A,B = self.sample.angle_x,self.detector.angle_x
726 L = self.detector.wavelength
727 Qx,Qz = ABL_to_QxQz(A,B,L)
728 self.Qx,self.Qz = Qx,Qz
729
731 """
732 Helper function: document data object by convert attributes listed in
733 properties into a string.
734 """
735 cls = object.__class__.__name__
736 props = [a+"="+str(getattr(object,a)) for a in object.properties]
737 return "%s %s"%(cls,"\n ".join(props))
738
739
740 -def _set(object,kw):
741 '''
742 Helper function: distribute the __init__ keyward paramters to
743 individual attributes of an object, raising AttributeError if
744 the class does not define the given attribute.
745
746 Example:
747
748 def __init__(self, **kw): _set(self,kw)
749 '''
750 for k,v in kw.iteritems():
751 if hasattr(self,k):
752 setattr(object,k,v)
753 else:
754 raise AttributeError, "Unknown attribute %s"%(k)
755
756
757
758
759 """
760 Computed values
761 ===============
762 edges_x (metric=['pixel'|'mm'|'degrees'|'radians'],frame=0)
763 Returns the nx+1 pixel edges of the detector in the given units.
764 In distance units, this is the distance relative to the center
765 of the detector arm.
766 edges_y (metric=['pixel'|'mm'|'degrees'|'radians'],frame=0)
767 Returns the ny+1 pixel edges of the detector in the given units.
768
769 def resolution(self):
770 return
771 """
772
773
776 """
777 Return the number of detector frames available.
778 """
779 return self.channels*self.points
780
782 """
783 Convert raw frames into a form suitable for display.
784 """
785
786
787 xlo,xhi,ylo,yhi = self.roi
788 counts = self.detector.counts
789 nq = zhi-zlo+1
790 nx = self.detector.shape[0]
791 ny = self.detector.shape[1]
792 if ny == 1:
793 self.zx = counts[zlo:zhi+1,:]
794 else:
795 xy = numpy.zeros((nx,ny),dtype='float32')
796 zx = numpy.zeros((nq,nx),dtype='float32')
797 self.framerange = Limits()
798 for i in range(zlo,zhi):
799 v = self.frame(i)
800 self.framerange.add(v,dv=sqrt(v))
801 xy += v
802 zx[i-zlo,:] = numpy.sum(v[:,ylo:yhi],axis=1)
803 self.xy = xy
804 self.zx = zx
805
807 """
808 Return the 2-D detector frame for the given index k. For
809 multichannel instruments, index is the index for the channel
810 otherwise index is the measurement number.
811
812 The result is undefined if the detector is not a 2-D detector.
813 """
814 if self.channels > 1:
815 return self.detector.counts[:,index]
816 else:
817 return self.detector.counts[index,:]
818
819
820
821 -def shadow(f, beamstop, frame):
822 """
823 Construct a mask for the detector frame indicating which pixels
824 are outside the shadow of the beamstop. This pixels should not
825 be used when estimating sample background. Note that this becomes
826 considerably more tricky when angular divergence and gravity
827 are taken into account. The mask should include enough of the
828 penumbra that these effects can be ignored.
829
830 Currently this function returns no shadow.
831 """
832 mask = numpy.ones(self.detector.shape,'int8')
833 if beamstop.ispresent:
834
835
836 pass
837 return mask
838