Пример #1
0
    def test_parse_1d_scan_energies(self):
        """Test parsing a 1D scan output file"""
        path1 = os.path.join(arc_path, 'arc', 'testing', 'rotor_scans',
                             'sBuOH.out')
        energies, angles = parser.parse_1d_scan_energies(path=path1)
        expected_energies = np.array([
            1.57530564e-05, 3.98826556e-01, 1.60839959e+00, 3.49030801e+00,
            5.74358812e+00, 8.01124810e+00, 9.87649510e+00, 1.10079306e+01,
            1.11473788e+01, 1.02373175e+01, 8.49330826e+00, 6.23697731e+00,
            3.89294941e+00, 1.87096796e+00, 5.13009545e-01, 1.86410533e-04,
            4.16146979e-01, 1.66269755e+00, 3.59565619e+00, 5.90306099e+00,
            8.19668453e+00, 1.00329329e+01, 1.10759678e+01, 1.10923247e+01,
            1.00763770e+01, 8.28078980e+00, 6.04456755e+00, 3.77500671e+00,
            1.83344694e+00, 5.20014378e-01, 2.21067093e-03, 3.70723206e-01,
            1.56091218e+00, 3.44323279e+00, 5.73505787e+00, 8.04497265e+00,
            9.93330041e+00, 1.10426686e+01, 1.11168469e+01, 1.01271857e+01,
            8.32729265e+00, 6.06336876e+00, 3.76108631e+00, 1.80461632e+00,
            4.94715062e-01, 0.00000000e+00
        ], np.float64)
        expected_angles = np.array([
            0., 8., 16., 24., 32., 40., 48., 56., 64., 72., 80., 88., 96.,
            104., 112., 120., 128., 136., 144., 152., 160., 168., 176., 184.,
            192., 200., 208., 216., 224., 232., 240., 248., 256., 264., 272.,
            280., 288., 296., 304., 312., 320., 328., 336., 344., 352., 360.
        ], np.float64)
        np.testing.assert_almost_equal(energies, expected_energies)
        np.testing.assert_almost_equal(angles, expected_angles)

        path2 = os.path.join(arc_path, 'arc', 'testing', 'rotor_scans',
                             'scan_1d_curvilinear_error.out')
        energies_2, angles_2 = parser.parse_1d_scan_energies(path=path2)
        self.assertEqual(energies_2, None)
        self.assertEqual(angles_2, None)
Пример #2
0
def transfer_to_database(spc, database_path, output_file_name='output.out'):

    # Create a new folder to store
    if 'smiles' not in spc:
        spc['smiles'] = xyz_to_mol(spc['geom']).to_smiles()

    for i in range(100):
        new_dir = os.path.join(database_path, spc['smiles'], str(i))
        try:
            os.makedirs(new_dir, exist_ok=False)
        except:
            continue
        else:
            break

    # make sure it is the updated summary
    generate_summary(spc)
    with open(os.path.join(new_dir, 'info.txt'), 'w') as info:
        info.write(spc['summary'])

    transfer_species_jobs(spc, new_dir, output_file_name)

    spc['directory'] = new_dir
    xyz_to_xyz_file(spc)
    for rotor in spc['rotors_dict'].values():
        try:
            energies, angles = parse_1d_scan_energies(rotor['scan_path'])
            plot_1d_rotor_scan(angles=angles,
                               energies=energies,
                               path=os.path.dirname(rotor['scan_path']),
                               scan=rotor['scan'])
        except:
            pass

    return spc
