def get_maxima(self, threshold=5.0): '''Run diffdump, printpeaks to get a list of diffraction maxima at their image positions, to allow for further analysis.''' if not self._image: raise RuntimeError('image not set') if not os.path.exists(self._image): raise RuntimeError('image %s does not exist' % \ self._image) dd = Diffdump() dd.set_image(self._image) header = dd.readheader() beam = header['raw_beam'] pixel = header['pixel'] template, directory = image2template_directory(self._image) image_number = image2image(os.path.split(self._image)[-1]) spot_file = '%s.spt' % template_number2image( template, image_number) self.start() self.input('template "%s"' % template) self.input('directory "%s"' % directory) self.input('findspots local find %d file %s' % \ (image_number, spot_file)) self.input('go') self.close_wait() self.check_for_errors() output = open(os.path.join(self.get_working_directory(), spot_file)).readlines() os.remove(os.path.join(self.get_working_directory(), spot_file)) peaks = [] for record in output[3:-2]: lst = record.split() x = float(lst[0]) y = float(lst[1]) i = float(lst[4]) / float(lst[5]) x /= pixel[0] y /= pixel[1] if i < threshold: continue # this is Mosflm right? Swap X & Y!! peaks.append((y, x, i)) return peaks
def epocher(images): '''Get a list of epochs for each image in this list, returning as a list of tuples.''' result = [] for i in images: dd = Diffdump() dd.set_image(i) header = dd.readheader() e = header['epoch'] result.append((i, e)) return result
def get_maxima(self): '''Run diffdump, printpeaks to get a list of diffraction maxima at their image positions, to allow for further analysis.''' if not self._image: raise RuntimeError('image not set') if not os.path.exists(self._image): raise RuntimeError('image %s does not exist' % \ self._image) dd = Diffdump() dd.set_image(self._image) header = dd.readheader() beam = header['raw_beam'] pixel = header['pixel'] self.add_command_line(self._image) self.start() self.close_wait() self.check_for_errors() # results were ok, so get all of the output out output = self.get_all_output() peaks = [] for record in output: if not 'Peak' in record[:4]: continue lst = record.replace(':', ' ').split() x = float(lst[4]) y = float(lst[6]) i = float(lst[-1]) x += beam[0] y += beam[1] x /= pixel[0] y /= pixel[1] peaks.append((x, y, i)) return peaks
def accumulate(images): '''Accumulate dose as a function of image epoch.''' dose = {} integrated_dose = {} for i in images: dd = Diffdump() dd.set_image(i) header = dd.readheader() d = header['exposure_time'] e = header['epoch'] dose[e] = d keys = sorted(dose.keys()) accum = 0.0 for k in keys: integrated_dose[k] = accum + 0.5 * dose[k] accum += dose[k] # ok, now check that the value for the maximum dose is < 1e6 - elsewise # chef may explode. or write out ****** as the values are too large for # an f8.1 format statement. max_dose = max([integrated_dose[k] for k in keys]) factor = 1.0 while max_dose / factor > 1.0e6: factor *= 10.0 Debug.write('Doses scaled by %5.2e' % factor) # now divide all of those doses by factor for k in keys: integrated_dose[k] /= factor return integrated_dose, factor
assert 0.0 <= i[0] <= 2.0 assert 0.0 <= i[1] <= 2.0 assert math.fabs((dot(x, d) / math.sqrt(dot(x, x) * dot(d, d))) - 1) < 0.001 if __name__ == "__main_work__": work_equation_of_line() if __name__ == "__main__": from xia2.Wrappers.XIA.Diffdump import Diffdump bm = BackstopMask(sys.argv[1]) dd = Diffdump() dd.set_image(sys.argv[2]) header = dd.readheader() def format_limits(limits): assert len(limits) == 4 result = "limits quad" for l in limits: result += " %.1f %.1f" % l return result print(format_limits(bm.calculate_mask_mosflm(header)))
def gain(image): """Get the gain from an image.""" dd = Diffdump() dd.set_image(image) return dd.gain()
def mosflm_check_indexer_solution(indexer): distance = indexer.get_indexer_distance() axis = matrix.col([0, 0, 1]) beam = indexer.get_indexer_beam_centre() cell = indexer.get_indexer_cell() wavelength = indexer.get_wavelength() space_group_number = l2s(indexer.get_indexer_lattice()) spacegroup = sgtbx.space_group_symbols(space_group_number).hall() phi = indexer.get_header()['phi_width'] sg = sgtbx.space_group(spacegroup) if not (sg.n_ltr() - 1): # primitive solution - just return ... something return None, None, None, None # FIXME need to raise an exception if this is not available! m_matrix = indexer.get_indexer_payload('mosflm_orientation_matrix') # N.B. in the calculation below I am using the Cambridge frame # and Mosflm definitions of X & Y... m_elems = [] for record in m_matrix[:3]: record = record.replace('-', ' -') for e in map(float, record.split()): m_elems.append(e / wavelength) mi = matrix.sqr(m_elems) m = mi.inverse() A = matrix.col(m.elems[0:3]) B = matrix.col(m.elems[3:6]) C = matrix.col(m.elems[6:9]) # now select the images - start with the images that the indexer # used for indexing, though can interrogate the FrameProcessor # interface of the indexer to put together a completely different # list if I like... images = [] for i in indexer.get_indexer_images(): for j in i: if not j in images: images.append(j) images.sort() # now construct the reciprocal-space peak list n.b. should # really run this in parallel... spots_r = [] spots_r_j = {} for i in images: image = indexer.get_image_name(i) dd = Diffdump() dd.set_image(image) header = dd.readheader() phi = header['phi_start'] + 0.5 * header['phi_width'] pixel = header['pixel'] wavelength = header['wavelength'] peaks = locate_maxima(image) spots_r_j[i] = [] for p in peaks: x, y, isigma = p if isigma < 5.0: continue xp = pixel[0] * y - beam[0] yp = pixel[1] * x - beam[1] scale = wavelength * math.sqrt(xp * xp + yp * yp + distance * distance) X = distance / scale X -= 1.0 / wavelength Y = -xp / scale Z = yp / scale S = matrix.col([X, Y, Z]) rtod = 180.0 / math.pi spots_r.append(S.rotate(axis, -phi / rtod)) spots_r_j[i].append(S.rotate(axis, -phi / rtod)) # now reindex the reciprocal space spot list and count - n.b. need # to transform the Bravais lattice to an assumed spacegroup and hence # to a cctbx spacegroup! # lists = [spots_r_j[j] for j in spots_r_j] lists = [] lists.append(spots_r) for l in lists: absent = 0 present = 0 total = 0 for spot in l: hkl = (m * spot).elems total += 1 ihkl = map(nint, hkl) if math.fabs(hkl[0] - ihkl[0]) > 0.1: continue if math.fabs(hkl[1] - ihkl[1]) > 0.1: continue if math.fabs(hkl[2] - ihkl[2]) > 0.1: continue # now determine if it is absent if sg.is_sys_absent(ihkl): absent += 1 else: present += 1 # now perform the analysis on these numbers... sd = math.sqrt(absent) if total: Debug.write('Counts: %d %d %d %.3f' % \ (total, present, absent, (absent - 3 * sd) / total)) else: Debug.write('Not enough spots found for analysis') return False, None, None, None if (absent - 3 * sd) / total < 0.008: return False, None, None, None # in here need to calculate the new orientation matrix for the # primitive basis and reconfigure the indexer - somehow... # ok, so the bases are fine, but what I will want to do is reorder them # to give the best primitive choice of unit cell... sgp = sg.build_derived_group(True, False) lattice_p = s2l(sgp.type().number()) symm = crystal.symmetry(unit_cell=cell, space_group=sgp) rdx = symm.change_of_basis_op_to_best_cell() symm_new = symm.change_basis(rdx) # now apply this to the reciprocal-space orientation matrix mi # cb_op = sgtbx.change_of_basis_op(rdx) cb_op = rdx R = cb_op.c_inv().r().as_rational().as_float().transpose().inverse() mi_r = mi * R # now re-derive the cell constants, just to be sure m_r = mi_r.inverse() Ar = matrix.col(m_r.elems[0:3]) Br = matrix.col(m_r.elems[3:6]) Cr = matrix.col(m_r.elems[6:9]) a = math.sqrt(Ar.dot()) b = math.sqrt(Br.dot()) c = math.sqrt(Cr.dot()) rtod = 180.0 / math.pi alpha = rtod * Br.angle(Cr) beta = rtod * Cr.angle(Ar) gamma = rtod * Ar.angle(Br) # print '%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f' % \ # (a, b, c, alpha, beta, gamma) cell = uctbx.unit_cell((a, b, c, alpha, beta, gamma)) amat = [wavelength * e for e in mi_r.elems] bmat = matrix.sqr(cell.fractionalization_matrix()) umat = mi_r * bmat.inverse() # yuk! surely I don't need to do this... # I do need to do this, and don't call me shirley! new_matrix = ['%s\n' % r for r in \ format_matrix((a, b, c, alpha, beta, gamma), amat, umat.elems).split('\n')] # ok - this gives back the right matrix in the right setting - excellent! # now need to apply this back at base to the results of the indexer. # N.B. same should be applied to the same calculations for the XDS # version of this. return True, lattice_p, new_matrix, (a, b, c, alpha, beta, gamma)
def gain(image): '''Get the gain from an image.''' dd = Diffdump() dd.set_image(image) return dd.gain()