COSMO-RS Conformer Workflows for Acetic Acid
********************************************

COSMO-RS Conformers

The "ADFCOSMORSConfJob" class provides a customizable conformer-
generation workflow for COSMO-RS. In its default form it generates
conformers, performs ADF and COSMO calculations for all unique
conformers, and produces ".coskf" files that can be used in multi-
species COSMO-RS.

The workflow can be refined with additional filters and extra
calculation steps to improve the geometries passed to ADF or to
increase the accuracy of the energies used in filtering. For the
multi-species follow-up workflow, see the GUI tutorial and the pyCRS
example.

**Requires:** AMS2026 or later

-[ Related examples ]-

* ADF and COSMO-RS Workflow

* Generating COSMO-RS Compounds from XYZ Files and SMILES

* Property Prediction from SMILES with pyCRS

* Conformer Generation, Rescoring, and Filtering

* Conformer Generation for Multiple Molecules

-[ Related tutorials ]-

* PLAMS with COSMO-RS tutorial

* Conformers tutorial

-[ Related documentation ]-

* PLAMS COSMO-RS scripting

* AMS conformers utility


Initial imports
===============

   from scm.plams.recipes.adfcosmorsconformers import ADFCOSMORSConfJob, ADFCOSMORSConfFilter
   from scm.plams import Molecule, from_smiles, Settings, config, JobRunner
   from scm.conformers import ConformersJob

   config.default_jobrunner = JobRunner(parallel=True, maxjobs=8)  # Set the default jobrunner to be parallel
   config.default_jobmanager.settings.hashing = None  # Disable rerun prevention
   config.job.runscript.nproc = 1  # Number of cores for each job
   config.log.stdout = 1  # Suppress plams output


Set up conformer generator
==========================

First, we input the acetic acid molecule with the "from_smiles"
function and provide the optional compound information that can be
written to the COSKF file.

   mol = from_smiles("CC(=O)O")
   mol_info = {
       "CAS": "64-19-7",
       "IUPAC": "Acetic acid",
       "Other Name": "Ethanoic acid; Ethylic acid",
   }

Now, we’ll specify a conformer generator (identical to the default)
that generates only 50 initial structures:

   conf_sett = Settings()
   conf_sett.input.AMS.Generator.RDKit
   conf_sett.input.AMS.Generator.RDKit.InitialNConformers = 50
   conf_job = ConformersJob(name="conformers_uff", molecule=mol, settings=conf_sett)

Let’s also specify an additional step to add to the default workflow.
Here, we’ll add a DFTB geometry optimization.

   dftb_sett = Settings()
   dftb_sett.input.DFTB
   dftb_sett.input.AMS.Task = "Optimize"

The final thing we need to specify are filters. Let’s make three
filters, the first to take a maximum of 20 conformers with a maximum
energy range of 22 kcal/mol, the second with 10 conformers and 12
kcal/mol and the third with 5 conformers and 7 kcal/mol.

   # ADFCOSMORSConfFilter(max number of conformers, max energy range)
   fil1 = ADFCOSMORSConfFilter(20, 22)  # applied to UFF
   fil2 = ADFCOSMORSConfFilter(10, 12)  # applied to DFTB
   fil3 = ADFCOSMORSConfFilter(5, 7)  # applied to ADF gas phase


Run COSMO-RS conformers job
===========================

Finally, we give this information to the "ADFCOSMORSConfJob" class. We
also specify the name of the coskf files as well as the directory in
which we’ll find them after the calculations complete.

   job = ADFCOSMORSConfJob(
       mol,
       conf_gen=conf_job,
       first_filter=fil1,
       additional=[(dftb_sett, fil2)],
       final_filter=fil3,
       coskf_name="acetic_acid",
       coskf_dir="test_coskfs",
       mol_info=mol_info,
   )
   job.run()
   job.results.wait()

   [18.03|16:14:05] JOB plamsjob STARTED
   [18.03|16:14:05] Waiting for job plamsjob to finish
   [18.03|16:14:05] JOB plamsjob/conformers_uff STARTED
   [18.03|16:14:05] JOB plamsjob/job1_additional STARTED
   [18.03|16:14:05] JOB plamsjob/job2_adf STARTED
   [18.03|16:14:05] JOB plamsjob/job3_adf_filter STARTED
   [18.03|16:14:05] Waiting for job job3_adf_filter to finish
   [18.03|16:14:05] Waiting for job job1_additional to finish
   [18.03|16:14:05] Waiting for job conformers_uff to finish
   [18.03|16:14:05] Waiting for job job2_adf to finish
   [18.03|16:14:11] JOB plamsjob/conformers_uff SUCCESSFUL
   [18.03|16:14:13] JOB plamsjob/job1_additional SUCCESSFUL
   [18.03|16:23:29] JOB plamsjob/job2_adf SUCCESSFUL
   [18.03|16:23:30] JOB plamsjob/job3_adf_filter SUCCESSFUL
   [18.03|16:23:30] JOB plamsjob/job4_replay STARTED
   [18.03|16:24:15] JOB plamsjob/job4_replay SUCCESSFUL
   [18.03|16:24:20] JOB plamsjob SUCCESSFUL

   !amsview test_coskfs/acetic_acid_0.coskf

   !amsview test_coskfs/acetic_acid_1.coskf


