#!/bin/sh

output="MASS-25"            # specify output observable
parameter=MS                # specify scan parameter
start=100                   # range
stop=100000
steps=30
step_size=log               # log or linear



Xt=0
TB=20
MS=10000

At=$(echo "scale=10; (1./${TB} + ${Xt}) * ${MS}" | bc)
M3factor=1                  # Mg = M3factor * MS
M3=1
AS="1.18000000e-01"
AI="1.28944742e+02"
MT="1.733400000e+02"        # Mt_pole
MB="4.20000000e-00"         # mb(mb) SM MSbar
MTau="1.777030000e-00"      # Mtau_pole
MTmethod=0
GF=0.0000116639
MZ=91.1876
loop=0                      # controls SE tadpole looporder
yuk=0			    # controls the matching(BSM-SM) loop order of Yukawas
tresh=0 
lam=0			    # controls the matching(BSM-SM) loop order of lambda
mtpol=0                     # controls yukawa corrections order at Q=MZ
BSM=0
BL=3
QS=0


#dump_fs_slha_input_file=
#dump_fs_slha_output_file=
#dump_ss_slha_input_file=
#dump_ss_slha_output_file=




sminputs_tmpl="\
Block SMINPUTS               # Standard Model inputs
    1   128.944742           #1.279440000e+02      # alpha^(-1) SM MSbar(MZ)
    2   1.166390000e-05      # G_Fermi
    3   1.18000000e-01       # alpha_s(MZ) SM MSbar
    4   9.118760000e+01      # MZ(pole)
    5   4.20000000e+00       # mb(mb) SM MSbar
    6   1.733400000e+02      # mtop(pole)
    7   1.777030000e+00      # mtau(pole)
    8   0.000000000e+00      # mnu3(pole)
    9   80.385               # MW pole
   11   5.109989020e-04      # melectron(pole)
   12   0.000000000e+00      # mnu1(pole)
   13   1.056583570e-01      # mmuon(pole)
   14   0.000000000e+00      # mnu2(pole)
   21   4.750000000e-03      # md(2 GeV) MS-bar
   22   2.400000000e-03      # mu(2 GeV) MS-bar
   23   1.040000000e-01      # ms(2 GeV) MS-bar
   24   1.270000000e+00      # mc(mc) MS-bar
"

slha_tmpl="\
Block MODSEL                 # Select model
#    6   0                   # flavour violation
Block FlexibleSUSY
    0   1.000000000e-05      # precision goal
    1   0                    # max. iterations (0 = automatic)
    2   0                    # algorithm (0 = two_scale, 1 = lattice)
    3   0                    # calculate SM pole masses
    4   ${loop}              # pole mass loop order
    5   ${loop}              # EWSB loop order
    6   ${BL}                # beta-functions loop order
    7   ${tresh}             # threshold corrections loop order
    8   1                    # Higgs 2-loop corrections O(alpha_t alpha_s)
    9   1                    # Higgs 2-loop corrections O(alpha_b alpha_s)
   10   1                    # Higgs 2-loop corrections O((alpha_t + alpha_b)^2)
   11   1                    # Higgs 2-loop corrections O(alpha_tau^2)
   12   0                    # force output
   13   1                    # Top quark 2-loop corrections QCD
   14   1.000000000e-11      # beta-function zero threshold
   15   0                    # calculate observables (a_muon, ...)
   16   0                    # force positive majorana masses
   17   0                    # pole mass renormalization scale (0 = SUSY scale)
   18   0                    # pole mass renormalization scale in the EFT (0 = min(SUSY scale, Mt))
   19   0                    # EFT matching scale (0 = SUSY scale)
   20   ${yuk}               # EFT loop order for upwards matching
   21   ${lam}               # EFT loop order for downwards matching
   22   0                    # EFT index of SM-like Higgs in the BSM model
   23   ${BSM}               # calculate BSM pole masses 
   24   122111121            # individual threshold correction loop orders
   25   0                    # ren. scheme for Higgs 3L corrections (0 = DR, 1 = MDR)
   26   0                    # Higgs 3-loop corrections O(alpha_t alpha_s^2)
   27   0                    # Higgs 3-loop corrections O(alpha_b alpha_s^2)
   28   0                    # Higgs 3-loop corrections O(alpha_t^2 alpha_s)
   29   0                    # Higgs 3-loop corrections O(alpha_t^3)
   30   0                    # Higgs 4-loop corrections O(alpha_t alpha_s^3)

