/******************************************************************************
 * poisecal
 * --------
 * 
 * Download from: https://git.io/JUHOk
 *
 * AU script which automates p1 optimisation using POISE. Behaves similarly to
 * pulsecal: optimises the value of p1 in expno 99999, then sets the optimised
 * value to the current dataset and shows a message.
 *
 * To optimise on only one particular part of the spectrum, either:
 * 
 *  1) Use the command `dpl` to specify a particular region, then run
 *     `poisecal`; or
 *  2) use the command 
 *
 *         poisecal LEFT RIGHT
 *
 *     where LEFT and RIGHT are the edges of the desired spectral window in
 *     ppm. The order in which these are specified does not matter, so
 *     `poisecal 1 4` and `poisecal 4 1` behave exactly the same way.
 *
 * To optimise only one end of a spectrum (e.g. above 4 ppm only), use option 2
 * and pass a large value as the other argument, e.g. `poisecal 4 1000`.
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *****************************************************************************/

GETCURDATA
int old_expno = expno;
double f1p, f2p;
// Argument parsing
if (i_argc == 4) {  // argv[0] is always the programme name, argv[1] is 'exec'
    double d1, d2;
    char *cp;
    d1 = strtod(i_argv[2], &cp);
    if (*cp) STOPMSG("Invalid arguments. Usage: poisecal [left right]")
    d2 = strtod(i_argv[3], &cp);
    if (*cp) STOPMSG("Invalid arguments. Usage: poisecal [left right]")
    f1p = d1 > d2 ? d1 : d2;
    f2p = d1 > d2 ? d2 : d1;
}
else if (i_argc == 2) {
    FETCHPAR("F1P", &f1p)
    FETCHPAR("F2P", &f2p)
}
else STOPMSG("Invalid arguments. Usage: poisecal [left right]")
// Use EXPNO 99999 in the current folder for optimisation.
DATASET(name, 99999, procno, disk, user)
// Set some key parameters. Notice that these lines can be substantially cut
// if an appropriate parameter set is set up beforehand.
RPAR("PROTON", "all")
GETPROSOL
STOREPAR("PULPROG", "zg")
STOREPAR("NS", 1)
STOREPAR("DS", 0)
STOREPAR("D 1", 1.0)
STOREPAR("RG", 1)
STOREPAR("F1P", f1p)
STOREPAR("F2P", f2p)
STOREPARS("F1P", f1p)
STOREPARS("F2P", f2p)
// Run optimisation.
XCMD("sendgui xpy poise p1cal -a bobyqa -q")
// POISE stores the optimised value in p1 after it's done. We can retrieve it
// here. Don't try to get the *status* parameter, since that is not the
// optimised value (it is the value used for the last function evaluation!)
float p1opt;
FETCHPAR("P 1", &p1opt)
p1opt = p1opt/4;
// Move back to old dataset and set p1 to optimised value.
DATASET(name, old_expno, procno, disk, user)
VIEWDATA_SAMEWIN  // not strictly necessary, just re-focuses the original spectrum
STOREPAR("P 1", p1opt)
Proc_err(INFO_OPT, "Optimised value of p1: %.3f", p1opt);
// (Optional) Run acquisition.
// ZG
QUIT
// vim: ft=c
