示例#1
0
    def build_groups(self,
                     mpsnl,
                     force_new=False,
                     snlgroup_guess=None,
                     testing_mode=False):
        # testing mode is used to see if something already exists in DB w/o adding it to the db

        match_found = False
        if not force_new:
            if snlgroup_guess:
                sgp = self.snlgroups.find_one({'snlgroup_id': snlgroup_guess})
                snlgroup = SNLGroup.from_dict(sgp)
                match_found = self._add_if_belongs(snlgroup, mpsnl,
                                                   testing_mode)

            if not match_found:
                # look at all potential matches
                for entry in self.snlgroups.find(
                    {'snlgroup_key': mpsnl.snlgroup_key},
                        sort=[("num_snl", DESCENDING)]):
                    snlgroup = SNLGroup.from_dict(entry)
                    match_found = self._add_if_belongs(snlgroup, mpsnl,
                                                       testing_mode)
                    if match_found:
                        break

        if not match_found:
            # add a new SNLGroup
            snlgroup_id = self._get_next_snlgroup_id()
            snlgroup = SNLGroup(snlgroup_id, mpsnl)
            if not testing_mode:
                self.snlgroups.insert(snlgroup.to_dict)

        return snlgroup, not match_found
示例#2
0
    def build_groups(self, mpsnl, force_new=False, snlgroup_guess=None, testing_mode=False):
        # testing mode is used to see if something already exists in DB w/o adding it to the db

        match_found = False
        if not force_new:
            if snlgroup_guess:
                sgp = self.snlgroups.find_one({'snlgroup_id': snlgroup_guess})
                snlgroup = SNLGroup.from_dict(sgp)
                match_found, spec_group = self._add_if_belongs(snlgroup, mpsnl, testing_mode)

            if not match_found:
                # look at all potential matches
                for entry in self.snlgroups.find({'snlgroup_key': mpsnl.snlgroup_key},
                                                 sort=[("num_snl", DESCENDING)]):
                    snlgroup = SNLGroup.from_dict(entry)
                    match_found, spec_group = self._add_if_belongs(snlgroup, mpsnl, testing_mode)
                    if match_found:
                        break

        if not match_found:
            # add a new SNLGroup
            snlgroup_id = self._get_next_snlgroup_id()
            snlgroup = SNLGroup(snlgroup_id, mpsnl)
            spec_group=None
            if snlgroup.species_groups:
                spec_group = snlgroup.species_groups.keys()[0]
            if not testing_mode:
                self.snlgroups.insert(snlgroup.to_dict)

        return snlgroup, not match_found, spec_group
示例#3
0
    def switch_canonical_snl(self, snlgroup_id, canonical_mpsnl):
        sgp = self.snlgroups.find_one({'snlgroup_id': snlgroup_id})
        snlgroup = SNLGroup.from_dict(sgp)

        all_snl_ids = [sid for sid in snlgroup.all_snl_ids]
        if canonical_mpsnl.snl_id not in all_snl_ids:
            raise ValueError('Canonical SNL must already be in snlgroup to switch!')

        new_group = SNLGroup(snlgroup_id, canonical_mpsnl, all_snl_ids)
        self.snlgroups.update({'snlgroup_id': snlgroup_id}, new_group.as_dict())
示例#4
0
    def switch_canonical_snl(self, snlgroup_id, canonical_mpsnl):
        sgp = self.snlgroups.find_one({'snlgroup_id': snlgroup_id})
        snlgroup = SNLGroup.from_dict(sgp)

        all_snl_ids = [sid for sid in snlgroup.all_snl_ids]
        if canonical_mpsnl.snl_id not in all_snl_ids:
            raise ValueError(
                'Canonical SNL must already be in snlgroup to switch!')

        new_group = SNLGroup(snlgroup_id, canonical_mpsnl, all_snl_ids)
        self.snlgroups.update({'snlgroup_id': snlgroup_id}, new_group.to_dict)
示例#5
0
文件: base.py 项目: aykol/MPWorks
 def process_item(self, item, index):
     nrow, ncol = index/self._ncols, index%self._ncols
     snlgroups = {} # keep {snlgroup_id: SNLGroup} to avoid dupe queries
     if isinstance(item, dict) and 'snlgroup_ids' in item:
         for gid in item['snlgroup_ids']:
             try:
                 snlgrp_dict = self._snlgroups.collection.find_one({ "snlgroup_id": gid })
                 snlgroups[gid] = SNLGroup.from_dict(snlgrp_dict)
             except:
                 exc_type, exc_value, exc_traceback = sys.exc_info()
                 _log.info('%r %r', exc_type, exc_value)
                 self._increase_counter(nrow, ncol, {categories[self.checker_name]: [str(gid)]})
     return nrow, ncol, snlgroups
示例#6
0
 def process_item(self, item, index):
     nrow, ncol = index / self._ncols, index % self._ncols
     snlgroups = {}  # keep {snlgroup_id: SNLGroup} to avoid dupe queries
     if isinstance(item, dict) and 'snlgroup_ids' in item:
         for gid in item['snlgroup_ids']:
             try:
                 snlgrp_dict = self._snlgroups.collection.find_one(
                     {"snlgroup_id": gid})
                 snlgroups[gid] = SNLGroup.from_dict(snlgrp_dict)
             except:
                 exc_type, exc_value, exc_traceback = sys.exc_info()
                 _log.info('%r %r', exc_type, exc_value)
                 self._increase_counter(
                     nrow, ncol,
                     {categories[self.checker_name]: [str(gid)]})
     return nrow, ncol, snlgroups