${sminputs_tmpl}
Block MINPAR                 # Input parameters
    4   1                    # SignMu
#Block EXTPAR                 # Input parameters
#  100   2                    # LambdaLoopOrder (HSSUSY)
Block Ms
    ${MS}                    # SUSY scale
Block TanBeta
    ${TB}                    # tan(Beta) at the SUSY scale
Block Xtt
    ${Xt}                    # Xt / Ms
"

# prints SLHA block
print_slha_block_awk='
BEGIN {
   is_block = 0;
   if (block == "") {
      print "Error: block name not defined";
      print "   Please define the block name with -v block=<block-name>";
      exit 1
   }
}
{
   pattern     = "^block[[:blank:]]*" tolower(block) "([^[:graph:]].*)?$";
   not_pattern = "^block[[:blank:]]*.*$";

   if (tolower($0) ~ pattern) {
      is_block = 1
   } else if (tolower($0) ~ not_pattern) {
      is_block = 0
   };

   if (is_block)
      print $0
}
'

# prints block entry
# expects block entry keys in the form x or x:y or x:y:z etc.
print_block_entry_awk='
{
  len = split(keys,k,":");

  matches = 1;

  for (i in k) {
     if ($(i) != k[i])
        matches = 0
  }

  if (matches == 1)
     print $(len + 1)
}
'