See also
========


Related examples
----------------

* ADF and COSMO-RS Workflow

* Generating COSMO-RS Compounds from XYZ Files and SMILES

* Property Prediction from SMILES with pyCRS

* Conformer Generation, Rescoring, and Filtering

* Conformer Generation for Multiple Molecules


Related tutorials
-----------------

* PLAMS with COSMO-RS tutorial

* Conformers tutorial


Related documentation
---------------------

* PLAMS COSMO-RS scripting

* AMS conformers utility


Python Script
=============

   #!/usr/bin/env python
   # coding: utf-8

   # ## Initial imports

   from scm.plams.recipes.adfcosmorsconformers import ADFCOSMORSConfJob, ADFCOSMORSConfFilter
   from scm.plams import Molecule, from_smiles, Settings, config, JobRunner
   from scm.conformers import ConformersJob


   config.default_jobrunner = JobRunner(parallel=True, maxjobs=8)  # Set the default jobrunner to be parallel
   config.default_jobmanager.settings.hashing = None  # Disable rerun prevention
   config.job.runscript.nproc = 1  # Number of cores for each job
   config.log.stdout = 1  # Suppress plams output


   # ## Set up conformer generator

   # First, we input the acetic acid molecule with the `from_smiles` function and provide the optional compound information that can be written to the COSKF file.

   mol = from_smiles("CC(=O)O")
   mol_info = {
       "CAS": "64-19-7",
       "IUPAC": "Acetic acid",
       "Other Name": "Ethanoic acid; Ethylic acid",
   }


   # Now, we'll specify a conformer generator (identical to the default) that generates only 50 initial structures:

   conf_sett = Settings()
   conf_sett.input.AMS.Generator.RDKit
   conf_sett.input.AMS.Generator.RDKit.InitialNConformers = 50
   conf_job = ConformersJob(name="conformers_uff", molecule=mol, settings=conf_sett)


   # Let's also specify an additional step to add to the default workflow.  Here, we'll add a DFTB geometry optimization.

   dftb_sett = Settings()
   dftb_sett.input.DFTB
   dftb_sett.input.AMS.Task = "Optimize"


   # The final thing we need to specify are filters.  Let's make three filters, the first to take a maximum of 20 conformers with a maximum energy range of 22 kcal/mol, the second with 10 conformers and 12 kcal/mol and the third with 5 conformers and 7 kcal/mol.

   # ADFCOSMORSConfFilter(max number of conformers, max energy range)
   fil1 = ADFCOSMORSConfFilter(20, 22)  # applied to UFF
   fil2 = ADFCOSMORSConfFilter(10, 12)  # applied to DFTB
   fil3 = ADFCOSMORSConfFilter(5, 7)  # applied to ADF gas phase


   # ## Run COSMO-RS conformers job

   # Finally, we give this information to the `ADFCOSMORSConfJob` class.  We also specify the name of the coskf files as well as the directory in which we'll find them after the calculations complete.

   job = ADFCOSMORSConfJob(
       mol,
       conf_gen=conf_job,
       first_filter=fil1,
       additional=[(dftb_sett, fil2)],
       final_filter=fil3,
       coskf_name="acetic_acid",
       coskf_dir="test_coskfs",
       mol_info=mol_info,
   )
   job.run()
   job.results.wait()


   # get_ipython().system('amsview test_coskfs/acetic_acid_0.coskf')


   # get_ipython().system('amsview test_coskfs/acetic_acid_1.coskf')