示例#7
0
    def build_groups(self, mpsnl, testing_mode=False):
        # testing mode is used to see if something already exists in DB w/o adding it to the db
        add_new = True

        for entry in self.snlgroups.find({'snlgroup_key': mpsnl.snlgroup_key},
                                         sort=[("num_snl", DESCENDING)]):
            snlgroup = SNLGroup.from_dict(entry)
            if snlgroup.add_if_belongs(mpsnl):
                add_new = False
                print 'MATCH FOUND, grouping (snl_id, snlgroup): {}'.format(
                    (mpsnl.snl_id, snlgroup.snlgroup_id))
                if not testing_mode:
                    self.snlgroups.update({'snlgroup_id': snlgroup.snlgroup_id}, snlgroup.to_dict)
                break

        if add_new:
            # add a new SNLGroup
            snlgroup_id = self._get_next_snlgroup_id()
            snlgroup = SNLGroup(snlgroup_id, mpsnl)
            if not testing_mode:
                self.snlgroups.insert(snlgroup.to_dict)

        return snlgroup, add_new
示例#8
0
def analyze(args):
    """analyze data at any point for a copy of the streaming figure"""
    # NOTE: make copy online first with suffix _%Y-%m-%d and note figure id
    fig = py.get_figure(creds['username'], args.fig_id)
    if args.t:
        if args.fig_id == 42:
            label_entries = filter(
                None, '<br>'.join(fig['data'][2]['text']).split('<br>'))
            pairs = map(make_tuple, label_entries)
            grps = set(chain.from_iterable(pairs))
            snlgrp_cursor = sma.snlgroups.aggregate([{
                '$match': {
                    'snlgroup_id': {
                        '$in': list(grps)
                    },
                    'canonical_snl.about.projects': {
                        '$ne': 'CederDahn Challenge'
                    }
                }
            }, {
                '$project': {
                    'snlgroup_id': 1,
                    'canonical_snl.snlgroup_key': 1,
                    '_id': 0
                }
            }],
                                                    cursor={})
            snlgroup_keys = {}
            for d in snlgrp_cursor:
                snlgroup_keys[
                    d['snlgroup_id']] = d['canonical_snl']['snlgroup_key']
            print snlgroup_keys[40890]
            sma2 = SNLMongoAdapter.from_file(
                os.path.join(os.environ['DB_LOC'], 'materials_db.yaml'))
            materials_cursor = sma2.database.materials.aggregate([{
                '$match': {
                    'snlgroup_id_final': {
                        '$in': list(grps)
                    },
                    'snl_final.about.projects': {
                        '$ne': 'CederDahn Challenge'
                    }
                }
            }, {
                '$project': {
                    'snlgroup_id_final': 1,
                    '_id': 0,
                    'task_id': 1,
                    'final_energy_per_atom': 1,
                    'band_gap.search_gap.band_gap': 1,
                    'volume': 1,
                    'nsites': 1
                }
            }],
                                                                 cursor={})
            snlgroup_data = {}
            for material in materials_cursor:
                snlgroup_id = material['snlgroup_id_final']
                final_energy_per_atom = material['final_energy_per_atom']
                band_gap = material['band_gap']['search_gap']['band_gap']
                volume_per_atom = material['volume'] / material['nsites']
                snlgroup_data[snlgroup_id] = {
                    'final_energy_per_atom': final_energy_per_atom,
                    'band_gap': band_gap,
                    'task_id': material['task_id'],
                    'volume_per_atom': volume_per_atom
                }
            print snlgroup_data[40890]
            filestem = 'mpworks/check_snl/results/bad_snlgroups_2_'
            with open(filestem+'in_matdb.csv', 'wb') as f, \
                    open(filestem+'notin_matdb.csv', 'wb') as g:
                writer1, writer2 = csv.writer(f), csv.writer(g)
                header = [
                    'category', 'composition', 'snlgroup_id 1', 'sg_num 1',
                    'task_id 1', 'snlgroup_id 2', 'sg_num 2', 'task_id 2',
                    'delta_energy', 'delta_bandgap', 'delta_volume_per_atom',
                    'rms_dist', 'scenario'
                ]
                writer1.writerow(header)
                writer2.writerow(header)
                for primary_id, secondary_id in pairs:
                    if primary_id not in snlgroup_keys or \
                       secondary_id not in snlgroup_keys:
                        continue
                    composition, primary_sg_num = snlgroup_keys[
                        primary_id].split('--')
                    secondary_sg_num = snlgroup_keys[secondary_id].split(
                        '--')[1]
                    category = 'same SGs' if primary_sg_num == secondary_sg_num else 'diff. SGs'
                    if primary_id not in snlgroup_data or secondary_id not in snlgroup_data:
                        delta_energy, delta_bandgap, delta_volume_per_atom = '', '', ''
                    else:
                        delta_energy = "{0:.3g}".format(abs(
                            snlgroup_data[primary_id]['final_energy_per_atom'] - \
                            snlgroup_data[secondary_id]['final_energy_per_atom']
                        ))
                        delta_bandgap = "{0:.3g}".format(abs(
                            snlgroup_data[primary_id]['band_gap'] - \
                            snlgroup_data[secondary_id]['band_gap']
                        ))
                        delta_volume_per_atom = "{0:.3g}".format(abs(
                            snlgroup_data[primary_id]['volume_per_atom'] - \
                            snlgroup_data[secondary_id]['volume_per_atom']
                        ))
                    scenario, rms_dist_str = '', ''
                    if category == 'diff. SGs' and delta_energy and delta_bandgap:
                        scenario = 'different' if (
                            float(delta_energy) > 0.01
                            or float(delta_bandgap) > 0.1) else 'similar'
                        snlgrp1_dict = sma.snlgroups.find_one(
                            {"snlgroup_id": primary_id})
                        snlgrp2_dict = sma.snlgroups.find_one(
                            {"snlgroup_id": secondary_id})
                        snlgrp1 = SNLGroup.from_dict(snlgrp1_dict)
                        snlgrp2 = SNLGroup.from_dict(snlgrp2_dict)
                        primary_structure = snlgrp1.canonical_structure
                        secondary_structure = snlgrp2.canonical_structure
                        rms_dist = matcher.get_rms_dist(
                            primary_structure, secondary_structure)
                        if rms_dist is not None:
                            rms_dist_str = "({0:.3g},{1:.3g})".format(
                                *rms_dist)
                            print rms_dist_str
                    row = [
                        category, composition,
                        primary_id, primary_sg_num,
                        snlgroup_data[primary_id]['task_id'] \
                        if primary_id in snlgroup_data else '',
                        secondary_id, secondary_sg_num,
                        snlgroup_data[secondary_id]['task_id'] \
                        if secondary_id in snlgroup_data else '',
                        delta_energy, delta_bandgap, delta_volume_per_atom,
                        rms_dist_str, scenario
                    ]
                    if delta_energy and delta_bandgap: writer1.writerow(row)
                    else: writer2.writerow(row)
        elif args.fig_id == 16:
            out_fig = Figure()
            badsnls_trace = Scatter(x=[],
                                    y=[],
                                    text=[],
                                    mode='markers',
                                    name='SG Changes')
            bisectrix = Scatter(x=[0, 230],
                                y=[0, 230],
                                mode='lines',
                                name='bisectrix')
            print 'pulling bad snls from plotly ...'
            bad_snls = OrderedDict()
            for category, text in zip(fig['data'][2]['y'],
                                      fig['data'][2]['text']):
                for snl_id in map(int, text.split('<br>')):
                    bad_snls[snl_id] = category
            with open('mpworks/check_snl/results/bad_snls.csv', 'wb') as f:
                print 'pulling bad snls from database ...'
                mpsnl_cursor = sma.snl.find({
                    'snl_id': {
                        '$in': bad_snls.keys()
                    },
                    'about.projects': {
                        '$ne': 'CederDahn Challenge'
                    }
                })
                writer = csv.writer(f)
                writer.writerow([
                    'snl_id', 'category', 'snlgroup_key', 'nsites', 'remarks',
                    'projects', 'authors'
                ])
                print 'writing bad snls to file ...'
                for mpsnl_dict in mpsnl_cursor:
                    mpsnl = MPStructureNL.from_dict(mpsnl_dict)
                    row = [
                        mpsnl.snl_id, bad_snls[mpsnl.snl_id],
                        mpsnl.snlgroup_key
                    ]
                    row += _get_snl_extra_info(mpsnl)
                    writer.writerow(row)
                    sg_num = mpsnl.snlgroup_key.split('--')[1]
                    if (bad_snls[mpsnl.snl_id] == 'SG default' and sg_num != '-1') or \
                       bad_snls[mpsnl.snl_id] == 'SG change':
                        mpsnl.structure.remove_oxidation_states()
                        sf = SpacegroupAnalyzer(mpsnl.structure, symprec=0.1)
                        badsnls_trace['x'].append(mpsnl.sg_num)
                        badsnls_trace['y'].append(sf.get_spacegroup_number())
                        badsnls_trace['text'].append(mpsnl.snl_id)
                        if bad_snls[mpsnl.snl_id] == 'SG default':
                            print sg_num, sf.get_spacegroup_number()
                print 'plotting out-fig ...'
                out_fig['data'] = Data([bisectrix, badsnls_trace])
                out_fig['layout'] = Layout(
                    showlegend=False,
                    hovermode='closest',
                    title='Spacegroup Assignment Changes',
                    xaxis=XAxis(showgrid=False,
                                title='old SG number',
                                range=[0, 230]),
                    yaxis=YAxis(showgrid=False,
                                title='new SG number',
                                range=[0, 230]),
                )
                filename = 'spacegroup_changes_'
                filename += datetime.datetime.now().strftime('%Y-%m-%d')
                py.plot(out_fig, filename=filename, auto_open=False)
        elif args.fig_id == 43:  # SNLGroupMemberChecker
            matcher2 = StructureMatcher(ltol=0.2,
                                        stol=0.3,
                                        angle_tol=5,
                                        primitive_cell=False,
                                        scale=True,
                                        attempt_supercell=True,
                                        comparator=ElementComparator())
            print 'pulling data from plotly ...'
            trace = Scatter(x=[],
                            y=[],
                            text=[],
                            mode='markers',
                            name='mismatches')
            bad_snls = OrderedDict()  # snlgroup_id : [ mismatching snl_ids ]
            for category, text in zip(fig['data'][2]['y'],
                                      fig['data'][2]['text']):
                if category != 'mismatch': continue
                for entry in text.split('<br>'):
                    fields = entry.split(':')
                    snlgroup_id = int(fields[0].split(',')[0])
                    print snlgroup_id
                    snlgrp_dict = sma.snlgroups.find_one(
                        {'snlgroup_id': snlgroup_id})
                    snlgrp = SNLGroup.from_dict(snlgrp_dict)
                    s1 = snlgrp.canonical_structure.get_primitive_structure()
                    bad_snls[snlgroup_id] = []
                    for i, snl_id in enumerate(fields[1].split(',')):
                        mpsnl_dict = sma.snl.find_one({'snl_id': int(snl_id)})
                        if 'CederDahn Challenge' in mpsnl_dict['about'][
                                'projects']:
                            print 'skip CederDahn: %s' % snl_id
                            continue
                        mpsnl = MPStructureNL.from_dict(mpsnl_dict)
                        s2 = mpsnl.structure.get_primitive_structure()
                        is_match = matcher2.fit(s1, s2)
                        if is_match: continue
                        bad_snls[snlgroup_id].append(snl_id)
                        trace['x'].append(snlgroup_id)
                        trace['y'].append(i + 1)
                        trace['text'].append(snl_id)
                    if len(bad_snls[snlgroup_id]) < 1:
                        bad_snls.pop(snlgroup_id, None)
            with open('mpworks/check_snl/results/bad_snlgroups.csv',
                      'wb') as f:
                print 'pulling bad snlgroups from database ...'
                snlgroup_cursor = sma.snlgroups.find({
                    'snlgroup_id': {
                        '$in': bad_snls.keys()
                    },
                })
                writer = csv.writer(f)
                writer.writerow(
                    ['snlgroup_id', 'snlgroup_key', 'mismatching snl_ids'])
                print 'writing bad snlgroups to file ...'
                for snlgroup_dict in snlgroup_cursor:
                    snlgroup = SNLGroup.from_dict(snlgroup_dict)
                    row = [
                        snlgroup.snlgroup_id,
                        snlgroup.canonical_snl.snlgroup_key,
                        ' '.join(bad_snls[snlgroup.snlgroup_id])
                    ]
                    writer.writerow(row)
            print 'plotting out-fig ...'
            out_fig = Figure()
            out_fig['data'] = Data([trace])
            out_fig['layout'] = Layout(
                showlegend=False,
                hovermode='closest',
                title='Member Mismatches of SNLGroup Canonicals',
                xaxis=XAxis(showgrid=False,
                            title='snlgroup_id',
                            showexponent='none'),
                yaxis=YAxis(showgrid=False, title='# mismatching SNLs'),
            )
            filename = 'groupmember_mismatches_'
            filename += datetime.datetime.now().strftime('%Y-%m-%d')
            py.plot(out_fig, filename=filename, auto_open=False)
    else:
        errors = Counter()
        bad_snls = OrderedDict()
        bad_snlgroups = OrderedDict()
        for i, d in enumerate(fig['data']):
            if not isinstance(d, Scatter): continue
            if not 'x' in d or not 'y' in d or not 'text' in d: continue
            start_id = int(d['name'].split(' - ')[0][:-1]) * 1000
            marker_colors = d['marker']['color']
            if i < 2 * num_snl_streams:  # spacegroups
                errors += Counter(marker_colors)
                for idx, color in enumerate(marker_colors):
                    snl_id = start_id + d['x'][idx]
                    color_index = category_colors.index(color)
                    category = categories[color_index]
                    bad_snls[snl_id] = category
            else:  # groupmembers
                for idx, color in enumerate(marker_colors):
                    if color != category_colors[0]: continue
                    snlgroup_id = start_id + d['x'][idx]
                    mismatch_snl_id, canonical_snl_id = d['text'][idx].split(
                        ' != ')
                    bad_snlgroups[snlgroup_id] = int(mismatch_snl_id)
        print errors
        fig_data = fig['data'][-1]
        fig_data['x'] = [
            errors[color] for color in fig_data['marker']['color']
        ]
        filename = _get_filename()
        print filename
        #py.plot(fig, filename=filename)
        with open('mpworks/check_snl/results/bad_snls.csv', 'wb') as f:
            mpsnl_cursor = sma.snl.find({'snl_id': {'$in': bad_snls.keys()}})
            writer = csv.writer(f)
            writer.writerow([
                'snl_id', 'category', 'snlgroup_key', 'nsites', 'remarks',
                'projects', 'authors'
            ])
            for mpsnl_dict in mpsnl_cursor:
                mpsnl = MPStructureNL.from_dict(mpsnl_dict)
                row = [
                    mpsnl.snl_id, bad_snls[mpsnl.snl_id], mpsnl.snlgroup_key
                ]
                row += _get_snl_extra_info(mpsnl)
                writer.writerow(row)
        with open('mpworks/check_snl/results/bad_snlgroups.csv', 'wb') as f:
            snlgrp_cursor = sma.snlgroups.find(
                {'snlgroup_id': {
                    '$in': bad_snlgroups.keys()
                }})
            first_mismatch_snls_cursor = sma.snl.find(
                {'snl_id': {
                    '$in': bad_snlgroups.values()
                }})
            first_mismatch_snl_info = OrderedDict()
            for mpsnl_dict in first_mismatch_snls_cursor:
                mpsnl = MPStructureNL.from_dict(mpsnl_dict)
                first_mismatch_snl_info[mpsnl.snl_id] = _get_snl_extra_info(
                    mpsnl)
            writer = csv.writer(f)
            writer.writerow([
                'snlgroup_id', 'snlgroup_key', 'canonical_snl_id',
                'first_mismatching_snl_id', 'nsites', 'remarks', 'projects',
                'authors'
            ])
            for snlgrp_dict in snlgrp_cursor:
                snlgrp = SNLGroup.from_dict(snlgrp_dict)
                first_mismatch_snl_id = bad_snlgroups[snlgrp.snlgroup_id]
                row = [
                    snlgrp.snlgroup_id, snlgrp.canonical_snl.snlgroup_key,
                    snlgrp.canonical_snl.snl_id, first_mismatch_snl_id
                ]
                row += [
                    ' & '.join(pair) if pair[0] != pair[1] else pair[0]
                    for pair in zip(
                        _get_snl_extra_info(snlgrp.canonical_snl),
                        first_mismatch_snl_info[int(first_mismatch_snl_id)])
                ]
                writer.writerow(row)