run_HSSUSY() {
    local SG="$1"
    local MS2=$(echo "scale=5; ${MS}^2" | bc)
    local At=$(echo "scale=10; (1./${TB} + ${Xt}) * ${MS}" | bc)
    local slha_output=
    local block=
    local value=
    local slha_input=
    local output_block=$(echo "${output}" | cut -d'-' -f1)
    local output_entry=$(echo "${output}" | cut -d'-' -f2)

    slha_input=$(
    { echo "$slha_tmpl" ; \
      cat <<EOF
Block MODSEL                 # Select model
#   12   ${MS}
Block FlexibleSUSY
    0   1.000000000e-05      # precision goal
    1   0                    # max. iterations (0 = automatic)
    2   0                    # algorithm (0 = all, 1 = two_scale, 2 = semi_analytic)
    3   1                    # calculate SM pole masses
    4   ${loop}              # pole mass loop order
    5   ${loop}              # EWSB loop order
    6   ${BL}                # beta-functions loop order
    7   ${thresh}            # threshold corrections loop order
    8   1                    # Higgs 2-loop corrections O(alpha_t alpha_s)
    9   1                    # Higgs 2-loop corrections O(alpha_b alpha_s)
   10   1                    # Higgs 2-loop corrections O(alpha_t^2 + alpha_t alpha_b + alpha_b^2)
   11   1                    # Higgs 2-loop corrections O(alpha_tau^2)
   12   0                    # force output
   13   ${mtpol}             # Top pole mass QCD corrections (0 = 1L, 1 = 2L, 2 = 3L)
   14   1.000000000e-11      # beta-function zero threshold
   15   0                    # calculate observables (a_muon, ...)
   16   0                    # force positive majorana masses
   17   0                    # pole mass renormalization scale (0 = SUSY scale)
   18   0                    # pole mass renormalization scale in the EFT (0 = min(SUSY scale, Mt))
   19   ${QS}                # EFT matching scale (0 = SUSY scale)
   20   ${yuk}               # EFT loop order for upwards matching
   21   ${lam}               # EFT loop order for downwards matching
   22   0                    # EFT index of SM-like Higgs in the BSM model
   23   1                    # calculate BSM pole masses
   24   124111321            # individual threshold correction loop orders
   25   0                    # ren. scheme for Higgs 3L corrections (0 = DR, 1 = MDR)
   26   1                    # Higgs 3-loop corrections O(alpha_t alpha_s^2)
   27   0                    # Higgs 3-loop corrections O(alpha_b alpha_s^2)
   28   0                    # Higgs 3-loop corrections O(alpha_t^2 alpha_s)
   29   0                    # Higgs 3-loop corrections O(alpha_t^3)
   30   0                    # Higgs 4-loop corrections O(alpha_t alpha_s^3)
Block FlexibleSUSYInput
    0   0.00729735           # alpha_em(0)
    1   125.09               # Mh pole
Block SMINPUTS               # Standard Model inputs
    1   ${AI}                # alpha_em(MZ) SM MSbar
    2   ${GF}                # G_Fermi
    3   ${AS}                # alpha_s(MZ) SM MSbar
    4   ${MZ}                # MZ(pole)
    5   ${MB}                # mb(mb) SM MSbar
    6   ${MT}                # mtop(pole)
    7   ${MTau}              # mtau(pole)
    8   0.000000000e+00      # mnu3(pole)
    9   80.385               # MW pole
   11   5.109989020e-04      # melectron(pole)
   12   0.000000000e+00      # mnu1(pole)
   13   1.056583570e-01      # mmuon(pole)
   14   0.000000000e+00      # mnu2(pole)
   21   4.750000000e-03      # md(2 GeV) MS-bar
   22   2.400000000e-03      # mu(2 GeV) MS-bar
   23   1.040000000e-01      # ms(2 GeV) MS-bar
   24   1.270000000e+00      # mc(mc) MS-bar
Block EXTPAR                 # Input parameters
    0   ${MS}                # MSUSY
    1   ${M3}                # M1(MSUSY)
    2   ${M3}                # M2(MSUSY)
    3   ${M3}                # M3(MSUSY)
    4   ${MS}                # Mu(MSUSY)
    5   ${MS}                # mA(MSUSY)
    6   173.34               # MEWSB
    7   ${At}                # At(MSUSY)
   25   ${TB}                # TanBeta(MSUSY)
  100   ${lam}               # LambdaLoopOrder
  101   1                    # TwoLoopAtAs
  102   1                    # TwoLoopAbAs
  103   1                    # TwoLoopAtAb
  104   1                    # TwoLoopAtauAtau
  105   1                    # TwoLoopAtAt
  200   0                    # DeltaEFT
  201   0                    # DeltaYt
  202   0                    # DeltaOS (0 = DR, 1 = OS)
  203   0                    # Qmatch
  205   1                    # ThreeLoopAtAsAs
Block MSQ2IN
  1  1     ${MS2}   # mq2(1,1)
  2  2     ${MS2}   # mq2(2,2)
  3  3     ${MS2}   # mq2(3,3)
Block MSE2IN
  1  1     ${MS2}   # me2(1,1)
  2  2     ${MS2}   # me2(2,2)
  3  3     ${MS2}   # me2(3,3)
Block MSL2IN
  1  1     ${MS2}   # ml2(1,1)
  2  2     ${MS2}   # ml2(2,2)
  3  3     ${MS2}   # ml2(3,3)
Block MSU2IN
  1  1     ${MS2}   # mu2(1,1)
  2  2     ${MS2}   # mu2(2,2)
  3  3     ${MS2}   # mu2(3,3)
Block MSD2IN
  1  1     ${MS2}   # md2(1,1)
  2  2     ${MS2}   # md2(2,2)
  3  3     ${MS2}   # md2(3,3)
Block AUIN
  1  1     0        # Au(1,1)
  2  2     0        # Au(2,2)
  3  3     ${At}    # Au(3,3)
Block ADIN
  1  1     0        # Ad(1,1)
  2  2     0        # Ad(2,2)
  3  3     0        # Ad(3,3)
Block AEIN
  1  1     0        # Ae(1,1)
  2  2     0        # Ae(2,2)
  3  3     0        # Ae(3,3)
EOF
    })

    # echo "$slha_input"

    # run the spectrum generator
    slha_output=$(echo "$slha_input" | $SG --slha-input-file=- 2>/dev/null)

    block=$(echo "$slha_output" | awk -v block="$output_block" "$print_slha_block_awk")
    value=$(echo "$block"       | awk -v keys="$output_entry" "$print_block_entry_awk")

    [ "x$value" = "x" ] && value="-"

    [ "x$dump_fs_slha_input_file" != "x" ] && \
        echo "$slha_input" > "$dump_fs_slha_input_file"

    [ "x$dump_fs_slha_output_file" != "x" ] && \
        echo "$slha_output" > "$dump_fs_slha_output_file"

    echo $value
}

