QRef
QRef is a new implementation of quantum refinement, based on the freely available Phenix and Orca software. It allows for refinement in both real and reciprocal space, using X-ray, XFEL, neutron, cryo-EM and micro-ED data. The actual refinement (geometry optimisation) is run by Phenix. Several overlapping or disjoint QM regions are allowed.

The method is described in "Quantum refinement in real and reciprocal space" by Kristoffer J. M. Lundgren, Octav Caldararu, Esko Oksanen and Ulf Ryde, IUCrJ, 11 (2024) 921-937; DOI: 10.1107/S2052252524008406.
The first application is published in H. Jiang, K. J. M. Lundgren & U. Ryde (2023) "Protonation of homocitrate and the E1 state of Fe-nitrogenase studied by QM/MM calculations", Inorg. Chem., 62, 19433-19445 ; DOI: 10.1021/acs.inorgchem.3c02329.

The program is freely available on GitHub: https://github.com/krlun/QRef.
Installation procedure is described there.

The current version is for phenix-1.21.2-5419
Older versions: phenix-1.20.1-4487, phenix-1.21.1-5286.

Updated for Orca 6.0.0 22/8-24 (
/lunarc/nobackup/projects/teobio/Kristoffer/orca/orca_6_0_0). Load modules GCC/13.2.0 and OpenMPI/4.1.6.
module add GCC/12.3.0  OpenMPI/4.1.5 ORCA/6.0.1
module add GCC/13.2.0  OpenMPI/4.1.6 ORCA/6.1.0-avx2
It seems that QRef works only with static orca in
/lunarc/nobackup/projects/teobio/Kristoffer/orca/orca_5_0_4-static/orca

 

QRef is run if there is a file qref.dat in the current directory and there is no file qm.lock.
It can be turned temporarily off by
touch qm.lock

Template sbatch file:

#!/bin/sh
#SBATCH -n 1
#SBATCH -t 168:00:00
#SBATCH -A LU2025-2-123

phenix.refine phenix.params --overwrite
prep_geo_opt_qm_constrained.py 6qi3_sorted_refine_001.pdb
if [ $? -eq 0 ] ; then
 cd geo_opt_qm_constrained_1
 /lunarc/nobackup/projects/teobio/Kristoffer/orca/orca_5_0_4-static/orca qm_1.inp > qm_1.out
 cd ../geo_opt_qm_constrained_2
 /lunarc/nobackup/projects/teobio/Kristoffer/orca/orca_5_0_4-static/orca qm_2.inp > qm_2.out
fi

export PHENIX=/lunarc/nobackup/projects/teobio/Bio/Qref/phenix-1.21.2-5419
export PHENIX_VERSION=1.21.2-5419
. $PHENIX/build/setpaths.sh
export PATH=$PATH:/lunarc/nobackup/projects/teobio/Bio/Qref/Qref-main/scripts

# Specific for Cosmos, parallel version
export OMPI_MCA_btl='^uct,ofi'

export OMPI_MCA_pml='ucx'
export OMPI_MCA_mtl='^ofi'

module add GCC/12.3.0  OpenMPI/4.1.5

phenix.refine phenix.params --overwrite
prep_geo_opt_qm_constrained.py 7kkw_fixed_sorted_refine_001.pdb
cd geo_opt_qm_constrained_1
/lunarc/nobackup/projects/teobio/Kristoffer/orca/orca_6_0_0/orca qm_1.inp > qm_1.out
cd ..
phenix.maps maps.params


How to start a quantum-refinement job