示例#9
0
def check_snls_in_snlgroups(args):
    """check whether SNLs in each SNLGroup still match resp. canonical SNL"""
    range_index = args.start / num_ids_per_stream
    idxs = [2 * (num_snl_streams + range_index)]
    idxs += [idxs[0] + 1]
    s = [py.Stream(stream_ids[i]) for i in idxs]
    for i in range(len(idxs)):
        s[i].open()
    end = num_snlgroups if args.end > num_snlgroups else args.end
    id_range = {"$gt": args.start, "$lte": end}
    snlgrp_cursor = sma.snlgroups.find({"snlgroup_id": id_range})
    colors = []
    num_good_ids = 0
    for snlgrp_dict in snlgrp_cursor:
        start_time = time.clock()
        try:
            snlgrp = SNLGroup.from_dict(snlgrp_dict)
        except:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            text = ' '.join([str(exc_type), str(exc_value)])
            colors.append(category_colors[-1])  # Others
            data = dict(x=snlgrp_dict['snlgroup_id'] % num_ids_per_stream,
                        y=range_index,
                        text=text,
                        marker=Marker(color=colors))
            s[0].write(data)
            sleep(start_time)
            continue
        if len(snlgrp.all_snl_ids) <= 1:
            num_good_ids += 1
            data = dict(x=[num_good_ids], y=[range_index])
            s[1].write(data)
            sleep(start_time)
            continue
        exc_raised = False
        all_snls_good = True
        for snl_id in snlgrp.all_snl_ids:
            if snl_id == snlgrp.canonical_snl.snl_id: continue
            mpsnl_dict = sma.snl.find_one({"snl_id": snl_id})
            try:
                mpsnl = MPStructureNL.from_dict(mpsnl_dict)
                is_match = matcher.fit(mpsnl.structure,
                                       snlgrp.canonical_structure)
            except:
                exc_type, exc_value, exc_traceback = sys.exc_info()
                exc_raised = True
            if exc_raised or not is_match:  # Scatter (bad)
                if exc_raised:
                    category = 2 if fnmatch(str(exc_type), '*pybtex*') else 3
                    text = ' '.join([str(exc_type), str(exc_value)])
                else:
                    category = 0
                    text = '%d != can:%d' % (mpsnl_dict['snl_id'],
                                             snlgrp.canonical_snl.snl_id)
                colors.append(category_colors[category])
                data = dict(x=snlgrp_dict['snlgroup_id'] % num_ids_per_stream,
                            y=range_index,
                            text=text,
                            marker=Marker(color=colors))
                s[0].write(data)
                all_snls_good = False
                sleep(start_time)
                break
        if all_snls_good:  # Bar (good)
            num_good_ids += 1
            data = dict(x=[num_good_ids], y=[range_index])
            s[1].write(data)
            sleep(start_time)
    for i in range(len(idxs)):
        s[i].close()