run_sg() {
    local SG="$1"
    local MS2=$(echo "scale=5; ${MS}^2" | bc)
    local At=$(echo "scale=10; (1./${TB} + ${Xt}) * ${MS}" | bc)
    local slha_output=
    local block=
    local value=
    local slha_input=
    local output_block=$(echo "${output}" | cut -d'-' -f1)
    local output_entry=$(echo "${output}" | cut -d'-' -f2)

    slha_input=$(
    { echo "$slha_tmpl" ; \
      cat <<EOF

Block MODSEL                 # Select model
#   12    1000                # DRbar parameter output scale (GeV)
Block FlexibleSUSY
    0   1.000000000e-05      # precision goal
    1   0                    # max. iterations (0 = automatic)
    2   0                    # algorithm (0 = all, 1 = two_scale, 2 = semi_analytic)
    3   1                    # calculate SM pole masses
    4   ${loop}              # pole mass loop order
    5   ${loop}              # EWSB loop order
    6   ${BL}                # beta-functions loop order
    7   ${thresh}            # threshold corrections loop order
    8   1                    # Higgs 2-loop corrections O(alpha_t alpha_s)
    9   1                    # Higgs 2-loop corrections O(alpha_b alpha_s)
   10   1                    # Higgs 2-loop corrections O((alpha_t + alpha_b)^2)
   11   1                    # Higgs 2-loop corrections O(alpha_tau^2)
   12   1                    # force output
   13   ${mtpol}             # Top pole mass QCD corrections (0 = 1L, 1 = 2L, 2 = 3L)
   14   1.000000000e-11      # beta-function zero threshold
   15   0                    # calculate observables (a_muon, ...)
   16   0                    # force positive majorana masses
   17   0                    # pole mass renormalization scale (0 = SUSY scale)
   18   0                    # pole mass renormalization scale in the EFT (0 = min(SUSY scale, Mt))
   19   0                    # EFT matching scale (0 = SUSY scale)
   20   ${loop}              # EFT loop order for upwards matching
   21   ${lam}               # EFT loop order for downwards matching
   22   0                    # EFT index of SM-like Higgs in the BSM model
   23   1                    # calculate BSM pole masses
   24   122111121            # individual threshold correction loop orders
   25   0                    # ren. scheme for Higgs 3L corrections (0 = DR, 1 = MDR)
   26   1                    # Higgs 3-loop corrections O(alpha_t alpha_s^2)
   27   0                    # Higgs 3-loop corrections O(alpha_b alpha_s^2)
   28   0                    # Higgs 3-loop corrections O(alpha_t^2 alpha_s)
   29   0                    # Higgs 3-loop corrections O(alpha_t^3)
   30   0                    # Higgs 4-loop corrections O(alpha_t alpha_s^3)
Block SMINPUTS               # Standard Model inputs
    1   ${AI}                # alpha_em(MZ) SM MSbar
    2   ${GF}                # G_Fermi
    3   ${AS}                # alpha_s(MZ) SM MSbar
    4   ${MZ}                # MZ(pole)
    5   ${MB}                # mb(mb) SM MSbar
    6   ${MT}                # mtop(pole)
    7   ${MTau}              # mtau(pole)
    8   0.000000000e+00      # mnu3(pole)
    9   80.385               # MW pole
   11   5.109989020e-04      # melectron(pole)
   12   0.000000000e+00      # mnu1(pole)
   13   1.056583570e-01      # mmuon(pole)
   14   0.000000000e+00      # mnu2(pole)
   21   4.750000000e-03      # md(2 GeV) MS-bar
   22   2.400000000e-03      # mu(2 GeV) MS-bar
   23   1.040000000e-01      # ms(2 GeV) MS-bar
   24   1.270000000e+00      # mc(mc) MS-bar
Block MINPAR                 # Input parameters
    3   ${TB}                  # TanBeta
Block EXTPAR                 # Input parameters
    0   ${MS}                # MSUSY
    1   ${M3}                # M1(MSUSY)
    2   ${M3}                # M2(MSUSY)
    3   ${M3}                # M3(MSUSY)
    4   ${MS}                # Mu(MSUSY)
    5   ${MS}                # mA(MSUSY)
    6   173.34               # MEWSB
    7   ${At}                # At(MSUSY)
   11   ${At}                # At(MSUSY)
   12   0
   13   0
   14   0
   15   0
   16   0
   17   0
   18   0
   19   0
   23   ${MS}                # Mu(MSUSY)
   24   ${MS2}               # mA(MSUSY)^2
   31   ${MS}                # msel(1,1)
   32   ${MS}                # msel(2,2)
   33   ${MS}                # msel(3,3)
   34   ${MS}                # mser(1,1)
   35   ${MS}                # mser(2,2)
   36   ${MS}                # mser(3,3)
   41   ${MS}                # msq(1,1)
   42   ${MS}                # msq(2,2)
   43   ${MS}                # msq(3,3)
   44   ${MS}                # msur(1,1)
   45   ${MS}                # msur(2,2)
   46   ${MS}                # msur(3,3)
   47   ${MS}                # msdr(1,1)
   48   ${MS}                # msdr(2,2)
   49   ${MS}                # msdr(3,3)
EOF
    })

    # echo "$slha_input"

    # run the spectrum generator
    slha_output=$(echo "$slha_input" | $SG --slha-input-file=- 2>/dev/null)

    block=$(echo "$slha_output" | awk -v block="$output_block" "$print_slha_block_awk")
    value=$(echo "$block"       | awk -v keys="$output_entry" "$print_block_entry_awk")

    [ "x$value" = "x" ] && value="-"

    [ "x$dump_fs_slha_input_file" != "x" ] && \
        echo "$slha_input" > "$dump_fs_slha_input_file"

    [ "x$dump_fs_slha_output_file" != "x" ] && \
        echo "$slha_output" > "$dump_fs_slha_output_file"

    echo $value
}



