def test_lauegroup_to_lattice_functions(ccp4): from xia2.lib.SymmetryLib import lauegroup_to_lattice assert lauegroup_to_lattice("I m m m") == "oI" assert lauegroup_to_lattice("C 1 2/m 1") == "mC" assert lauegroup_to_lattice("P -1") == "aP" assert lauegroup_to_lattice("P 4/mmm") == "tP"
def _scale_setup(self): '''Set things up for scaling, in particular mediate pointgroup / lattice with the indexers.''' assert (self._scalr_integraters) epochs = sorted(self._scalr_integraters) integraters = [self._scalr_integraters[e] for e in epochs] pointgroups = [self._scale_setup_integrater(i) for i in integraters] lattices = [lauegroup_to_lattice(p) for p in pointgroups] unique_lattices = list(set(lattices)) # consider the situation that they arrived at more than one conclusion if len(unique_lattices) > 1: consensus_lattice = sort_lattices(unique_lattices)[0] for integrater in integraters: refiner = integrater.get_integrater_refiner() state = refiner.set_refiner_asserted_lattice(consensus_lattice) assert (state != refiner.LATTICE_IMPOSSIBLE) # then decide on the consensus pointgroup pointgroups = set([]) for integrater in integraters: pointgroups = self._scale_list_likely_pointgroups(integrater) lattices = [lauegroup_to_lattice(p) for p in pointgroups] poingroups.add(pointgroups[lattices.index(consensus_lattice)]) # FIXME will need to handle twinned cases more gracefully sometime # FIXME also need to "mend" the integrater set spacegroup API assert (len(pointgroups) == 1) for integrater in integraters: integrater.set_integrater_spacegroup_number(pointgroup) # now reindex to the correct setting reference = integraters[0] for integrater in integraters[1:]: self._scale_reindex_to_reference(reference, integrater) return pointgroups[0]
def _scale_setup(self): '''Set things up for scaling, in particular mediate pointgroup / lattice with the indexers.''' assert(self._scalr_integraters) epochs = sorted(self._scalr_integraters) integraters = [self._scalr_integraters[e] for e in epochs] pointgroups = [self._scale_setup_integrater(i) for i in integraters] lattices = [lauegroup_to_lattice(p) for p in pointgroups] unique_lattices = list(set(lattices)) # consider the situation that they arrived at more than one conclusion if len(unique_lattices) > 1: consensus_lattice = sort_lattices(unique_lattices)[0] for integrater in integraters: refiner = integrater.get_integrater_refiner() state = refiner.set_refiner_asserted_lattice(consensus_lattice) assert(state != refiner.LATTICE_IMPOSSIBLE) # then decide on the consensus pointgroup pointgroups = set([]) for integrater in integraters: pointgroups = self._scale_list_likely_pointgroups(integrater) lattices = [lauegroup_to_lattice(p) for p in pointgroups] poingroups.add(pointgroups[lattices.index(consensus_lattice)]) # FIXME will need to handle twinned cases more gracefully sometime # FIXME also need to "mend" the integrater set spacegroup API assert(len(pointgroups) == 1) for integrater in integraters: integrater.set_integrater_spacegroup_number(pointgroup) # now reindex to the correct setting reference = integraters[0] for integrater in integraters[1:]: self._scale_reindex_to_reference(reference, integrater) return pointgroups[0]
def _scale_setup_integrater(self, integrater): '''Check that the pointgroup for a data set is consistent with the lattice used for integration, then determine the pointgroup for the data.''' # FIXME will have to handle gracefully user provided pointgroup pointgroups = self._scale_list_likely_pointgroups(integrater) refiner = integrater.get_integrater_refiner() lattices = [lauegroup_to_lattice(p) for p in pointgroups] correct_lattice = None for lattice in lattices: state = refiner.set_refiner_asserted_lattice(lattice) if state == refiner.LATTICE_CORRECT: correct_lattice = lattice break elif state == refiner.LATTICE_IMPOSSIBLE: continue elif state == refiner.LATTICE_POSSIBLE: correct_lattice = lattice break assert (correct_lattice) # run this analysis again, which may respond in different conclusions # if it triggers the reprocessing of the data with a new lattice pointgroups = self._scale_list_likely_pointgroups(integrater) lattices = [lauegroup_to_lattice(p) for p in pointgroups] return pointgroups[lattices.index(correct_lattice)]
def _scale_setup_integrater(self, integrater): '''Check that the pointgroup for a data set is consistent with the lattice used for integration, then determine the pointgroup for the data.''' # FIXME will have to handle gracefully user provided pointgroup pointgroups = self._scale_list_likely_pointgroups(integrater) refiner = integrater.get_integrater_refiner() lattices = [lauegroup_to_lattice(p) for p in pointgroups] correct_lattice = None for lattice in lattices: state = refiner.set_refiner_asserted_lattice(lattice) if state == refiner.LATTICE_CORRECT: correct_lattice = lattice break elif state == refiner.LATTICE_IMPOSSIBLE: continue elif state == refiner.LATTICE_POSSIBLE: correct_lattice = lattice break assert(correct_lattice) # run this analysis again, which may respond in different conclusions # if it triggers the reprocessing of the data with a new lattice pointgroups = self._scale_list_likely_pointgroups(integrater) lattices = [lauegroup_to_lattice(p) for p in pointgroups] return pointgroups[lattices.index(correct_lattice)]
'LaueGroupName')[0].childNodes[0].data reindex = s.getElementsByTagName( 'ReindexOperator')[0].childNodes[0].data netzc = float(s.getElementsByTagName( 'NetZCC')[0].childNodes[0].data) likelihood = float(s.getElementsByTagName( 'Likelihood')[0].childNodes[0].data) r_merge = float(s.getElementsByTagName( 'R')[0].childNodes[0].data) delta = float(s.getElementsByTagName( 'CellDelta')[0].childNodes[0].data) # record this as a possible lattice... if it's Z score # is positive, anyway lattice = lauegroup_to_lattice(lauegroup) if not lattice in self._possible_lattices: if netzc > 0.0: self._possible_lattices.append(lattice) # do we not always want to have access to the # solutions, even if they are unlikely - this will # only be invoked if they are known to # be right... self._lattice_to_laue[lattice] = lauegroup return 'ok' def decide_spacegroup(self): '''Given data indexed in the correct pointgroup, have a
def generate(self): if not self._initial_cell: raise RuntimeError, 'must set the cell' if not self._initial_lattice_type: raise RuntimeError, 'must set the lattice' self.start() self.input('%f %f %f %f %f %f' % tuple(self._initial_cell)) self.input('%s' % self._initial_lattice_type) self.input('') self.close_wait() # parse the output of the program... for o in self.get_all_output(): if not '[' in o: continue if 'Reindex op' in o: continue if 'Same cell' in o: continue if 'Other cell' in o: continue if 'within angular tolerance' in o: continue lauegroup = o[:11].strip() if not lauegroup: continue if lauegroup[0] == '[': continue modded_lauegroup = '' for token in lauegroup.split(): if token == '1': continue modded_lauegroup += token try: lattice = lauegroup_to_lattice(modded_lauegroup) except KeyError, e: # there was some kind of mess made of the othercell # output - this happens! continue cell = tuple(map(float, o[11:45].split())) distortion = float(o.split()[-2]) operator = o.split()[-1][1:-1] if not lattice in self._lattices: self._lattices.append(lattice) self._distortions[lattice] = distortion self._cells[lattice] = cell self._reindex_ops[lattice] = operator else: if distortion > self._distortions[lattice]: continue self._distortions[lattice] = distortion self._cells[lattice] = cell self._reindex_ops[lattice] = operator
def generate(self): if not self._cell: raise RuntimeError('no unit cell specified') if not self._spacegroup: raise RuntimeError('no spacegroup specified') self.add_command_line('--unit_cell=%f,%f,%f,%f,%f,%f' % \ tuple(self._cell)) self.add_command_line('--space_group=%s' % self._spacegroup) self.start() self.close_wait() # now wade through all of the options and see which comes # out best for each lattice class... - as defined by the # minimum value of Maximal angular difference state = { } for o in self.get_all_output(): # print o[:-1] if ':' in o: count = o.find(':') left = o[:count] right = o[count + 1:] state[left.strip()] = right.strip() if 'Maximal angular difference' in o: # transform & digest results distortion = float(state[ 'Maximal angular difference'].split()[0]) # this appears to be getting the wrong cell - I want the # one which corresponds to the correct lattice, yes?! # cell = map(float, state[ # 'Symmetry-adapted cell'].replace( # '(', ' ').replace(')', ' ').replace(',', ' ').split()) cell = map(float, state[ 'Unit cell'].replace( '(', ' ').replace(')', ' ').replace(',', ' ').split()) lauegroup = '' # FIXME for more recent versions of cctbx the conventional # setting I 1 2/m 1 has appeared -> look at the # 'Symmetry in minimum-lengths cell' instead (equivalent # to changing lkey here to 'Conventional setting' # # No, can't do this because this now reports the Hall # symmetry not the Laue group. Will have to cope with # the I setting instead :o( lkey = 'Symmetry in minimum-lengths cell' for token in state[lkey].split('(')[0].split(): if token == '1': continue lauegroup += token # FIXME bug 3157 - there appears to be a bug in # recent versions of cctbx (cf. above) which means # a lauegroup of 'R-3m:R' is given -> correct this # in the string. Also :h as well :o( lauegroup = lauegroup.replace(':R', ':H') lauegroup = lauegroup.replace(':h', ':H') lattice = lauegroup_to_lattice(lauegroup) reindex_basis = state['Change of basis'] reindex = state['Inverse'] if not lattice in self._lattices: self._lattices.append(lattice) self._distortions[lattice] = distortion self._cells[lattice] = cell self._reindex_ops[lattice] = reindex self._reindex_ops_basis[lattice] = reindex_basis elif distortion < self._distortions[lattice]: self._distortions[lattice] = distortion self._cells[lattice] = cell self._reindex_ops[lattice] = reindex self._reindex_ops_basis[lattice] = reindex_basis state = { } return
def decide_pointgroup(self, ignore_errors=False, batches=None): """Decide on the correct pointgroup for hklin.""" if not self._xdsin: self.check_hklin() self.set_task( "Computing the correct pointgroup for %s" % self.get_hklin() ) else: Debug.write("Pointless using XDS input file %s" % self._xdsin) self.set_task( "Computing the correct pointgroup for %s" % self.get_xdsin() ) # FIXME this should probably be a standard CCP4 keyword if self._xdsin: self.add_command_line("xdsin") self.add_command_line(self._xdsin) self.add_command_line("xmlout") self.add_command_line("%d_pointless.xml" % self.get_xpid()) if self._hklref: self.add_command_line("hklref") self.add_command_line(self._hklref) self.start() if self._allow_out_of_sequence_files: self.input("allow outofsequencefiles") # https://github.com/xia2/xia2/issues/125 pass in run limits for this # HKLIN file - prevents automated RUN determination from causing errors if batches: self.input("run 1 batch %d to %d" % tuple(batches)) self.input("systematicabsences off") self.input("setting symmetry-based") if self._hklref: dev = PhilIndex.params.xia2.settings.developmental if dev.pointless_tolerance > 0.0: self.input("tolerance %f" % dev.pointless_tolerance) # may expect more %age variation for small molecule data if PhilIndex.params.xia2.settings.small_molecule: if self._hklref: self.input("tolerance 5.0") if PhilIndex.params.xia2.settings.symmetry.chirality is not None: self.input( "chirality %s" % PhilIndex.params.xia2.settings.symmetry.chirality ) if self._input_laue_group: self.input("lauegroup %s" % self._input_laue_group) self.close_wait() # check for errors self.check_for_errors() # check for fatal errors output = self.get_all_output() fatal_error = False for j, record in enumerate(output): if "FATAL ERROR message:" in record: if ignore_errors: fatal_error = True else: raise RuntimeError( "Pointless error: %s" % output[j + 1].strip() ) if ( "Resolution range of Reference data and observed data do not" in record and ignore_errors ): fatal_error = True if "All reflection pairs rejected" in record and ignore_errors: fatal_error = True if ( "Reference data and observed data do not overlap" in record and ignore_errors ): fatal_error = True hklin_spacegroup = "" # split loop - first seek hklin symmetry then later look for everything # else for o in self.get_all_output(): if "Spacegroup from HKLIN file" in o: hklin_spacegroup = spacegroup_name_xHM_to_old( o.replace("Spacegroup from HKLIN file :", "").strip() ) if "Space group from HKLREF file" in o: hklref_spacegroup = spacegroup_name_xHM_to_old( o.replace("Space group from HKLREF file :", "").strip() ) # https://github.com/xia2/xia2/issues/115 if fatal_error: assert hklref_spacegroup self._pointgroup = hklref_spacegroup self._confidence = 1.0 self._totalprob = 1.0 self._reindex_matrix = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] self._reindex_operator = "h,k,l" return "ok" for o in self.get_all_output(): if "No alternative indexing possible" in o: # then the XML file will be broken - no worries... self._pointgroup = hklin_spacegroup self._confidence = 1.0 self._totalprob = 1.0 self._reindex_matrix = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] self._reindex_operator = "h,k,l" return "ok" if "**** Incompatible symmetries ****" in o: raise RuntimeError( "reindexing against a reference with different symmetry" ) if "***** Stopping because cell discrepancy between files" in o: raise RuntimeError("incompatible unit cells between data sets") if "L-test suggests that the data may be twinned" in o: self._probably_twinned = True # parse the XML file for the information I need... xml_file = os.path.join( self.get_working_directory(), "%d_pointless.xml" % self.get_xpid() ) mend_pointless_xml(xml_file) # catch the case sometimes on ppc mac where pointless adds # an extra .xml on the end... if not os.path.exists(xml_file) and os.path.exists("%s.xml" % xml_file): xml_file = "%s.xml" % xml_file if not self._hklref: dom = xml.dom.minidom.parse(xml_file) try: best = dom.getElementsByTagName("BestSolution")[0] except IndexError: raise RuntimeError("error getting solution from pointless") self._pointgroup = ( best.getElementsByTagName("GroupName")[0].childNodes[0].data ) self._confidence = float( best.getElementsByTagName("Confidence")[0].childNodes[0].data ) self._totalprob = float( best.getElementsByTagName("TotalProb")[0].childNodes[0].data ) self._reindex_matrix = map( float, best.getElementsByTagName("ReindexMatrix")[0] .childNodes[0] .data.split(), ) self._reindex_operator = clean_reindex_operator( best.getElementsByTagName("ReindexOperator")[0] .childNodes[0] .data.strip() ) else: # if we have provided a HKLREF input then the xml output # is changed... # FIXME in here, need to check if there is the legend # "No possible alternative indexing" in the standard # output, as this will mean that the index scores are # not there... c/f oppf1314, with latest pointless build # 1.2.14. dom = xml.dom.minidom.parse(xml_file) try: best = dom.getElementsByTagName("IndexScores")[0] except IndexError: Debug.write("Reindex not found in xml output") # check for this legend then found = False for record in self.get_all_output(): if "No possible alternative indexing" in record: found = True if not found: raise RuntimeError("error finding solution") best = None hklref_pointgroup = "" # FIXME need to get this from the reflection file HKLREF reflection_file_elements = dom.getElementsByTagName("ReflectionFile") for rf in reflection_file_elements: stream = rf.getAttribute("stream") if stream == "HKLREF": hklref_pointgroup = ( rf.getElementsByTagName("SpacegroupName")[0] .childNodes[0] .data.strip() ) # Chatter.write('HKLREF pointgroup is %s' % \ # hklref_pointgroup) if hklref_pointgroup == "": raise RuntimeError("error finding HKLREF pointgroup") self._pointgroup = hklref_pointgroup self._confidence = 1.0 self._totalprob = 1.0 if best: index = best.getElementsByTagName("Index")[0] self._reindex_matrix = map( float, index.getElementsByTagName("ReindexMatrix")[0] .childNodes[0] .data.split(), ) self._reindex_operator = clean_reindex_operator( index.getElementsByTagName("ReindexOperator")[0] .childNodes[0] .data.strip() ) else: # no alternative indexing is possible so just # assume the default... self._reindex_matrix = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] self._reindex_operator = "h,k,l" if not self._input_laue_group and not self._hklref: scorelist = dom.getElementsByTagName("LaueGroupScoreList")[0] scores = scorelist.getElementsByTagName("LaueGroupScore") for s in scores: lauegroup = ( s.getElementsByTagName("LaueGroupName")[0].childNodes[0].data ) netzc = float( s.getElementsByTagName("NetZCC")[0].childNodes[0].data ) # record this as a possible lattice if its Z score is positive lattice = lauegroup_to_lattice(lauegroup) if not lattice in self._possible_lattices: if netzc > 0.0: self._possible_lattices.append(lattice) # do we not always want to have access to the # solutions, even if they are unlikely - this will # only be invoked if they are known to # be right... self._lattice_to_laue[lattice] = lauegroup return "ok"
def generate(self): if not self._initial_cell: raise RuntimeError('must set the cell') if not self._initial_lattice_type: raise RuntimeError('must set the lattice') self.start() self.input('%f %f %f %f %f %f' % tuple(self._initial_cell)) self.input('%s' % self._initial_lattice_type) self.input('') self.close_wait() # parse the output of the program... for o in self.get_all_output(): if not '[' in o: continue if 'Reindex op' in o: continue if 'Same cell' in o: continue if 'Other cell' in o: continue if 'within angular tolerance' in o: continue lauegroup = o[:11].strip() if not lauegroup: continue if lauegroup[0] == '[': continue modded_lauegroup = '' for token in lauegroup.split(): if token == '1': continue modded_lauegroup += token try: lattice = lauegroup_to_lattice(modded_lauegroup) except KeyError: # there was some kind of mess made of the othercell # output - this happens! continue cell = tuple(map(float, o[11:45].split())) distortion = float(o.split()[-2]) operator = o.split()[-1][1:-1] if not lattice in self._lattices: self._lattices.append(lattice) self._distortions[lattice] = distortion self._cells[lattice] = cell self._reindex_ops[lattice] = operator else: if distortion > self._distortions[lattice]: continue self._distortions[lattice] = distortion self._cells[lattice] = cell self._reindex_ops[lattice] = operator
def test_lauegroup_to_lattice_functions(ccp4): from xia2.lib.SymmetryLib import lauegroup_to_lattice assert lauegroup_to_lattice('I m m m') == 'oI' assert lauegroup_to_lattice('C 1 2/m 1') == 'mC' assert lauegroup_to_lattice('P -1') == 'aP' assert lauegroup_to_lattice('P 4/mmm') == 'tP'
def generate(self): if not self._cell: raise RuntimeError, 'no unit cell specified' if not self._spacegroup: raise RuntimeError, 'no spacegroup specified' self.add_command_line('--unit_cell=%f,%f,%f,%f,%f,%f' % \ tuple(self._cell)) self.add_command_line('--space_group=%s' % self._spacegroup) self.start() self.close_wait() # now wade through all of the options and see which comes # out best for each lattice class... - as defined by the # minimum value of Maximal angular difference state = { } for o in self.get_all_output(): # print o[:-1] if ':' in o: count = o.find(':') left = o[:count] right = o[count + 1:] state[left.strip()] = right.strip() if 'Maximal angular difference' in o: # transform & digest results distortion = float(state[ 'Maximal angular difference'].split()[0]) # this appears to be getting the wrong cell - I want the # one which corresponds to the correct lattice, yes?! # cell = map(float, state[ # 'Symmetry-adapted cell'].replace( # '(', ' ').replace(')', ' ').replace(',', ' ').split()) cell = map(float, state[ 'Unit cell'].replace( '(', ' ').replace(')', ' ').replace(',', ' ').split()) lauegroup = '' # FIXME for more recent versions of cctbx the conventional # setting I 1 2/m 1 has appeared -> look at the # 'Symmetry in minimum-lengths cell' instead (equivalent # to changing lkey here to 'Conventional setting' # # No, can't do this because this now reports the Hall # symmetry not the Laue group. Will have to cope with # the I setting instead :o( lkey = 'Symmetry in minimum-lengths cell' for token in state[lkey].split('(')[0].split(): if token == '1': continue lauegroup += token # FIXME bug 3157 - there appears to be a bug in # recent versions of cctbx (cf. above) which means # a lauegroup of 'R-3m:R' is given -> correct this # in the string. Also :h as well :o( lauegroup = lauegroup.replace(':R', ':H') lauegroup = lauegroup.replace(':h', ':H') lattice = lauegroup_to_lattice(lauegroup) reindex_basis = state['Change of basis'] reindex = state['Inverse'] if not lattice in self._lattices: self._lattices.append(lattice) self._distortions[lattice] = distortion self._cells[lattice] = cell self._reindex_ops[lattice] = reindex self._reindex_ops_basis[lattice] = reindex_basis elif distortion < self._distortions[lattice]: self._distortions[lattice] = distortion self._cells[lattice] = cell self._reindex_ops[lattice] = reindex self._reindex_ops_basis[lattice] = reindex_basis state = { } return
def decide_pointgroup(self, ignore_errors=False, batches=None): '''Decide on the correct pointgroup for hklin.''' if not self._xdsin: self.check_hklin() self.set_task('Computing the correct pointgroup for %s' % \ self.get_hklin()) else: Debug.write('Pointless using XDS input file %s' % \ self._xdsin) self.set_task('Computing the correct pointgroup for %s' % \ self.get_xdsin()) # FIXME this should probably be a standard CCP4 keyword if self._xdsin: self.add_command_line('xdsin') self.add_command_line(self._xdsin) self.add_command_line('xmlout') self.add_command_line('%d_pointless.xml' % self.get_xpid()) if self._hklref: self.add_command_line('hklref') self.add_command_line(self._hklref) self.start() if self._allow_out_of_sequence_files: self.input('allow outofsequencefiles') # https://github.com/xia2/xia2/issues/125 pass in run limits for this # HKLIN file - prevents automated RUN determination from causing errors if batches: self.input('run 1 batch %d to %d' % tuple(batches)) self.input('systematicabsences off') self.input('setting symmetry-based') if self._hklref: dev = PhilIndex.params.xia2.settings.developmental if dev.pointless_tolerance > 0.0: self.input('tolerance %f' % dev.pointless_tolerance) # may expect more %age variation for small molecule data if PhilIndex.params.xia2.settings.small_molecule == True: if self._hklref: self.input('tolerance 5.0') if PhilIndex.params.ccp4.pointless.chirality is not None: self.input('chirality %s' %PhilIndex.params.ccp4.pointless.chirality) if self._input_laue_group: self.input('lauegroup %s' % self._input_laue_group) self.close_wait() # check for errors self.check_for_errors() # check for fatal errors output = self.get_all_output() fatal_error = False for j, record in enumerate(output): if 'FATAL ERROR message:' in record: if ignore_errors: fatal_error = True else: raise RuntimeError('Pointless error: %s' % output[j+1].strip()) if 'Resolution range of Reference data and observed data do not' \ in record and ignore_errors: fatal_error = True if 'All reflection pairs rejected' in record and ignore_errors: fatal_error = True if 'Reference data and observed data do not overlap' in record and \ ignore_errors: fatal_error = True hklin_spacegroup = '' hklin_lattice = '' # split loop - first seek hklin symmetry then later look for everything # else for o in self.get_all_output(): if 'Spacegroup from HKLIN file' in o: hklin_spacegroup = spacegroup_name_xHM_to_old( o.replace( 'Spacegroup from HKLIN file :', '').strip()) hklin_lattice = Syminfo.get_lattice(hklin_spacegroup) if 'Space group from HKLREF file' in o: hklref_spacegroup = spacegroup_name_xHM_to_old( o.replace( 'Space group from HKLREF file :', '').strip()) hklref_lattice = Syminfo.get_lattice(hklref_spacegroup) # https://github.com/xia2/xia2/issues/115 if fatal_error: assert hklref_spacegroup self._pointgroup = hklref_spacegroup self._confidence = 1.0 self._totalprob = 1.0 self._reindex_matrix = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] self._reindex_operator = 'h,k,l' return 'ok' for o in self.get_all_output(): if 'No alternative indexing possible' in o: # then the XML file will be broken - no worries... self._pointgroup = hklin_spacegroup self._confidence = 1.0 self._totalprob = 1.0 self._reindex_matrix = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] self._reindex_operator = 'h,k,l' return 'ok' if '**** Incompatible symmetries ****' in o: raise RuntimeError( \ 'reindexing against a reference with different symmetry') if '***** Stopping because cell discrepancy between files' in o: raise RuntimeError('incompatible unit cells between data sets') if 'L-test suggests that the data may be twinned' in o: self._probably_twinned = True # parse the XML file for the information I need... xml_file = os.path.join(self.get_working_directory(), '%d_pointless.xml' % self.get_xpid()) mend_pointless_xml(xml_file) # catch the case sometimes on ppc mac where pointless adds # an extra .xml on the end... if not os.path.exists(xml_file) and \ os.path.exists('%s.xml' % xml_file): xml_file = '%s.xml' % xml_file if not self._hklref: dom = xml.dom.minidom.parse(xml_file) try: best = dom.getElementsByTagName('BestSolution')[0] except IndexError: raise RuntimeError('error getting solution from pointless') self._pointgroup = best.getElementsByTagName( 'GroupName')[0].childNodes[0].data self._confidence = float(best.getElementsByTagName( 'Confidence')[0].childNodes[0].data) self._totalprob = float(best.getElementsByTagName( 'TotalProb')[0].childNodes[0].data) self._reindex_matrix = map(float, best.getElementsByTagName( 'ReindexMatrix')[0].childNodes[0].data.split()) self._reindex_operator = clean_reindex_operator( best.getElementsByTagName( 'ReindexOperator')[0].childNodes[0].data.strip()) else: # if we have provided a HKLREF input then the xml output # is changed... # FIXME in here, need to check if there is the legend # "No possible alternative indexing" in the standard # output, as this will mean that the index scores are # not there... c/f oppf1314, with latest pointless build # 1.2.14. dom = xml.dom.minidom.parse(xml_file) try: best = dom.getElementsByTagName('IndexScores')[0] except IndexError: Debug.write('Reindex not found in xml output') # check for this legend then found = False for record in self.get_all_output(): if 'No possible alternative indexing' in record: found = True if not found: raise RuntimeError('error finding solution') best = None hklref_pointgroup = '' # FIXME need to get this from the reflection file HKLREF reflection_file_elements = dom.getElementsByTagName( 'ReflectionFile') for rf in reflection_file_elements: stream = rf.getAttribute('stream') if stream == 'HKLREF': hklref_pointgroup = rf.getElementsByTagName( 'SpacegroupName')[0].childNodes[0].data.strip() # Chatter.write('HKLREF pointgroup is %s' % \ # hklref_pointgroup) if hklref_pointgroup == '': raise RuntimeError('error finding HKLREF pointgroup') self._pointgroup = hklref_pointgroup self._confidence = 1.0 self._totalprob = 1.0 if best: index = best.getElementsByTagName('Index')[0] self._reindex_matrix = map(float, index.getElementsByTagName( 'ReindexMatrix')[0].childNodes[0].data.split()) self._reindex_operator = clean_reindex_operator( index.getElementsByTagName( 'ReindexOperator')[0].childNodes[0].data.strip()) else: # no alternative indexing is possible so just # assume the default... self._reindex_matrix = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] self._reindex_operator = 'h,k,l' if not self._input_laue_group and not self._hklref: scorelist = dom.getElementsByTagName('LaueGroupScoreList')[0] scores = scorelist.getElementsByTagName('LaueGroupScore') lauegroups = { } netzcs = { } likelihoods = { } for s in scores: number = int(s.getElementsByTagName( 'number')[0].childNodes[0].data) lauegroup = s.getElementsByTagName( 'LaueGroupName')[0].childNodes[0].data reindex = s.getElementsByTagName( 'ReindexOperator')[0].childNodes[0].data netzc = float(s.getElementsByTagName( 'NetZCC')[0].childNodes[0].data) likelihood = float(s.getElementsByTagName( 'Likelihood')[0].childNodes[0].data) r_merge = float(s.getElementsByTagName( 'R')[0].childNodes[0].data) delta = float(s.getElementsByTagName( 'CellDelta')[0].childNodes[0].data) # record this as a possible lattice... if it's Z score # is positive, anyway lattice = lauegroup_to_lattice(lauegroup) if not lattice in self._possible_lattices: if netzc > 0.0: self._possible_lattices.append(lattice) # do we not always want to have access to the # solutions, even if they are unlikely - this will # only be invoked if they are known to # be right... self._lattice_to_laue[lattice] = lauegroup return 'ok'