示例#10
0
def analyze(args):
    """analyze data at any point for a copy of the streaming figure"""
    # NOTE: make copy online first with suffix _%Y-%m-%d and note figure id
    fig = py.get_figure(creds['username'], args.fig_id)
    if args.t:
        if args.fig_id == 42:
            label_entries = filter(None, '<br>'.join(fig['data'][2]['text']).split('<br>'))
            pairs = map(make_tuple, label_entries)
            grps = set(chain.from_iterable(pairs))
            snlgrp_cursor = sma.snlgroups.aggregate([
                { '$match': {
                    'snlgroup_id': { '$in': list(grps) },
                    'canonical_snl.about.projects': {'$ne': 'CederDahn Challenge'}
                } },
                { '$project': { 'snlgroup_id': 1, 'canonical_snl.snlgroup_key': 1, '_id': 0 } }
            ], cursor={})
            snlgroup_keys = {}
            for d in snlgrp_cursor:
                snlgroup_keys[d['snlgroup_id']] = d['canonical_snl']['snlgroup_key']
            print snlgroup_keys[40890]
            sma2 = SNLMongoAdapter.from_file(
                os.path.join(os.environ['DB_LOC'], 'materials_db.yaml')
            )
            materials_cursor = sma2.database.materials.aggregate([
                { '$match': {
                    'snlgroup_id_final': { '$in': list(grps) },
                    'snl_final.about.projects': {'$ne': 'CederDahn Challenge'}
                } },
                { '$project': {
                    'snlgroup_id_final': 1, '_id': 0, 'task_id': 1,
                    'final_energy_per_atom': 1,
                    'band_gap.search_gap.band_gap': 1,
                    'volume': 1, 'nsites': 1
                }}
            ], cursor={})
            snlgroup_data = {}
            for material in materials_cursor:
                snlgroup_id = material['snlgroup_id_final']
                final_energy_per_atom = material['final_energy_per_atom']
                band_gap = material['band_gap']['search_gap']['band_gap']
                volume_per_atom = material['volume'] / material['nsites']
                snlgroup_data[snlgroup_id] = {
                    'final_energy_per_atom': final_energy_per_atom,
                    'band_gap': band_gap, 'task_id': material['task_id'],
                    'volume_per_atom': volume_per_atom
                }
            print snlgroup_data[40890]
            filestem = 'mpworks/check_snl/results/bad_snlgroups_2_'
            with open(filestem+'in_matdb.csv', 'wb') as f, \
                    open(filestem+'notin_matdb.csv', 'wb') as g:
                writer1, writer2 = csv.writer(f), csv.writer(g)
                header = [
                    'category', 'composition',
                    'snlgroup_id 1', 'sg_num 1', 'task_id 1',
                    'snlgroup_id 2', 'sg_num 2', 'task_id 2',
                    'delta_energy', 'delta_bandgap', 'delta_volume_per_atom',
                    'rms_dist', 'scenario'
                ]
                writer1.writerow(header)
                writer2.writerow(header)
                for primary_id, secondary_id in pairs:
                    if primary_id not in snlgroup_keys or \
                       secondary_id not in snlgroup_keys: continue
                    composition, primary_sg_num = snlgroup_keys[primary_id].split('--')
                    secondary_sg_num = snlgroup_keys[secondary_id].split('--')[1]
                    category = 'same SGs' if primary_sg_num == secondary_sg_num else 'diff. SGs'
                    if primary_id not in snlgroup_data or secondary_id not in snlgroup_data:
                        delta_energy, delta_bandgap, delta_volume_per_atom = '', '', ''
                    else:
                        delta_energy = "{0:.3g}".format(abs(
                            snlgroup_data[primary_id]['final_energy_per_atom'] - \
                            snlgroup_data[secondary_id]['final_energy_per_atom']
                        ))
                        delta_bandgap = "{0:.3g}".format(abs(
                            snlgroup_data[primary_id]['band_gap'] - \
                            snlgroup_data[secondary_id]['band_gap']
                        ))
                        delta_volume_per_atom = "{0:.3g}".format(abs(
                            snlgroup_data[primary_id]['volume_per_atom'] - \
                            snlgroup_data[secondary_id]['volume_per_atom']
                        ))
                    scenario, rms_dist_str = '', ''
                    if category == 'diff. SGs' and delta_energy and delta_bandgap:
                        scenario = 'different' if (
                            float(delta_energy) > 0.01 or float(delta_bandgap) > 0.1
                        ) else 'similar'
                        snlgrp1_dict = sma.snlgroups.find_one({ "snlgroup_id": primary_id })
                        snlgrp2_dict = sma.snlgroups.find_one({ "snlgroup_id": secondary_id })
                        snlgrp1 = SNLGroup.from_dict(snlgrp1_dict)
                        snlgrp2 = SNLGroup.from_dict(snlgrp2_dict)
                        primary_structure = snlgrp1.canonical_structure
                        secondary_structure = snlgrp2.canonical_structure
                        rms_dist = matcher.get_rms_dist(primary_structure, secondary_structure)
                        if rms_dist is not None:
                            rms_dist_str = "({0:.3g},{1:.3g})".format(*rms_dist)
                            print rms_dist_str
                    row = [
                        category, composition,
                        primary_id, primary_sg_num,
                        snlgroup_data[primary_id]['task_id'] \
                        if primary_id in snlgroup_data else '',
                        secondary_id, secondary_sg_num,
                        snlgroup_data[secondary_id]['task_id'] \
                        if secondary_id in snlgroup_data else '',
                        delta_energy, delta_bandgap, delta_volume_per_atom,
                        rms_dist_str, scenario
                    ]
                    if delta_energy and delta_bandgap: writer1.writerow(row)
                    else: writer2.writerow(row)
        elif args.fig_id == 16:
            out_fig = Figure()
            badsnls_trace = Scatter(x=[], y=[], text=[], mode='markers', name='SG Changes')
            bisectrix = Scatter(x=[0,230], y=[0,230], mode='lines', name='bisectrix')
            print 'pulling bad snls from plotly ...'
            bad_snls = OrderedDict()
            for category, text in zip(fig['data'][2]['y'], fig['data'][2]['text']):
                for snl_id in map(int, text.split('<br>')):
                    bad_snls[snl_id] = category
            with open('mpworks/check_snl/results/bad_snls.csv', 'wb') as f:
                print 'pulling bad snls from database ...'
                mpsnl_cursor = sma.snl.find({
                    'snl_id': { '$in': bad_snls.keys() },
                    'about.projects': {'$ne': 'CederDahn Challenge'}
                })
                writer = csv.writer(f)
                writer.writerow([
                    'snl_id', 'category', 'snlgroup_key', 'nsites', 'remarks', 'projects', 'authors'
                ])
                print 'writing bad snls to file ...'
                for mpsnl_dict in mpsnl_cursor:
                    mpsnl = MPStructureNL.from_dict(mpsnl_dict)
                    row = [ mpsnl.snl_id, bad_snls[mpsnl.snl_id], mpsnl.snlgroup_key ]
                    row += _get_snl_extra_info(mpsnl)
                    writer.writerow(row)
                    sg_num = mpsnl.snlgroup_key.split('--')[1]
                    if (bad_snls[mpsnl.snl_id] == 'SG default' and sg_num != '-1') or \
                       bad_snls[mpsnl.snl_id] == 'SG change':
                        mpsnl.structure.remove_oxidation_states()
                        sf = SpacegroupAnalyzer(mpsnl.structure, symprec=0.1)
                        badsnls_trace['x'].append(mpsnl.sg_num)
                        badsnls_trace['y'].append(sf.get_spacegroup_number())
                        badsnls_trace['text'].append(mpsnl.snl_id)
                        if bad_snls[mpsnl.snl_id] == 'SG default':
                            print sg_num, sf.get_spacegroup_number()
                print 'plotting out-fig ...'
                out_fig['data'] = Data([bisectrix, badsnls_trace])
                out_fig['layout'] = Layout(
                    showlegend=False, hovermode='closest',
                    title='Spacegroup Assignment Changes',
                    xaxis=XAxis(showgrid=False, title='old SG number', range=[0,230]),
                    yaxis=YAxis(showgrid=False, title='new SG number', range=[0,230]),
                )
                filename = 'spacegroup_changes_'
                filename += datetime.datetime.now().strftime('%Y-%m-%d') 
                py.plot(out_fig, filename=filename, auto_open=False)
        elif args.fig_id == 43: # SNLGroupMemberChecker
            matcher2 = StructureMatcher(
                ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=False, scale=True,
                attempt_supercell=True, comparator=ElementComparator()
            )
            print 'pulling data from plotly ...'
            trace = Scatter(x=[], y=[], text=[], mode='markers', name='mismatches')
            bad_snls = OrderedDict() # snlgroup_id : [ mismatching snl_ids ]
            for category, text in zip(fig['data'][2]['y'], fig['data'][2]['text']):
                if category != 'mismatch': continue
                for entry in text.split('<br>'):
                    fields = entry.split(':')
                    snlgroup_id = int(fields[0].split(',')[0])
                    print snlgroup_id
                    snlgrp_dict = sma.snlgroups.find_one({ 'snlgroup_id': snlgroup_id })
                    snlgrp = SNLGroup.from_dict(snlgrp_dict)
                    s1 = snlgrp.canonical_structure.get_primitive_structure()
                    bad_snls[snlgroup_id] = []
                    for i, snl_id in enumerate(fields[1].split(',')):
                        mpsnl_dict = sma.snl.find_one({ 'snl_id': int(snl_id) })
                        if 'CederDahn Challenge' in mpsnl_dict['about']['projects']:
                            print 'skip CederDahn: %s' % snl_id
                            continue
                        mpsnl = MPStructureNL.from_dict(mpsnl_dict)
                        s2 = mpsnl.structure.get_primitive_structure()
                        is_match = matcher2.fit(s1, s2)
                        if is_match: continue
                        bad_snls[snlgroup_id].append(snl_id)
                        trace['x'].append(snlgroup_id)
                        trace['y'].append(i+1)
                        trace['text'].append(snl_id)
                    if len(bad_snls[snlgroup_id]) < 1:
                        bad_snls.pop(snlgroup_id, None)
            with open('mpworks/check_snl/results/bad_snlgroups.csv', 'wb') as f:
                print 'pulling bad snlgroups from database ...'
                snlgroup_cursor = sma.snlgroups.find({
                    'snlgroup_id': { '$in': bad_snls.keys() },
                })
                writer = csv.writer(f)
                writer.writerow(['snlgroup_id', 'snlgroup_key', 'mismatching snl_ids'])
                print 'writing bad snlgroups to file ...'
                for snlgroup_dict in snlgroup_cursor:
                    snlgroup = SNLGroup.from_dict(snlgroup_dict)
                    row = [
                        snlgroup.snlgroup_id, snlgroup.canonical_snl.snlgroup_key,
                        ' '.join(bad_snls[snlgroup.snlgroup_id])
                    ]
                    writer.writerow(row)
            print 'plotting out-fig ...'
            out_fig = Figure()
            out_fig['data'] = Data([trace])
            out_fig['layout'] = Layout(
                showlegend=False, hovermode='closest',
                title='Member Mismatches of SNLGroup Canonicals',
                xaxis=XAxis(showgrid=False, title='snlgroup_id', showexponent='none'),
                yaxis=YAxis(showgrid=False, title='# mismatching SNLs'),
            )
            filename = 'groupmember_mismatches_'
            filename += datetime.datetime.now().strftime('%Y-%m-%d') 
            py.plot(out_fig, filename=filename, auto_open=False)
    else:
        errors = Counter()
        bad_snls = OrderedDict()
        bad_snlgroups = OrderedDict()
        for i,d in enumerate(fig['data']):
            if not isinstance(d, Scatter): continue
            if not 'x' in d or not 'y' in d or not 'text' in d: continue
            start_id = int(d['name'].split(' - ')[0][:-1])*1000
            marker_colors = d['marker']['color']
            if i < 2*num_snl_streams: # spacegroups
                errors += Counter(marker_colors)
                for idx,color in enumerate(marker_colors):
                    snl_id = start_id + d['x'][idx]
                    color_index = category_colors.index(color)
                    category = categories[color_index]
                    bad_snls[snl_id] = category
            else: # groupmembers
                for idx,color in enumerate(marker_colors):
                    if color != category_colors[0]: continue
                    snlgroup_id = start_id + d['x'][idx]
                    mismatch_snl_id, canonical_snl_id = d['text'][idx].split(' != ')
                    bad_snlgroups[snlgroup_id] = int(mismatch_snl_id)
        print errors
        fig_data = fig['data'][-1]
        fig_data['x'] = [ errors[color] for color in fig_data['marker']['color'] ]
        filename = _get_filename()
        print filename
        #py.plot(fig, filename=filename)
        with open('mpworks/check_snl/results/bad_snls.csv', 'wb') as f:
            mpsnl_cursor = sma.snl.find({ 'snl_id': { '$in': bad_snls.keys() } })
            writer = csv.writer(f)
            writer.writerow([
                'snl_id', 'category', 'snlgroup_key', 'nsites', 'remarks', 'projects', 'authors'
            ])
            for mpsnl_dict in mpsnl_cursor:
                mpsnl = MPStructureNL.from_dict(mpsnl_dict)
                row = [ mpsnl.snl_id, bad_snls[mpsnl.snl_id], mpsnl.snlgroup_key ]
                row += _get_snl_extra_info(mpsnl)
                writer.writerow(row)
        with open('mpworks/check_snl/results/bad_snlgroups.csv', 'wb') as f:
            snlgrp_cursor = sma.snlgroups.find({ 'snlgroup_id': { '$in': bad_snlgroups.keys() } })
            first_mismatch_snls_cursor = sma.snl.find({ 'snl_id': { '$in': bad_snlgroups.values() } })
            first_mismatch_snl_info = OrderedDict()
            for mpsnl_dict in first_mismatch_snls_cursor:
                mpsnl = MPStructureNL.from_dict(mpsnl_dict)
                first_mismatch_snl_info[mpsnl.snl_id] = _get_snl_extra_info(mpsnl)
            writer = csv.writer(f)
            writer.writerow([
                'snlgroup_id', 'snlgroup_key',
                'canonical_snl_id', 'first_mismatching_snl_id',
                 'nsites', 'remarks', 'projects', 'authors'
            ])
            for snlgrp_dict in snlgrp_cursor:
                snlgrp = SNLGroup.from_dict(snlgrp_dict)
                first_mismatch_snl_id = bad_snlgroups[snlgrp.snlgroup_id]
                row = [
                    snlgrp.snlgroup_id, snlgrp.canonical_snl.snlgroup_key,
                    snlgrp.canonical_snl.snl_id, first_mismatch_snl_id
                ]
                row += [
                    ' & '.join(pair) if pair[0] != pair[1] else pair[0]
                    for pair in zip(
                        _get_snl_extra_info(snlgrp.canonical_snl),
                        first_mismatch_snl_info[int(first_mismatch_snl_id)]
                    )
                ]
                writer.writerow(row)