help() {
    cat <<EOF
Usage: $0 [options]
Options:
  --dump-flexiblesusy-slha-input=   dump FlexibleSUSY SLHA input file
  --dump-flexiblesusy-slha-output=  dump FlexibleSUSY SLHA output file
  --dump-softsusy-slha-input=       dump SOFTSUSY SLHA input file
  --dump-softsusy-slha-output=      dump SOFTSUSY SLHA output file
  --output=      output parameter in the format BLOCK-ENTRY1[:ENTRY2] (default: ${output})
  --parameter=   scanned parameter (default: ${parameter})
  --start=       start value (default: ${start})
  --stop=        end value (default: ${stop})
  --steps=       number of steps (default: ${steps})
  --step_size=   linear or log (default: ${step_size})
  --AI=          alpha_em (default: ${AI})
  --AS=          alpha_s (default: ${AS})
  --BL=          beta-functions loop order (default: ${BL})
  --GF           Fermi constant
  --M3factor=    Gluino mass factor: M3 = M3factor * MS (default: ${M3factor})
  --MS=          M_SUSY (default: ${MS})
  --MT=          Top quark pole mass (default: ${MT})
  --MZ           Z pole mass
  --TB=          tan(beta) (default: ${TB})
  --Xt=          Xt (default: ${Xt})
  --help=|-h     print this help message
EOF
}