The general procedure to set up a quantum refinement job consists of the following steps:

  1. Ensure that you have proper paths to Phenix and Orca:
    export PHENIX=/lunarc/nobackup/projects/teobio/Bio/Qref/phenix-1.21.2-5419
    export PHENIX_VERSION=1.21.2-5419
    . $PHENIX/build/setpaths.sh
    module add GCC/12.3.0  OpenMPI/4.1.5 ORCA/6.0.1

    or on Tetralith:
    export PHENIX=/proj/teobio/Gayathri/softwares/phenix/phenix-installer-1.21.1-5286-intel-linux-2.6-x86_64-centos6/phenix-1.21.1-5286
    export PHENIX_VERSION=1.21.
    1-5286
    . $PHENIX/build/setpaths.sh

    module load ORCA/6.1.0-bdist

  2. Get the deposited pdb file and structure factor files (the latter converted to mtz format):
    phenix.fetch_pdb <pdb_code> --mtz >fetch.out
    If you do not get the mtz file, download the structure factor file from PDB and then
    phenix.cif_as_mtz <structure_facto_file>
    The latter often gives problem. Try to solve them with the instructions given from Phenix.
    However, Phenix can run also on the cif file.
  3. Protonate the pdb file and construct restraints files for all non-standard residues.
    phenix.ready_set add_h_to_water=True optimise_final_geometry_of_hydrogens=False <pdb_file> >ready_set.out

    The file <pdb_code>.ligands.cif contains all restraints needed.
    Move only protons of the QM system to the original PDB file.

  4. Already done in previous step but may be needed if the step fails.
    Prepare restraint files for unknown residues and ligands. The script qref_prep.py will tell you if there are any missing restraint files.
    This can be achieved using phenix.ready_set and phenix.elbow.
    Cut out the non-standard ligand from the full pdb file and put it into a separate pdb file.
    phenix.elbow --final_geometry=<pdb_file> >elbow.out
    The output is in the xxx.cif file

  5. Sort the pdb file (so that the order does not change when running Phenix.
    sort_pdb.py <model>.pdb
    This gives a file <model>_sorted.pdb.

  6. Prepare the syst1 file that defines the QM region(s).
    The QM region needs to make chemical sense. This means that the QM region should be protonated and complete (but the model outside of the QM region can be incomplete, e.g. with no H atoms).
    Some instructions how to select the QM regions are given below.

  7. Run qref_prep.py <model>_sorted.pdb to generate qref.dat (a file containing settings for the QR interface), as well as PDB files describing the QM regions. Note that the pdb file name must come first, before the options.

    qref_prep.py6qi1_sorted.pdb -s syst11 syst12 -j /lunarc/nobackup/projects/teobio/Bio/Data/Comqum/junctfactor -c cif >prep.out

  8. Check that you have got the correct path to orca in file qref.dat
    Note that if you run Orca in parallel, it needs to be compiled with static linking (only Orca 5.2):
    /lunarc/nobackup/projects/teobio/Kristoffer/orca/orca_5_0_4-static/orca
    sed -i s#/usr/bin/orca#/lunarc/nobackup/projects/teobio/Kristoffer/orca/orca_5_0_4-static/orca# qref.dat

  9. The next step is to prepare input files for Orca.

  10. Run a standard (non-QM) Phenix refinement
    touch qm.lock
    phenix.refine --overwrite <model>_sorted.pdb <model>.mtz (cif_fil)
    Find the wxc factor used:
    grep "wxc = " *.log
    | wxc = 23.293294             wxc_scale = 0.500            wc = 1.000         |
    | wxc = 3.484164              wxc_scale = 0.500            wc = 1.000         |
    | wxc = 3.656784              wxc_scale = 0.500            wc = 1.000         |
    and calculate the average of the latter two. Note that it should be divided by two, because wxc_scale=0.5.

  11. Construct a  Phenix parameter file.
    This is the .eff file from the Phenix refinement in the previous point. It contains all the Phenix refinement settings for the current experimental data and model).
    Rename the .eff file to phenix.params
    cp 5b6w_sorted_refine_001.eff phenix.params
    and edit it to make sure the following options are set:
    Change pdb and mtz file names if needed

  12. To run the quantum refinement job, delete the qm.lock file and then execute either phenix.refine phenix.params or phenix.real_space_refine phenix.params.
    If there is a need to restart the job with different settings for Phenix, make sure to delete the file settings.pickle.
    phenix.refine phenix.params --overwrite
    or
    phenix_real_space.refine phenix.params --overwrite

    If the job is run in parallel, you need to load modules for openMPI (those needed for ORCA). Phenix does not run in parallel.

    If you need to do a restart, do
    rm *.lock

  13. Set up the strain-energies with the command
    prep_geo_opt_qm_constrained.py <pdb_file_qm_refined>
    Go to the directories
    geo_opt_qm_constrained_1, copy a sbatch script and run them
  14. Run edstats to get the RSZD scores:
    First run
    phenix.maps
    without any arguments to get the file maps.params.

    Insert the final pdb file and the reflection file into the file maps.params:
       input {
         pdb_file_name = "5b6w_sorted_refine_001.pdb"
         reflection_data {
           file_name = "5b6w_sorted_refine_001.mtz"
    It works with the original xxxx.mtz file also (they normally give the same results), but it is more safe with the one from Phenix (ensures that all fields are the same as used for the refinement).

    Then run
    phenix.maps maps.params

    Ensure that you can run ccp4 programs:
    . /lunarc/nobackup/projects/bio/CCP4/ccp4-7.0/bin/ccp4.setup-sh
    Construct a file
    edstats.sh and run it
    ./edstats.sh
    This is the content of the edstats.sh file (file names in bold face may need to be changed):
    cad hklin1 pdb_sorted_refine_001_fmodel.mtz hklin2 pdb_sorted_refine_001_map_coeffs.mtz hklout hkl_ed.mtz<<EOF
    LABIN FILE 1 E1=FOBS E2=SIGFOBS E3=FCALC E4=PHIFCALC E5=FOM E6=R_FREE_FLAGS
    LABOUT FILE 1 E1=FOBS E2=SIGFOBS E3=FC E4=PHIC E5=FOM E6=FREE
    LABIN FILE 2 ALL
    EOF
    edstats.pl -xyzin pdb_sorted_refine_001.pdb -hklin hkl_ed.mtz -flabel FOBS -noerror

    This gives the file edstats.out
    It contains results from all residues.
    You normally want to grep out only the interesting results, e.g.
    grep "CYS C   62" edstats.out
    grep "GLY C   87" edstats.out
    ...

    There are three sections in the output: one for the mainchain (m), one for the sidechain (s) and one for all atoms in the residue (a).
    The interesting results are in the ZD-, ZD+ and ZD columns (maximum value for the negative or positive difference density, as well as the maximum absolute value of these two.

    If you run edstats.py without any options, the program will tell you the content of all columns.

  15. Remove unnecessary files for a restart calculation:
    \rm
    *_sorted.pdb *_sorted_refine_001.cif *_sorted_refine_001.eff *_sorted_refine_001.geo *_sorted_refine_001.log *_sorted_refine_001.mtz *_sorted_refine_001_2mFo-DFc_map.ccp4 *_sorted_refine_001_fmodel.mtz *_sorted_refine_001_map_coeffs.mtz *_sorted_refine_002.def edstats.out hkl_ed.mtz qm_?.bibtex qm_?.densities qm_?.densitiesinfo qm_?.engrad qm_?.gbw qm_?.ges qm_?.out qm_?.pdb qm_?.property.txt qref_?.log settings.pickle slurm-*.out 
    You also need to rename the *_sorted_refine_001.pdb file to *_sorted.pdb
  16. This is a script to set occupancies in a restart calculation:
    https://github.com/krlun/QRef/blob/main/scripts/change_occ_pdb.py

  17. QRef is completely reproducible, meaning that when started with the same files, the same results are obtained.



How to calculate strain energy of deposited (or Phenix-refined) structure
  1. Set up the syst1 file(s)
  2. Protonate the file, if necessary.
  3. Run qref_prep.py:
    qref_prep.py
    <file>.pdb -s syst11 syst12 -j /lunarc/nobackup/projects/teobio/Bio/Data/Comqum/junctfactor -c cif >prep.out
  4. mkdir Qm1 Qm2
    cp qm_1_h.pdb Qm1
    cp qm_2_h.pdb Qm2
  5. Set up the following qm_1.inp file (and similar for Qm2):
    ! TPSS D4 DEF2-SV(P) Opt pal8
    *pdbfile +1 1 qm_1_h.pdb
    %geom optimizehydrogens true
    end
  6. Start the calculations with something like:
    #!/bin/sh
    #SBATCH -n 8
    #SBATCH -t 48:00:00
    #SBATCH -A LU2025-2-123

    module add GCC/12.3.0  OpenMPI/4.1.5
    alias orc=/lunarc/nobackup/projects/teobio/Bio/ORCA/orca_6_1_0_linux_x86-64_shared_openmpi418/orca

    orc qm_1.inp >qm_1.out
    cd ../Qm2
    orc qm_2.inp >qm_2.out
  7. Results are found by
    grep FINAL *.out



Occupancy refinement

Sometimes when dealing with QR structures (especially for time-resolved structures), it can be desirable to modify the occupancies within the QM region. Then, we recommend the following procedure:

  1. Start with the best QR structure
  2. Perform a normal Phenix (non-QM) refinement of occupancies:
  3. Copy to a separate directory
  4. Remove all QR files:
    \rm mm* qm* qref* syst* slurm*
  5. mv 5b6w_sorted_refine_001.pdb 5b6w_sorted.pdb
  6. \rm 5b6w_sorted_refine_001* 5b6w_sorted_refine_002* edstats.out settings.pickle hkl_ed.mtz
  7. In phenix.param, do the following changes:
  8.   refine {
        strategy = individual_sites individual_sites_real_space rigid_body \
                   individual_adp group_adp tls *occupancies group_anomalous den
    i.e. turn off coordinate and adp refinement and on occupancy refinement.
  9. Next lines:
       sites {
          individual = None
          torsion_angles = None
          rigid_body = None
        }
      i.e. delete any string after individual (probably strictly not needed) 
  10.     occupancies {
          individual = None
          remove_selection = None
          constrained_group {
            selection = "(resseq 110) and (chain A) and (altloc A)"
            selection = "(resseq 110) and (chain A) and (altloc B)"
            selection = "(resseq 110 or resseq 401) and (chain A) and (altloc C)"
            selection = "(resseq 110 or resseq 401) and (chain A) and (altloc D)"
          }
        }
    i.e. define the various altloc groups, one for each QM region
  11. If you have H atoms in the structure (outside QM region) you also need change from individual to riding (otherwise all of them will get non-unity occupancies):
      hydrogens {
        refine = individual *riding Auto
  12. Modify the sbatch file so that only Phenix is run
    phenix.refine phenix.params --overwrite
    and then submit it.



Neutron structures
In version 1.21, Phenix changed the procedure for joint X-ray–neutron refinement. Before, the joint refinement resulted in a single structure. After, you get two structures, where the neutron structure is restrained towards the X-ray structure.
You can do QRef with the old approach using QRef/Phenix 1.20.1-4487.
The new version has not yet been tested, but should work, but it requires two QM calculations for each model (one for X-ray and one for neutron).


Calculating strain energies
Is now automatised

  1. In the directory where you have run the QRef refinement, run
    prep_geo_opt_qm_constrained.py <pdb_file_qm_refined>

  2. It creeates the folder
    geo_opt_qm_constrained_1
    with files needed for the Orca optimisation
  3. Copy or construct a sbatch file to run the orca optimisation and submit it
/bio/Kristoffer/scripts/prep_geo_opt_qm_constrained.py utils.

It makes the folder g
cp q file


For the deposited structure, copy the starting (i.e. before running any quantum refinement) qm_1.inp and qm_1_h.pdb files to a separate directory and modify the qm_1.inp file to something like:
! TPSS def2-SV(P) D4 UKS Opt
%PAL NPROCS 32 END
*pdbfile +2 2 qm_1_h.pdb
%geom optimizehydrogens true end
(it is very important to remove the line with ! ENGRAD and add Opt - otherwise the geometry is not optimised)

Note also that even with all heavy atoms fixed, Orca will move the coordinates of all atoms slightly, so the final coordinates (in qm_1.pdb) will not reflect the fixed atoms (you need to do an RMS fit to see that). You need to check the qm_1_h.pdb input file to see what were the starting coordinates.

Calculating RSCC

  1. With sort_atoms=False Phenix does not translate the molecule back to the original frame (i.e. in agreement with the map). Therefore:
    At the end of the slurm file there is a command
    phenix.pdbtools translate="x y z"

  2. Run this command, with the final pdb file appended xxx_sorted_realspace_refined_001.pdb.

  3. Run
    phenix.map_model_cc translated_pdb_file map resolution=xxx


Restart a QR calculation from an old QR result

  1. Copy files
    cp phenix.params syst1 qref.dat qm_1.inp qm_1_h.pdb mm_1_c.pdb *refined_000.pdb q ../New
    1. phenix.params
    2. start pdb file
    3. syst1
    4. qref.dat
    5. qm_1.inp
    6. qm_1_h.pdb
    7. mm_1_c.pdb
    8. slurm file
    9. experimental data (normally specified in phenix.param and no need to copy)
    10. Possibly, xxx.cif files
  2. Change in phenix.param the name of the pdb file in two places
  3. Change output_serial = 1 in phenix.param
  4. Or alternatively, change the name of the pdb file to the original input-file name (xxx_sorted.pdb); then there is no need to change phenix.param, but it is a bit harder to know that it is a restart and where it was started from.
  5. Change in qm_1.inp (charge and multiplicity)

Calculate single-point Phenix on deposited structure
phenix.model_vs_data pdb mtz
Calculates statistics of the current model, e.g. Rfactors



Sample syst1 file

628-635 ! LYS A 83
2030 ! CYS A 257
2033-2036 ! CYS A 257
2700 ! THR A 335
2703-2707 ! THR A 335
2716-2720 ! PRO A 338
2723 ! PRO A 338
2724-2726 ! ARG A 339
2728-2747 ! ARG A 339
2921-2928 ! LYS A 361
3429-3437 ! HIS A 423
16809-16829 ! HCA A 501
16830-16846 ! 8P8 A 502
16847-16850 ! CO3 A 503

628 ! CD LYS A 83
2030 ! CA CYS A 257
2700 ! CA THR A 335
2705 ! CG THR A 335
2716 ! N PRO A 338
2720 ! CB PRO A 338
2726 ! C ARG A 339
2921 ! CD LYS A 361
3429 ! CB HIS A 423

Sample ORCA input file

! TPSS D4 DEF2-SV(P)
! ENGRAD
%PAL NPROCS 4 END
*pdbfile +1 1 qm_1_h.pdb

or for metal-containing systems:

! TPSS def2-SV(P) D4 UKS
! ENGRAD
! SlowConv
%PAL NPROCS 8 END
*pdbfile +3 2 qm_1_h.pdb

or even
! TPSS D4 DEF2-SV(P) UKS
! NOTRAH
! SlowConv
! TightSCF
! MORead
%moinp "qm.gbw"
%scf
  MaxIter 100000
  DIISMaxEq 20
  DirectResetFreq 1
end
%PAL NPROCS 48 END
*pdbfile -2 1 qm_1_h.pdb


Input files

  1. phenix.param (parameter file for phenix)
  2. The start model (a pdb or mmcif file)
  3. syst1 defines the QM system with atom numbers corresponding to the input pdb file.
  4. qref.dat defines the junctions (it also tells phenix to run QRef)
  5. qm_1.inp is the Orca input file, showing the charge, multiplicity and the QM method. If there is more than one QM region, the corresponding files are called qm_2.inp, qm_3.inp, etc.
  6. qm_1_h.pdb
  7. mm_1_c.odb
  8. A slurm script file
  9. Experimental data (mtz or map file). The name is specified in the phenix.param file and it might be outside the current director (since it does not change, that is normally and preferably the case).
  10. Possibly, additional restrants files for phenix (xxx.cif)
Output files

Phenix gives five output file, staring with the same prefix (e.g. 7ev9_sorted_real_space_refined_001):

Orca gives 6 output files (per QM system) with names qm_1.*

QRef gives one additional file and updates two files


Where to find final results




Additional comments

Use the same altloc for a specific occupancy (also, qref_prep.py does give a warning if a syst1 definition encompasses different altlocs

Occupancies:
Kristoffer 16/8-24: I have now added change_occ_pdb.py as part of the QRef repository (https://github.com/krlun/QRef/blob/main/scripts/change_occ_pdb.py), which might be useful in terms of adjusting occupancies in a model. It now also supports using a list (using columns 17-26 in a PDB file).

 

As part of the rewrite now one of the options --syst1or --residues has to be specified (and they are mutually exclusive), i.e. to use a syst1 file the syntax is

 

$ change_occ_pdb.py pdb occupancy --syst1 syst1_file

 

or using a residue list

 

$ change_occ_pdb.py pdb occupancy --residues residue_file

 

One might also have to manually update the shebang at line 1 so that it points towards an existing Python interpreter.

 

Do note that this rudimentary implementation is kind of a “all or only syst1” version; I recommend visually inspecting the starting model to find where different altlocs merge, then change the occupancies for the altlocs for the entire part of the subsystem to a single value as to not introduce weird artefacts from the experimental gradients (i.e. construct a complementary syst1 file (which does not need to contain a specification of the junction atoms) covering the entire altloc part of the model and use this new file to change the occupancies).

 

Also, it is possible to change occupancies using phenix.pdbtools, see the documentation at https://phenix-online.org/documentation/reference/pdbtools.html.
It is also probably doable through Coot, using the “Measures” -> “Residue Info…” tool.


Instructions how to build the QM regions



Instructions regarding the junctfactor file




Installation

A somewhat more hands-on description of the installation than described on GitHub.

  1. Download Phenix or make a copy of a existing installation of Phenix.
    If moving an already installed version, change the path in the phenix_env.sh file to the new location.
  2. Download QRef from GitHub (https://github.com/krlun/QRef.; Code - Download zip).
  3. Move it to a proper directiory and
    unzip QRef-main.zip
  4. Alternatively get the link from GitHub (Code - Right-click Download zip - Copy Link) and then
    git clone <link>
  5. source path_to_phenix/phenix_env.sh
  6. Go to the QRef-main/modules directory
  7. cp -pr qref $PHENIX/modules
  8. Overwrite the file $PHENIX/modules/cctbx_project/cctbx/geometry_restraints/energy.py with the proper file from cctbx_project/cctbx/geometry_restraints
    For example (for Phenix version 1.21.2-5419):
    cp cctbx_project/cctbx/geometry_restraints/energies_1.21.2-5419.py
    $PHENIX/modules/cctbx_project/cctbx/geometry_restraints/energies.py
  9. Do the same for the model.py file.
    For example:
    cp cctbx_project/mmtbx/model/model_1.21.2-5419.py $PHENIX/modules/cctbx_project/mmtbx/model/model.py
  10. Uncomment the line
    # if not os.path.exists('qm.lock') and (os.path.exists('xyz_reciprocal.lock') or os.path.exists('xyz.lock')):
    and comment out the next line
    if not os.path.exists('qm.lock'):
    in the file $PHENIX/modules/cctbx_project/cctbx/geometry_restraints/energies.py
  11. Add the line
    import os
    in the beginning of the file
    $PHENIX/modules/phenix/phenix/refinement/xyz_reciprocal_space.py
    Also add the two lines
          with open('xyz_reciprocal.lock', 'w'):
            pass
    before the line
          minimized = mmtbx.refinement.minimization.lbfgs(
    and this line after it:
          os.remove('xyz_reciprocal.lock')
    See below
  12. Do similar changes in the file
    $PHENIX/modules/phenix/phenix/refinement/macro_cycle_real_space.py
    Add the line
    import os
    in the beginning of the file.
    Add the two lines
        with open('xyz.lock', 'w'):
          pass

    before both the line containing self.minimization_no_ncs() and the line containing self.minimization_ncs(), i.e. two places
    and this line after them:
        os.remove('xyz.lock')
    See below
  13. Copy the answer of this command
    which cctbx.python
    to the first line of the files
    path_to_Qref-main/scripts/qref_prep.py, prep_geo_opt_qm_constrained.py
    and sort_pdb.py

  14. Ensure that the path_to_Qref-main/scripts directory is in you PATH variable.
    export PATH=$PATH:
    path_to_Qref-main/scripts

Thus, point 11 should look like this:
      if(self.all_params.main.scattering_table == "neutron"):
        is_neutron_scat_table = True
      with open('xyz_reciprocal.lock', 'w'):
        pass
      minimized = mmtbx.refinement.minimization.lbfgs(
        restraints_manager       = self.model.restraints_manager,
        fmodels                  = self.fmodels,
        model                    = self.model,
        refine_xyz               = True,
        lbfgs_termination_params = lbfgs_termination_params,
        target_weights           = self.target_weights,
        verbose                  = 0,
        correct_special_position_tolerance =
          self.all_params.main.correct_special_position_tolerance,
        is_neutron_scat_table    = is_neutron_scat_table,
        qblib_params             = getattr(self.all_params, "qbio", None),
        macro_cycle              = self.macro_cycle,
        h_params                 = self.h_params,
        log                      = self.log)
      os.remove('xyz_reciprocal.lock')
    elif(self.all_params.ncs.constraints.apply_to_coordinates):


Likewise, point 12 should look like this:
    if(ncs_groups is None or len(ncs_groups)==0):
      with open('xyz.lock', 'w'):
        pass
      self.minimization_no_ncs()
      os.remove('xyz.lock')
    else:
      with open('xyz.lock', 'w'):
        pass
      self.minimization_ncs()
      os.remove('xyz.lock')

  def nqh_flips(self):


Template qref.dat file:
{
    "cif": [
        "HXG.cif"
    ],
    "ltype": 12,
    "n_atoms": 25259,
    "orca_binary": "/proj/teobio/users/x_gayyu/softwares/orca/orca_5_0_4-static/orca",
    "restart": null,
    "syst1": {
        "g": {
            "3": 0.7259016393442623,
            "27": 0.7308552631578947,
            "872": 0.7303273213092851,
            "892": 0.7303273213092851
        },
        "link_pairs": {
            "3": 2,
            "27": 28,
            "872": 873,
            "892": 893
        },
        "restraints_angle": [],
        "restraints_distance": [
            [
                1,
                20912,
                3.12,
                2500.0
            ]
        ],
        "transforms": []
    },
    "syst1_files": [
        "syst1"
    ],
    "w_qm": 7.5
}