示例#11
0
def check_snls_in_snlgroups(args):
    """check whether SNLs in each SNLGroup still match resp. canonical SNL"""
    range_index = args.start / num_ids_per_stream
    idxs = [2*(num_snl_streams+range_index)]
    idxs += [idxs[0]+1]
    s = [py.Stream(stream_ids[i]) for i in idxs]
    for i in range(len(idxs)): s[i].open()
    end = num_snlgroups if args.end > num_snlgroups else args.end
    id_range = {"$gt": args.start, "$lte": end}
    snlgrp_cursor = sma.snlgroups.find({ "snlgroup_id": id_range})
    colors = []
    num_good_ids = 0
    for snlgrp_dict in snlgrp_cursor:
        start_time = time.clock()
        try:
            snlgrp = SNLGroup.from_dict(snlgrp_dict)
        except:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            text = ' '.join([str(exc_type), str(exc_value)])
            colors.append(category_colors[-1]) # Others
            data = dict(
                x=snlgrp_dict['snlgroup_id']%num_ids_per_stream,
                y=range_index, text=text, marker=Marker(color=colors)
            )
            s[0].write(data)
            sleep(start_time)
            continue
        if len(snlgrp.all_snl_ids) <= 1:
            num_good_ids += 1
            data = dict(x=[num_good_ids], y=[range_index])
            s[1].write(data)
            sleep(start_time)
            continue
        exc_raised = False
        all_snls_good = True
        for snl_id in snlgrp.all_snl_ids:
            if snl_id == snlgrp.canonical_snl.snl_id: continue
            mpsnl_dict = sma.snl.find_one({ "snl_id": snl_id })
            try:
                mpsnl = MPStructureNL.from_dict(mpsnl_dict)
                is_match = matcher.fit(mpsnl.structure, snlgrp.canonical_structure)
            except:
                exc_type, exc_value, exc_traceback = sys.exc_info()
                exc_raised = True
            if exc_raised or not is_match: # Scatter (bad)
                if exc_raised:
                    category = 2 if fnmatch(str(exc_type), '*pybtex*') else 3
                    text = ' '.join([str(exc_type), str(exc_value)])
                else:
                    category = 0
                    text = '%d != can:%d' % (mpsnl_dict['snl_id'], snlgrp.canonical_snl.snl_id)
                colors.append(category_colors[category])
                data = dict(
                    x=snlgrp_dict['snlgroup_id']%num_ids_per_stream,
                    y=range_index, text=text, marker=Marker(color=colors)
                )
                s[0].write(data)
                all_snls_good = False
                sleep(start_time)
                break
        if all_snls_good: # Bar (good)
            num_good_ids += 1
            data = dict(x=[num_good_ids], y=[range_index])
            s[1].write(data)
            sleep(start_time)
    for i in range(len(idxs)): s[i].close()