if test $# -gt 0 ; then
    while test ! "x$1" = "x" ; do
        case "$1" in
            -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
            *) optarg= ;;
        esac

        case $1 in
            --dump-flexiblesusy-slha-input=*)  dump_fs_slha_input_file=$optarg ;;
            --dump-flexiblesusy-slha-output=*) dump_fs_slha_output_file=$optarg ;;
            --dump-softsusy-slha-input=*)      dump_ss_slha_input_file=$optarg ;;
            --dump-softsusy-slha-output=*)     dump_ss_slha_output_file=$optarg ;;
            --output=*)              output=$optarg ;;
            --parameter=*)           parameter=$optarg ;;
            --start=*)               start=$optarg ;;
            --stop=*)                stop=$optarg ;;
            --steps=*)               steps=$optarg ;;
            --step-size=*)           step_size=$optarg ;;
            --AI=*)                  AI=$optarg ;;
            --AS=*)                  AS=$optarg ;;
            --BL=*)                  BL=$optarg ;;
            --GF=*)                  GF=$optarg ;;
            --M3factor=*)            M3factor=$optarg ;;
            --MS=*)                  MS=$optarg ;;
            --MT=*)                  MT=$optarg ;;
            --MZ=*)                  MZ=$optarg ;;
            --TB=*)                  TB=$optarg ;;
            --Xt=*)                  Xt=$optarg ;;
            --help|-h)               help; exit 0 ;;
            *)  echo "Invalid option '$1'. Try $0 --help" ; exit 1 ;;
        esac
        shift
    done
fi


# the scan starts here

printf "# MS = ${MS}, TanBeta = ${TB}, Xt = ${Xt}\n"
printf "# %14s %16s %16s %16s\n" "$parameter" "feft_1l" "eft_3l" "fo_3l"

for i in `seq 0 $steps`; do
    # calculate current value for the scanned variable
    case "$step_size" in
        linear)
            value=$(cat <<EOF | bc
scale=10
$start + ($stop - $start)*${i} / $steps
EOF
                 ) ;;
        log)
            value=$(cat <<EOF | bc -l
scale=10
e(l($start) + (l($stop) - l($start))*${i} / $steps)
EOF
                 ) ;;
        *) echo "Error: unknown step size: $step_size"
           exit 1 ;;
    esac

    eval "${parameter}=${value}"

    M3=$(cat <<EOF | bc
scale=10
$MS * $M3factor
EOF
         )

   #helpful for scale variation and uncertainty estimation

   MShalf=$(echo "scale=10; (${MS} * 0.5)" | bc ) # -> double conversion run with bash instead sh
   MStwo=$(echo "scale=10; (${MS} * 2.)" | bc )
   QLhalf=$(echo "scale=10; ( 173.34  * 0.5)" | bc ) # -> double conversion run with bash instead sh
   QLtwo=$(echo "scale=10; ( 173.34* 2.)" | bc )
   
   QS=0 #${MStwo}
   QL=0 #${QLtwo}

   #specification of threshold corrections
    thresh=3
    mtpol=3
    yuk=2
    BSM=0
    BL=4
    


    #run the spectrum generators

    lam=1
    loop=1 
    feft=$(run_HSSUSY "models/MSSMEFTHiggs/run_MSSMEFTHiggs.x")
 
    loop=3
    yuk=2
    lam=2
    lam=3
    eft=$(run_HSSUSY "models/HSSUSY/run_HSSUSY.x")
 

    mtpol=2
    yuk=2
    loop=3
    BL=3
    fo=$(run_sg "models/NUHMSSMNoFVHimalaya/run_NUHMSSMNoFVHimalaya.x")



    printf "%16s %16s %16s %16s\n" "$value" "$feft" "$eft" "$fo"
    

done