Пример #3
0
def check_scan_quality(spc):
    """
    A helper function used to get the status of rotor scans
    """

    for rotor in spc['rotors_dict'].values():

        path = rotor['scan_path']
        if path:
            scan_args = parse_scan_args(path)
            energies, _ = parse_1d_scan_energies(path)
            invalid, reason, _, actions = scan_quality_check(
                spc['label'],
                pivots=rotor['scan'][1:-1],
                energies=energies,
                scan_res=scan_args['step_size'],
                log_file=path)
        else:
            rotor['success'] = False
            rotor['invalidation_reason'] = 'Unknown'
            continue

        if not invalid:
            rotor['success'] = True
            rotor['symmetry'] = determine_rotor_symmetry(
                label=spc['label'],
                pivots=rotor['scan'][1:3],
                energies=energies)[0]
            continue

        if 'change conformer' in actions:
            print(spc['label'] +
                  ': has a bad conformer orientation according to ' +
                  str(rotor['scan']))
            xyz = xyz_to_xyz_file_format(actions['change conformer'])
            return {'label': spc['label'], 'change conformer': xyz}

        if 'barrier' in reason:
            rotor['success'] = False
            rotor['invalidation_reason'] = reason
            continue

        # Otherwise need to come up with troubleshooting methods
        species_scan_lists = [rotor['scan']]
        scan_trsh, scan_res = trsh_scan_job(spc['label'],
                                            scan_args['step_size'],
                                            rotor['scan'], species_scan_lists,
                                            actions, path)
        rotor['trsh_methods'] = [{
            'scan_trsh': scan_trsh,
            'scan_res': scan_res
        }]
        rotor['archived'].append(rotor['scan_path'])
        spc['scan'].remove(rotor['scan_path'])

    return spc
Пример #4
0
    def test_scan_quality_check(self):
        """Test scan quality check for 1D rotor"""
        log_file = os.path.join(arc_path, 'arc', 'testing', 'rotor_scans',
                                'CH2OOH.out')
        # Case 1: non-smooth scan which troubleshot once
        case1 = {
            'label': 'CH2OOH',
            'pivots': [1, 2],
            'energies': parse_1d_scan_energies(log_file)[0],
            'scan_res': 4.0,
            'used_methods': None,
            'log_file': log_file,
        }
        invalidate, invalidation_reason, message, actions = trsh.scan_quality_check(
            **case1)
        self.assertTrue(invalidate)
        self.assertEqual(
            invalidation_reason,
            'Significant difference observed between consecutive conformers')
        expect_message = 'Rotor scan of CH2OOH between pivots [1, 2] is inconsistent between ' \
                         'two consecutive conformers.\nInconsistent consecutive conformers and ' \
                         'problematic internal coordinates:\nconformer # 63 / # 64        D3, D2' \
                         '\nconformer # 80 / # 81        D3, D2\nARC will attempt to troubleshoot' \
                         ' this rotor scan.'
        self.assertEqual(message, expect_message)
        self.assertEqual(len(actions.keys()), 1)
        self.assertIn('freeze', actions)
        self.assertIn([5, 1, 2, 3], actions['freeze'])
        self.assertIn([2, 1, 4, 5], actions['freeze'])

        # Case 2: Lower conformer
        log_file = os.path.join(arc_path, 'arc', 'testing', 'rotor_scans',
                                'COCCOO.out')
        case2 = {
            'label': 'COCCOO',
            'pivots': [2, 5],
            'energies': parse_1d_scan_energies(log_file)[0],
            'scan_res': 8.0,
            'used_methods': None,
            'log_file': log_file,
        }
        invalidate, invalidation_reason, message, actions = trsh.scan_quality_check(
            **case2)
        self.assertTrue(invalidate)
        self.assertEqual(
            invalidation_reason,
            'Another conformer for COCCOO exists which is 4.60 kJ/mol lower.')
        expect_message = 'Species COCCOO is not oriented correctly around pivots [2, 5], ' \
                         'searching for a better conformation...'
        self.assertEqual(message, expect_message)
        xyz = {
            'symbols': ('O', 'O', 'O', 'C', 'C', 'C', 'H', 'H', 'H', 'H', 'H',
                        'H', 'H', 'H'),
            'isotopes': (16, 16, 16, 12, 12, 12, 1, 1, 1, 1, 1, 1, 1, 1),
            'coords':
            ((1.064082, 0.653765, -0.451343), (-2.342701, 0.031994, 0.662511),
             (-2.398473, -1.385822, 0.327886), (0.076296, -0.002042, 0.321439),
             (-1.266646, 0.597254, -0.073572), (2.370241, 0.177374, -0.19811),
             (0.246556, 0.151577, 1.397399), (0.074611, -1.082893, 0.12612),
             (-1.343968, 1.669387, 0.129745), (-1.395784, 0.428829, -1.147694),
             (3.049182, 0.738271, -0.841111), (2.661092, 0.333101, 0.85075),
             (2.461024, -0.893605, -0.429469), (-3.255509, -1.417186,
                                                -0.119474))
        }
        self.assertEqual(actions, {'change conformer': xyz})