0

I have a tab separated model input file I would like to vary for an ensemble analysis formatted similar to this

cat input.txt
/*      Precipitation   in      mm      */
10      30      15      20      22      11

###     Species description
***     sp_name LMA     wsg     a_h     Pmass   h_max
abies_lasiocarpa        2       0.5     1       0.001   20
abies_grandis   2.5     0.4     1       0.005   30
larix_occidentalis      1.5     0.3     1       0.003   18

I have another tab separated file of multipliers randomly selected from a distribution, with 3 per line such as this

cat multipliers.txt
2        1        3
4        3        2
3        2        3

I currently have the workflow set up to handle varying 1 input parameter based off of a 1 column file of multipliers, as shown in the answer to a previous question here (Arithmetic between 2 files generating a series of new files (Pt 2)). This approach uses a script called tst.awk and is run with the command awk -f tst.awk input.txt multipliers.txt. I would like to adapt this script to vary multiple inputs based on one multi-column file of multipliers.

cat tst.awk
BEGIN { FS=OFS="\t" }
NR==FNR {
    if ( tgtFldNr ) {
        lines[++numLines] = $0
    }
    else {
        hdr = hdr $0 ORS
        if ( /^\*\*\*/ ) {      # in case this line is not tab-separated
            split($0,f," ")
            for (i in f) {
                if ( f[i] == "wsg" ) {
                    tgtFldNr = i-1
                    break
                }
            }
        }
    }
    next
}
{
    mult = $1
    out = "file" FNR ".txt"
    printf "%s", hdr > out
    for (lineNr=1; lineNr<=numLines; lineNr++) {
        $0 = lines[lineNr]
        $tgtFldNr *= mult
        print > out
    }
    close(out)
}

So, say I wanted to vary the inputs "LMA", "wsg", and "Pmass" based on the 3 columns of multipliers.txt, as opposed to just "wsg" in my current iteration, the outputs would look like the following

cat file1.txt

(LMA * 2, wsg * 1, Pmass * 3)

/*      Precipitation   in      mm      */
10      30      15      20      22      11

###     Species description
***     sp_name LMA     wsg     a_h     Pmass   h_max
abies_lasiocarpa        4       0.5     1       0.003   20
abies_grandis   5       0.4     1       0.015   30
larix_occidentalis      3       0.3     1       0.009   18
cat file2.txt

(LMA * 4, wsg * 3, Pmass * 2)

/*      Precipitation   in      mm      */
10      30      15      20      22      11

###     Species description
***     sp_name LMA     wsg     a_h     Pmass   h_max
abies_lasiocarpa        8       1.5     1       0.002   20
abies_grandis   10      1.2     1       0.01    30
larix_occidentalis      6       0.9     1       0.006   18
cat file3.txt

(LMA * 3, wsg * 2, Pmass * 3)

/*      Precipitation   in      mm      */
10      30      15      20      22      11

###     Species description
***     sp_name LMA     wsg     a_h     Pmass   h_max
abies_lasiocarpa        6       1       1       0.003   20
abies_grandis   7.5     0.8     1       0.015   30
larix_occidentalis      4.5     0.6     1       0.009   18

How would I adapt tst.awk to function this way? I have been trying to incorporate elif statements into tst.awk, but don't think I know enough about what I'm doing to make it function properly

1
awk 'BEGIN{ FS=OFS="\t" }
    NR==FNR         { muts[NR]=$0; c+=1; next }
    !hdr            { for(i=1; i<=c; i++) { close("file"i); print >>("file"i) } }
    /\*\*\*/ && !hdr{ hdr=1; next }
hdr {
      for (num in muts) {
          bak=$0; split(muts[num], tmp);
          $2*=tmp[1]; $3*=tmp[2]; $5*=tmp[3];
          close("file"num); print >>("file"num);
          $0=bak
      }
}' multipliers infile

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.