#!/bin/tcsh 

# transforms a MAUS BPF+signal collection into an emuDB in a ZIP 
# WARNING: this script assumes that all input BPFs have the same structure!

# The script checks not for consistent files in input dir; only the found signal files
# are converted together with their annotations.

# DEBUG
set CallString = "# Call: $0 $*"

# 2016-08-31 : changed dir name of the resulting emuDB from <emuRtemplateName>
#              to <emuRtemplateName>_emuDB
# 2016-11-10 : if *_annot.json files are available instead of *.par, these are
#              used to build the emuDB and a WARNING is issued to stdout
# 2017-02-16 : changes levels names to BPF tier names (ORT,KAN,MAU)
# 2017-05-01 : if a *.wav file is missing, look for a *.nis|nist|sph file, and
#              transform this into a *.wav file for output
# 2017-05-04 : added support for optional BPF tiers KAS and MAS; syllable tier MAS
#              must be word synchronous! Replaced emuDBconfig template by in-document
#              templates; changed option emuRtemplateName to emuRDBname
# 2017-05-08 : add deprecated option emuRtemplateName again for backward compatibility,
#              bug fix in emuDBconfig: canvas MAS was always there causing an error in EMUWebAPP
# 2017-06-01 : BPFs with a single MAU tier are processed into a emuDB with a single phonetic tier
# 2017-06-02 : added option createDBConfigOnly=<path+name>, if set, the scripts only writes
#              the DBconfig.json file into the given file name and exits
# 2017-06-09 : replaced validator URL for _annot.json and added validator URL for 
#              _DBconfig.json and set validate=true as default
# 2017-07-26 : extended to handle *_annot.json and *.par files that contain only a single
#              ORT tier as delivered by runASR.
# 2017-10-25 : complete re-coding to make the script more generic
#              header, class1 and class4 parts are generated by generic code (so that all 
#              combinations are possible; ORT is preferred the class 1 level and other class 1 BPF tiers are 
#              attributes to ORT; if no ORT is found but other class 1 tiers, the first is taken as class 1 level;
#              default top level 'bundle' always has all header BPF
#              entries as attributes + default attribute 'source'; all class 4 BPF tiers are converted into levels; the link 
#              structure is fixed: bundle -> ORT -> class 4 BPF tiers or bundle -> class 4 BPF tiers; 
#              class 4 tiers may have multiple word links (e.g. TRN); class 1 tiers too, but then at least 
#              other class 1 tier without must exist, and the class 1 tier with multiple word links
#              is not an attribute but a level between bundle and class 1.
#              introduced new commandline option 'convsignal=true'; if set to false the script 
#              will not automatically convert non RIFF WAVE input signals to RIFF, but leave 
#              them as is; input signals other than wav|nis|nist|sph|mp4|mpeg|mpg are not accepted.
# 2019-12-31 : added attribute level TON to MAS
# 2020-01-30 : BPF input that contains only class 2 tier is processed
# 2020-10-19 : check *_annot.json input for first line 'LHD: ...' because the services sometimes return
#              a *_annot.json file with BPF content, if the conversion mausbpf2emuR fails; since the same 
#              conversion would be tried on the BPF here (and fail), we skip this file and issue a WARNING;
#              if a signal file cannot be converted to RIFF WAVE, a WARNING is issued and the recording is skipped;
#              Skipped recordings and other warnings are listed in a file emuRDBname_emuDB/mausbpfDB2emuDBErrorLog.txt
# 2021-01-17 : extension to call Formant_analysis.R and integrate results into the root dir of the emuDB; this
#              behavior is triggered by option doFormantAnalysis=true and is controlled by the following additional
#              options: sounds="a: e: o: i: u:" (required), gender=u|m|f|c (if set to 'u' (default), 
#              the gender is determined automatically),
#              outlierMetric=euclid|mahalanobis, outlierThreshold=250, midpoint=false, computeERatio=false (for 
#              explanations of these options call 'Rscript Formant_analysis.R --help').
#              Results are stored in the root dir of the emuDB (dir FormantAnalysis).
# 2021-02-02 : change values for FormantAnalysis 'gender' option from u,f,m,c to unknown,female,male,child
# 2021-02-25 : added fix option --saveTracks true for Rscript Formant_analysis.R
# 2021-03-03 : added README file to FormantAnalysis output dir
# 2021-03-24 : plot 'VowelSpacePlotMedian.png' is copied to OUTZIP dir
#
  
#set SOURCE = /usr/local/maus.root
set SCRIPT = `readlink -f "$0"`
set SOURCE = `dirname "$SCRIPT"`  # location where the script is stored
                           # (even if we start via a symbolic link)
set OUTZIP = ""

set v = 0
set TONattributeExist = "FALSE" 

set force = FALSE
set emuRDBname = MAUSOUTPUT
# deprecated, just for backward compatibility
set emuRtemplate = ""
set validate = TRUE
#set SCHEMAANNOT = "http://webapp:9263/_annot"
set SCHEMAANNOT = "https://webapp2.phonetik.uni-muenchen.de:17890/_annot"
set SCHEMADBCONFIG = "https://webapp2.phonetik.uni-muenchen.de:17890/_DBconfig"
set createDBConfigOnly = "" 
set convsignal = "true"
set phontier = ""  # not used any longer; just for backwards compatibility

# the following lists define which BPF keys are supported by the script
# !!! SYNCHRONIZE THESE LISTS WITH mausbpf2emuR !!!
set headlist = ( SAM MAO SAO REP SPN )
set class1list = ( ORT KAN KAS SPK ) # the order is the preference order for the class 1 level name!
set class1listmult = ( NOI TRL TR2 TRO ) # class 1 BPF tiers that may have multiple word links
set class4list = ( MAU PHO SAP MAS WOR TRN )
set class2list = ( SPD IPA VAD )

# Formant_analysis.R options (see 'Rscript Formant_analysis.R --help')
set FORMANTANALYSIS = $SOURCE/FormantAnalysis/FormantAnalysis/Formant_analysis.R
set doFormantAnalysis = false
set sounds = ""              # (required)
set gender = "unknown"       # unknown|male|female|child (if 'unknown' the gender is determined automatically)
set Rgender = "u"
set outlierMetric = "euclid" # euclid|mahalanobis
set outlierThreshold = 250 
set midpoint = false 
set computeERatio = false

# Actually do the argument parsing here

while ( "$1" != "" )
	switch ("$1")
	case *=*:
		set key = `echo $1 | cut -d= -f1`
                #check if option is known (set)
                eval set checkoption = '$?'$key
                if ( $checkoption == 0 ) then
                  echo "ERROR: ${0:t} : unknown option $key - exiting" >> /dev/stderr
                  exit 1
                endif
		set val = `echo $1 | cut -d= -f2`
		eval "set $key "= \'"$val"\'
		unset key val
		shift
		breaksw
        default:
		break
        endsw
end

# end option parser

# boolean variable check; define all boolean input parameters here

set bool = ( force validate convsignal doFormantAnalysis midpoint computeERatio )
foreach booleanvariable ( $bool )
  eval set val = '$'$booleanvariable
  switch ( $val )
  case true:
    eval set $booleanvariable = TRUE
    breaksw
  case True:
    eval set $booleanvariable = TRUE
    breaksw
  case TRUE:
    eval set $booleanvariable = TRUE
    breaksw
  case 1:
    eval set $booleanvariable = TRUE
    breaksw
  case yes:
    eval set $booleanvariable = TRUE
    breaksw
  case Yes:
    eval set $booleanvariable = TRUE
    breaksw
  case YES:
    eval set $booleanvariable = TRUE
    breaksw
  case false:
    eval set $booleanvariable = FALSE
    breaksw
  case False:
    eval set $booleanvariable = FALSE
    breaksw
  case FALSE:
    eval set $booleanvariable = FALSE
    breaksw
  case 0:
    eval set $booleanvariable = FALSE
    breaksw
  case no:
    eval set $booleanvariable = FALSE
    breaksw
  case No:
    eval set $booleanvariable = FALSE
    breaksw
  case NO:
    eval set $booleanvariable = FALSE
    breaksw
  default:
    echo "$0:t : boolean $booleanvariable=$val is not a boolean value. Use either '0,1,true,false,yes,no'"
    exit 1
  endsw
end

# pre-checks for Formant Analysis
if ( "$doFormantAnalysis" == TRUE ) then
  # helpers
  if ( ! -e $FORMANTANALYSIS ) then 
    echo "ERROR: ${0:t} : cannot find required R script $FORMANTANALYSIS - exiting" >> /dev/stderr
    exit 1
  endif
  which Rscript >& /dev/null
  if ( $status != 0 && "$doFormantAnalysis" == TRUE ) then
    echo "ERROR: ${0:t} : required script 'Rscript' not installed - exiting" >> /dev/stderr
    exit 1
  endif
  # Formant analysis options check; booleans are checked above; we must check these rigorously because the webinterface 
  # allows user to pass on the empty string for sounds, or strings for numbers, and we must map gender values
  if ( "$doFormantAnalysis" == TRUE && "$sounds" == "" ) then
    echo "ERROR: ${0:t} : formant analysis requires option 'sounds' that lists the phonemes to be analyzed, e.g. sounds='a: e: i: o: u:' - exiting" >> /dev/stderr
    exit 1
  endif
  if ( "$doFormantAnalysis" == TRUE && "$outlierThreshold" !~ [0-9]* ) then
    echo "ERROR: ${0:t} : option 'outlierThreshold' ('Outlier detection threshold') must be a number - exiting"
    exit 1
  endif
  switch( "$gender" )
    case "unknown":
      set Rgender = u
      breaksw
    case "female":
      set Rgender = f
      breaksw
    case "male":
      set Rgender = m
      breaksw
    default:
      echo "ERROR: ${0:t} : unknown option value for gender=${gender}; valid option values are: female,male,child,unknown - exiting"
      exit 1
      breaksw
  endsw
endif


if ( $1 == "" ) then 
  echo "usage: $0:t [emuRDBname=MAUSOUTPUT][OUTZIP=<emuRDBname>.zip][validate=true][force=false][convsignal=true][doFormantAnalysis=false][sounds=""][gender=][midpoint=false][outlierMetric=euclid][outlierThreshold=250][computeERatio=false] <dir with *.wav and *.par/*_annot.json pairs>"
  echo "       $0:t createDBConfigOnly=<path+name> <dir with *.wav and *.par/*_annot.json pairs>" 
  echo "       The first call transforms MAUS generated BPFs (extension 'par') or emuR annot.json files + signals into emuR DB"
  echo "       named as given in emuRDBname (default: MAUSOUTPUT) plus '_emuDB'. The second call only writes the DBconfig.json file."
  echo "       If *.nis|nist|sph|mp4|mpg|mpeg are available instead of *.wav, these are transformed into *.wav for the emuDB,"
  echo "       option convsignal=true; other wise an ERROR is reported."
  echo "       If *_annot.json are available instead of *.par, these are used for the emuDB (copied)."
  echo "       If validate=1 the resulting *_annot.json/_DBconfig.json are validated using the validators in SCHEMAANNOT and SCHEMADBCONFIG"
  echo "       If force=true an existing output ZIP is overwritten"
  echo "       BPF files *must* have a SAM header entry. The following BPF tiers are recognized and converted:"
  echo "       $headlist $class1list $class4list $class2list"
  echo ""
  echo "       The first call performs a formant analysis, if the option doFormantAnalysis=true; options are:"
  echo "       sounds (required) : list of analyzed sounds, e.g. sounds='a: e: i: o:'; if a sound cannot be found in the"
  echo "                           input data, a WARNING is issued"
  echo "       gender : 'female' 'male' 'unknown', 'child'; if set to 'unknown', an automatic gender detection is performed"
  echo "       midpoint : if set to 'true', the formant is taken from exact midpoint of the segment, not from the mid 50%"
  echo "       outlierMetric : euclid|mahalanobis distances for outlier detection"
  echo "       outlierThreshold : formant values that have a larger distance to the class mean than this value are"
  echo "                          declared as 'outliers' and removed in some plots/tables"
  echo "       computeERatio : if set to true, for each analysed phone all possible eRatios to class means are"
  echo "                       calculated, i.e. the distance of the F1-F4 formants point of a /o/ phone to the"
  echo "                       class means of /a/ and /e/ and so on; eRatios are listed in a results table."  
  echo "       The results of the formant analysis (CSV tables and plots) are stored in the directory 'FormantAnalysis' in the"
  echo "       root dir of the emuDB. The formants tracks (F1-F4) are stored into the input emuDB (if writable); existing tracks are deleted."
  exit 1
endif

which uuid >& /dev/null
if ( $status != 0 ) then 
  echo "ERROR: ${0:t} : cannot find helper 'uuid' - exiting" >> /dev/stderr
  exit 1
endif

set src = $1

if ( ! -d $src ) then 
  echo "ERROR: ${0:t} : cannot find input dir with *.wav|nis|nist|sph - *.par|annot.json pairs - exiting" >> /dev/stderr
  exit 1
endif

# just to cover backward compatibilty for deprecated emuRtemplate option
if ( "$emuRtemplate" != "" ) set emuRDBname = `echo "${emuRtemplate:t}" | sed 's/^\([^_]*\)_.*$/\1/'`

# create temporary dir for target emuR DB
set DATE = `date '+%s'`
set TEMP = /tmp/$$_${DATE}_mausbpf2emuR
if ( -d $TEMP ) then 
  if ( `ls $TEMP/* | wc -l` > 0 ) then 
    rm -rf $TEMP/*
    if ( $status != 0 ) then 
      echo "ERROR: $0:t : cannot empty temporary dir $TEMP - exiting" >> /dev/stderr
      exit 1
    endif
  else
    touch $TEMP/TMP
    rm -f $TEMP/TMP
    if ( $status != 0 ) then 
      echo "ERROR: $0:t : cannot write to temporary dir $TEMP - exiting" >> /dev/stderr
      exit 1
    endif
  endif
else
  mkdir $TEMP
  if ( $status != 0 ) then 
    echo "ERROR: $0:t : cannot create  temporary dir $TEMP - exiting" >> /dev/stderr
    exit 1
  endif
  chmod 777 $TEMP
endif

# check output
if ( $createDBConfigOnly == "" ) then 
  if ( $OUTZIP == "" ) set OUTZIP = ${emuRDBname}.zip
  if ( -e $OUTZIP ) then 
    if ( $force == "FALSE" ) then 
      echo "ERROR: $0:t : output zip file $OUTZIP already exists; use option 'force=true' to overwrite - exiting" >> /dev/stderr
      rm -rf $TEMP
      exit 1
    else
      rm -f $OUTZIP
      if ( $status != 0 ) then 
        echo "ERROR: $0:t : cannot overwrite output zip $OUTZIP - exiting" >> /dev/stderr
        rm -rf $TEMP
        exit 1
      endif
    endif
  endif
  touch $OUTZIP
  if ( $status != 0 ) then
    echo "ERROR: $0:t : cannot write to output zip $OUTZIP - exiting" >> /dev/stderr
    rm -rf $TEMP
    exit 1
  endif
  rm -f $OUTZIP  # zip does not tolerate an existing empty zip file!
else
  if ( -e $createDBConfigOnly ) then 
    if ( $force == "TRUE" ) then 
      rm -f $createDBConfigOnly
      if ( $status != 0 ) then  
        echo "ERROR: $0:t : output file $createDBConfigOnly already exists and cannot delete - exiting" >> /dev/stderr
        rm -rf $TEMP
        exit 1
      endif
    else
      echo "ERROR: $0:t : output file $createDBConfigOnly already exists; use force=true to overwrite - exiting" >> /dev/stderr
      rm -rf $TEMP
      exit 1
    endif
  else
    touch $createDBConfigOnly
    if ( $status != 0 ) then
      echo "ERROR: ${0:t} : cannot write to output file $createDBConfigOnly - exiting" >> /dev/stderr
      rm -rf $TEMP
      exit 1
    endif
  endif
endif

if ( $v > 0 ) echo "DEBUG: ${0:t} : transforming files in $src to emu DB ${emuRDBname} in ZIP $OUTZIP"

# Check inputs
ls $src/{*.wav,*.nis,*.nist,*.sph,*.mp4,*.mpg,*.mpeg} >& /dev/null
if ( $status != 0 ) then
  echo "ERROR: ${0:t} : no *.wav|nis|nist|sph|mp4|mpg|mpeg files found in source dir $src - exiting" >> /dev/stderr
  rm -rf $TEMP 
  exit 1
endif

# If annotation inputs are BPF, check for required and optional BPF tiers in first BPF file
# WARNING: this script assumes that all input BPFs have the same structure!
set err_code = 0
set class4exist = ( ) 
set class2exist = ( ) 
set headexist = ( ) 
set class1exist = ( ) 
set class1existmult = ( )
ls "$src"/*.par >& /dev/null
if ( $status == 0 ) then

  # check for header entries
  set firstBPF = `ls "$src"/*.par | head -n 1`
  set headidx = 0
  foreach headkey ( $headlist )
    grep -q "^${headkey}:" $firstBPF
    if ( $status == 0 ) then 
      @ headidx ++
      set headexist = ( $headexist $headkey )
    endif 
  end
  if ( $headidx == 0 ) then 
    echo "ERROR: ${0:t} : input BPF has no header entry; minimal SAM is required - exiting" >> /dev/stderr
    rm -rf $TEMP
    exit 1
  endif
  # check for plain and mult class 1 entries
  set class1idx = 0
  foreach class1key ( $class1list )
    grep -q "^${class1key}:" $firstBPF
    if ( $status == 0 ) then
      # plain class 1 tier
      @ class1idx ++
      set class1exist = ( $class1exist $class1key )
    endif 
  end
  set class1idxmult = 0
  foreach class1key ( $class1listmult )
    grep -q "^${class1key}:" $firstBPF
    # class 1 tier with word link list
    if ( $status == 0 ) then
      @ class1idxmult ++
      set class1existmult = ( $class1existmult $class1key )
    endif 
  end
  # check for class 4 entries
  set class4idx = 0
  foreach class4key ( $class4list )
    grep -q "^${class4key}:" $firstBPF
    if ( $status == 0 ) then 
      @ class4idx ++
      set class4exist = ( $class4exist $class4key )
    endif 
  end
  # check for class 2 entries
  set class2idx = 0
  foreach class2key ( $class2list )
    grep -q "^${class2key}:" $firstBPF
    if ( $status == 0 ) then 
      @ class2idx ++
      set class2exist = ( $class2exist $class2key )
    endif 
  end

else

  # no BPF input, check for emuDB annot.json
  ls "$src"/*_annot.json >& /dev/null
  if ( $status == 0 ) then
    set firstEMU = `ls "$src"/*_annot.json | head -n 1`
    # check for defined levels/attributes in firstEMU
    set headidx = 0
    foreach headkey ( $headlist )
      grep -q '"name": *"'"${headkey}"'"' "$firstEMU"
      if ( $status == 0 ) then 
        @ headidx ++
        set headexist = ( $headexist $headkey )
      endif 
    end
    if ( $headidx == 0 ) then 
      echo "ERROR: ${0:t} : input _annot.json $firstEMU has no header entry; minimal SAM is required - exiting" >> /dev/stderr
      rm -rf $TEMP
      exit 1
    endif
    # check for class 1 entries
    set class1idx = 0
    foreach class1key ( $class1list )
      grep -q '"name": *"'"${class1key}"'"' "$firstEMU"
       if ( $status == 0 ) then 
        @ class1idx ++
        set class1exist = ( $class1exist $class1key )
      endif 
    end
    # check for class 1 mult entries
    set class1idxmult = 0
    foreach class1key ( $class1listmult )
      grep -q '"name": *"'"${class1key}"'"' "$firstEMU"
       if ( $status == 0 ) then 
        @ class1idxmult ++
        set class1existmult = ( $class1existmult $class1key )
      endif 
    end
    # check for class 4 entries
    set class4idx = 0
    foreach class4key ( $class4list )
      grep -q '"name": *"'"${class4key}"'"' "$firstEMU"
      if ( $status == 0 ) then 
        @ class4idx ++
        set class4exist = ( $class4exist $class4key )
      endif 
    end
    # check for class 2 entries
    set class2idx = 0
    foreach class2key ( $class2list )
      grep -q '"name": *"'"${class2key}"'"' "$firstEMU"
      if ( $status == 0 ) then 
        @ class2idx ++
        set class2exist = ( $class2exist $class2key )
      endif 
    end
    # check for TON attribute to MAS
    grep -q '"name": *"TON"' "$firstEMU"
    if ( $status == 0 ) set TONattributeExist = "TRUE"
  else
    echo "ERROR: $0:t : cannot find BPF input (*.par) nor emuDB input (*_annot.json) in $src - exiting" >> /dev/stderr
    rm -rf $TEMP
    exit 1
  endif 

endif

if ( $v > 0 ) echo "DEBUG: ${0:t} : detected tiers in input: $headexist $class1exist $class1existmult $class4exist $class2exist"

# check for inconsistencies
if ( $class1idx == 0 && $class4idx == 0 && $class2idx == 0 ) then
  echo "ERROR: $0:t : input contains no class 1, class 2 nor a class 4 tier - exiting" >> /dev/stderr
  rm -rf $TEMP
  exit 1
endif
if ( $class1idx == 0 ) then 
  if ( $v > 0 ) echo "DEBUG: ${0:t} : no class 1 tier (ITEM) detected in input: creating links from 'bundle' directly to class 2 and 4 tiers $class4exist $class2exist"
  set class1level = ""
  if ( $class1idxmult > 0 ) then
    echo "ERROR: $0:t : found class 1 tier with multiple word links but no plain class 1 link as a reference - exiting"
    exit 1
  endif
else
  # default class 1 level (ITEM) is the first found in class1list (usually 'ORT' or 'KAN')
  set class1level = $class1exist[1]
  if ( $v > 0 ) echo "DEBUG: ${0:t} : select class 1 tier level name : $class1level"
endif
if ( $class4idx == 0 && $class2idx == 0 && $v > 0 ) echo "DEBUG: ${0:t} : no class 2 or class 4 tier (SEGMENT) detected in input: creating a 'time-less' hierarchy"
if ( $class4idx == 0 && $class2idx > 0 && $v > 0 ) echo "DEBUG: ${0:t} : no class 4 tier (SEGMENT) detected in input: creating a hierarchy with no links to segmental class 2 tiers $class2exist"


# create emuR structure, error log and DBconfig
set uuid = `uuid`
mkdir $TEMP/${emuRDBname}_emuDB
mkdir $TEMP/${emuRDBname}_emuDB/0000_ses
echo "# mausbpfDB2emuDB error/warning log" >! $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt
echo "#" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt
echo "# This file contains errors, warnings or a list of skipped files that were reported" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt
echo "# during the conversion of the BAS WebService results into an EMU-SDMS database." >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt
echo "# If there are no lines except ones starting with '#', then no error occurred." >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt

# Save commandline to log file
echo "#" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt
echo "$CallString" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt
echo "#" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt

# DBconfig is made in three loops over headexist, class1exist and class4exist
if ( $v > 1 ) echo "DEBUG: ${0:t} : writing temporary DBConfig file in $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json"

# print preliminaries 
sed "s/##NAME##/${emuRDBname}/" <<EnD | sed "s/##UUID##/${uuid}/" >! $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
{
    "name": "##NAME##",
    "UUID": "##UUID##",
    "mediafileExtension": "wav",
    "ssffTrackDefinitions": [
EnD
if ( "$doFormantAnalysis" == TRUE ) then 
  printf '      {\n        "name": "FORMANTS",\n        "columnName": "fm",\n        "fileExtension": "fms"\n      }\n' >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
endif
cat <<EnD >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    ],
    "levelDefinitions": [
        {
            "name": "bundle",
            "type": "ITEM",
            "attributeDefinitions": [
                {
                    "name": "bundle",
                    "type": "STRING"
                },
                {
                    "name": "source",
                    "type": "STRING"
                },
EnD

# header loop
set idx = 1
foreach key ( $headexist )
  printf '                {\n                    "name": "%s",\n                    "type": "STRING"\n                }' ${key}  >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
  if ( $idx < $headidx ) echo "," >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
  @ idx ++
end
printf "\n            ]\n        },\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json

# class 1 loop 
if ( $class1idx > 0 ) then 
  printf '        {\n            "name": "%s",\n            "type": "ITEM",\n            "attributeDefinitions": [\n' "$class1level" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
  set idx = 1
  foreach key ( $class1exist ) 
    printf '                {\n                    "name": "%s",\n                    "type": "STRING"\n                }' ${key}  >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    if ( $idx < $class1idx ) then
      printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    else
      printf "\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    endif
    @ idx ++
  end
  printf "            ]\n        }" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
endif 

# class 1 mult loop 
if ( $class1idxmult > 0 ) then 
  set idx = 1
  printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json   # mult is only possible with a class 1 before!
  foreach key ( $class1existmult ) 
    printf '        {\n            "name": "%s",\n            "type": "ITEM",\n            "attributeDefinitions": [\n' "$key" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    printf '                {\n                    "name": "%s",\n                    "type": "STRING"\n                }\n' ${key}  >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    printf "            ]\n        }" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    if ( $idx < $class1idxmult ) then
      printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    else
      printf "\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    endif
    @ idx ++
  end
endif 

# class 4 loop 
if ( $class4idx > 0 ) then 
  set idx = 1
  if ( $class1idx > 0 ) printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
  foreach key ( $class4exist ) 
    printf '        {\n            "name": "%s",\n            "type": "SEGMENT",\n            "attributeDefinitions": [\n' "$key" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    printf '                {\n                    "name": "%s",\n                    "type": "STRING"\n                }' ${key}  >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    if ( ${key} == "MAS" && $TONattributeExist == "TRUE" ) then
      printf ',\n                {\n                    "name": "TON",\n                    "type": "STRING"\n                }\n'  >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    else
      printf "\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    endif
    printf "            ]\n        }" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    if ( $idx < $class4idx ) then
      printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    else
      printf "\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    endif
    @ idx ++
  end
endif 

# class 2 loop 
if ( $class2idx > 0 ) then 
  set idx = 1
  if ( $class1idx > 0 || $class4idx > 0 ) printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
  foreach key ( $class2exist ) 
    printf '        {\n            "name": "%s",\n            "type": "SEGMENT",\n            "attributeDefinitions": [\n' "$key" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    printf '                {\n                    "name": "%s",\n                    "type": "STRING"\n                }\n' ${key}  >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    printf "            ]\n        }" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    if ( $idx < $class2idx ) then
      printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    else
      printf "\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    endif
    @ idx ++
  end
endif 

# end levelDefinitions
printf '    ],\n' >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json

# linkDefinitions: 
printf '    "linkDefinitions": [\n' >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
# linkDefinitions: depending of class1 existence link either bundle to class1 (and then class1 to class4), or bundle to class4
if ( $class1idx == 0 ) then 
  # no class 1 level exists -> direct links from bundle to all class4 tiers
  # class 4 loop
  if ( $class4idx > 0 ) then
    set idx = 1
    foreach key ( $class4exist )
      printf '        {\n            "type": "ONE_TO_MANY",\n            "superlevelName": "bundle",\n            "sublevelName": "%s"\n        }' "${key}" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
      if ( $idx < $class4idx ) then
        printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
      else
        printf "\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
      endif
      @ idx ++
    end
  endif
else
  # class1 exists : links from bundle to class1 and from class1 to class4
  printf '        {\n            "type": "ONE_TO_MANY",\n            "superlevelName": "bundle",\n            "sublevelName": "%s"\n        }' "${class1level}" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
  # class 4 loop
  if ( $class4idx > 0 ) then
    printf ',\n' >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    set idx = 1
    foreach key ( $class4exist )
      printf '        {\n            "type": "ONE_TO_MANY",\n            "superlevelName": "%s",\n            "sublevelName": "%s"\n        }' "${class1level}" "$key" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
      if ( $idx < $class4idx ) then
        printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
      else
        printf "\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
      endif
      @ idx ++
    end
  else 
    printf '\n' >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
  endif
endif

if ( $class1idxmult > 0 ) then 
  # class1 mult tier(s) exist : links from bundle to class1 mult and from class1 mult to class1
  printf ',\n' >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
  set idx = 1
  foreach key ( $class1existmult )
    printf '        {\n            "type": "ONE_TO_MANY",\n            "superlevelName": "bundle",\n            "sublevelName": "%s"\n        },' "${key}" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    printf '        {\n            "type": "ONE_TO_MANY",\n            "superlevelName": "%s",\n            "sublevelName": "%s"\n        }' "${key}" "${class1level}" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    if ( $idx < $class1idxmult ) then
      printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
#    else
#      printf "\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    endif
    @ idx ++
  end
endif

echo ${class4exist} | grep -q "MAS"
set masExist = $status
echo ${class4exist} | grep -q "MAU"
set mauExist = $status
if ( $masExist == 0 && $mauExist == 0 ) then
  # add links from MAS to MAU
  printf ',\n        {\n            "type": "ONE_TO_MANY",\n            "superlevelName": "MAS",\n            "sublevelName": "MAU"\n        }\n' >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
else
  # close class1 mult tier(s) block
  printf "\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
endif

# class 2 loop
if ( $class2idx > 0 ) then
  set idx = 1
  if ( $class1idx > 0 || $class4idx > 0 ) printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
  foreach key ( $class2exist )
    printf '        {\n            "type": "ONE_TO_MANY",\n            "superlevelName": "bundle",\n            "sublevelName": "%s"\n        }' "${key}" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    if ( $idx < $class2idx ) then
        printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    else
        printf "\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    endif
    @ idx ++
  end
endif

# end linkDefinitions
printf '    ],\n' >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json

# the rest DBConfig:
cat <<EnD >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    "EMUwebAppConfig": {
        "perspectives": [
            {
                "name": "default",
                "signalCanvases": {
                    "order": [
                        "OSCI",
                        "SPEC"
                    ],
                    "assign": [
EnD
if ( "$doFormantAnalysis" == TRUE ) then 
printf '                      {\n                        "signalCanvasName": "SPEC",\n                        "ssffTrackName": "FORMANTS"\n                      }\n' >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
endif
cat <<EnD >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
                    ],
                    "contourLims": [

                    ]
                },
                "levelCanvases": {
                    "order": [
EnD
# class 4 loop
if ( $class4idx > 0 ) then
  set idx = 1
  foreach key ( $class4exist )
    printf '                        "%s"' "${key}" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    if ( $idx < $class4idx ) then
      printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    else
      printf "\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    endif
    @ idx ++
  end
endif
if ( $class2idx > 0 ) then
  set idx = 1
  if ( $class4idx > 0 ) printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
  foreach key ( $class2exist )
    printf '                        "%s"' "${key}" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    if ( $idx < $class2idx ) then
      printf ",\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    else
      printf "\n" >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
    endif
    @ idx ++
  end
endif
cat <<EnD >> $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json
                    ]
                },
                "twoDimCanvases": {
                    "order": [

                    ]
                }
            }
        ],
        "restrictions": 
        {
			"showPerspectivesSidebar": true,
			"playback": true,
			"correctionTool": true,
			"editItemSize": true,
			"useLargeTextInputField": false
        },
        "activeButtons": {
            "saveBundle": true,
            "showHierarchy": true
        }
    }
}
EnD

# validation
if ( $validate == "TRUE" ) then
  if ( $SCHEMADBCONFIG != "" ) then 
    if ( $v > 0 ) echo "DEBUG: ${0:t} : validating $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json using $SCHEMADBCONFIG"
    curl -s -H "Content-Type: applicationjson" --data-binary "@$TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json" "$SCHEMADBCONFIG" >& ${TEMP}/curlout
    set curlexit = $status
    if ( $curlexit == 7 ) then
      echo "WARNING: validation server for *_DBConfig.json output cannot be reached; output cannot be validated" >> /dev/stderr
      echo "WARNING: validation server for *_DBConfig.json output cannot be reached; output cannot be validated" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt
    else if ( $curlexit == 0 ) then
      grep -q 'SUCCESS' ${TEMP}/curlout
      if ( $status == 0 ) then
        if ( $v > 0 ) echo "DEBUG: ${0:t} :   -> Ok."
      else
        echo "ERROR: ${0:t} : output _DBConfig.json does not validate against schema - exiting" >> /dev/stderr
        if ( $v > 1 ) then
          echo "DEBUG: ${0:t} : curl output is:"
          cat ${TEMP}/curlout
        endif
        if ( $v == 0 ) rm -rf $TEMP
        exit 1
      endif
    else
      echo "WARNING: curl call to validation server for *_DBConfig.json output returns error code ${curlexit}; output cannot be validated" >> /dev/stderr
      echo "WARNING: curl call to validation server for *_DBConfig.json output returns error code ${curlexit}; output cannot be validated" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt 
      if ( $v > 1 ) then
        echo "DEBUG: ${0:t} : curl output is:"
        cat ${TEMP}/curlout
      endif
    endif
  else
    which jsonlint >& /dev/null
    if ( $status == 0 ) then
      if ( $v > 0 ) echo "DEBUG: ${0:t} : validating $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json using jsonlint"
      jsonlint "$TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json"
      if ( $status != 0 ) then
        echo "WARNING: ${0:t} : $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json does not validate syntactially" >> /dev/stderr
        echo "WARNING: ${0:t} : $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json does not validate syntactially" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt 
      else
        if ( $v > 0 ) echo "  -> Ok."
      endif
    else
      echo "WARNING: $0:t : JSON schema validation is de-activated (option 'validate=false'); fallback jsonlint is not installed" >> /dev/stderr
      echo "WARNING: $0:t : JSON schema validation is de-activated (option 'validate=false'); fallback jsonlint is not installed" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt 
    endif
  endif
endif

# create only DBconfig.json file output
if ( $createDBConfigOnly != "" ) then
  cp $TEMP/${emuRDBname}_emuDB/${emuRDBname}_DBconfig.json $createDBConfigOnly
  if ( $status != 0 ) then
    echo "ERROR: $0:t : cannot write to output file $createDBConfigOnly - exiting" >> /dev/stderr
    rm -rf $TEMP
    exit 1
  endif
  if ( $v > 0 ) echo "DEBUG: ${0:t} : writing _DBconfig.json to $createDBConfigOnly"
  rm -rf $TEMP
  exit 0
endif

# go over all signals in $src, locate corresponding *.par and convert into
# *_annot.json or find corresponding *_annot.json,
# create bundle dir in output emuR structure, convert non-wav signal to wav,
# copy *_annot.json and and *.wav to bundle dir
foreach pf ( $src/{*.wav,*.nis,*.nist,*.sph,*.mp4,*.mpg,*.mpeg} )
  if ( $v > 0 ) echo "DEBUG: ${0:t} : processing signal $pf"

  # checking which annotation file(s) exist
  set bpfExists = FALSE
  set jsonExists = FALSE
  if ( -e ${pf:r}.par ) then 
    set bpfExists = TRUE
    if ( $v > 0 ) echo "DEBUG: ${0:t} : found BPF input ${pf:r}.par"
  endif 
  if ( -e ${pf:r}_annot.json ) then
    set jsonExists = TRUE
    if ( $v > 0 ) echo "DEBUG: ${0:t} : found JSON input ${pf:r}_annot.json"
  endif 
  # checking if the existing _annot.json mistakenly contains BPF content; this is only the case, if a previous
  # conversion mausbpf2emuR has failed and the webservice (mistakenly) returns the BPF in disguise of a _annot.json
  if ( $jsonExists == TRUE ) then 
    head -n 1 ${pf:r}_annot.json | egrep -q '^LHD:'
    if ( $status == 0 ) then 
      echo "WARNING: ${0:t} : found input ${pf:r:t}_annot.json containing (erroneous) BPF content - skipping this recording" >> /dev/stderr
      echo "WARNING: ${0:t} : found input ${pf:r:t}_annot.json containing (erroneous) BPF content - skipping this recording" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt 
      continue
    endif
  endif
 

  # make the bundle dir
  mkdir $TEMP/${emuRDBname}_emuDB/0000_ses/${pf:t:r}_bndl

  # if signal is not *.wav, try to transform 
  if ( ${pf:e} != "wav" ) then 
    if ( $convsignal == "FALSE" ) then 
      echo "ERROR: $0:t : input signal ${pf:t} is not RIFF WAVE (extension 'wav') - exiting" >> /dev/stderr
      echo "     set option convsignal=true to automatically convert nis|nist|sph|mp4|mpg|mpeg" >> /dev/stderr
      rm -rf $TEMP
      exit 1
    endif
    switch ( ${pf:e} )
    case "nis":
    case "nist":
    case "sph":
      which sox >& /dev/null
      if ( $status != 0 ) then
        echo "ERROR: $0:t : sox is not installed, cannot convert input signals (*.${pf:e}) to *.wav - exiting" >> /dev/stderr
        rm -rf $TEMP 
        exit 1
      endif
      sox -t 'sph' $pf $TEMP/${emuRDBname}_emuDB/0000_ses/${pf:t:r}_bndl/${pf:t:r}.wav
      if ( $status != 0 ) then
        echo "WARNING: $0:t : sox reported error while converting ${pf:t} to  *.wav - skipping this recording" >> /dev/stderr
        echo "WARNING: $0:t : sox reported error while converting ${pf:t} to  *.wav - skipping this recording" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt 
        continue
      endif
      breaksw
    case "mp4":
    case "mpg":
    case "mpeg":
      which ffmpeg >& /dev/null
      if ( $status != 0 ) then
        echo "ERROR: $0:t : ffmpeg is not installed, cannot convert input signals (*.${pf:e}) to *.wav - exiting" >> /dev/stderr
        rm -rf $TEMP
        exit 1
      endif
      set VIDEOSAMPLERATE = `ffprobe ${pf} |& grep 'Stream .* Audio' | head -n 1 | sed 's/^.* \([0-9][0-9]*\) Hz.*$/\1/'`
      if ( $status != 0 || $VIDEOSAMPLERATE == "" ) then 
        echo "WARNING: ${0:t} : ffprobe cannot determine audio sample rate from input video; using 16000Hz; this means that emuDB *_annot.json files are based on 16000Hz sampling rate" >> /dev/stderr
        echo "WARNING: ${0:t} : ffprobe cannot determine audio sample rate from input video; using 16000Hz; this means that emuDB *_annot.json files are based on 16000Hz sampling rate"  >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt
        set VIDEOSAMPLERATE = 16000
      else
        echo "WARNING: ${0:t} : extracting audiotrack with ${VIDEOSAMPLERATE}Hz sampling rate from video input" >> /dev/stderr
      endif
      # we assume that '-ac 1' equals the default soundtrack (until now this always has been true)
      ffmpeg -loglevel quiet -y -i ${pf} -acodec pcm_s16le -ac 1 -ar $VIDEOSAMPLERATE $TEMP/${emuRDBname}_emuDB/0000_ses/${pf:t:r}_bndl/${pf:t:r}.wav
      if ( $status != 0 ) then
        echo "WARNING: $0:t : ffmpeg reported error while converting ${pf:t} to  *.wav - skipping this recording" >> /dev/stderr
        echo "WARNING: $0:t : ffmpeg reported error while converting ${pf:t} to  *.wav - skipping this recording" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt 
        continue
      endif
      breaksw
    default:
      breaksw
    endsw
  else
    cp ${pf:r}.wav $TEMP/${emuRDBname}_emuDB/0000_ses/${pf:t:r}_bndl
  endif

  if ( $bpfExists == TRUE && $jsonExists == TRUE ) then
    echo "WARNING: $0:t : both the json and the par file exist, will use the json file and ignore the information in the par file" >> /dev/stderr
    echo "WARNING: $0:t : both the json and the par file exist, will use the json file and ignore the information in the par file" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt 
  endif

  if (  $bpfExists == FALSE && $jsonExists == FALSE ) then 
    echo "WARNING: $0:t : can neither find bpf file ${pf:r}.par nor annot.json file ${pf:r}_annot.json for signal file ${pf} - skipping this recording" >> /dev/stderr
    echo "WARNING: $0:t : can neither find bpf file ${pf:r}.par nor annot.json file ${pf:r}_annot.json for signal file ${pf} - skipping this recording" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt 
    continue
  endif

  # if no _annot.json file exists, create one otherwise use the existing one
  if ( $jsonExists == FALSE ) then
    $SOURCE/mausbpf2emuR v=$v OUTDIR=$TEMP/${emuRDBname}_emuDB/0000_ses/${pf:t:r}_bndl validate=$validate SCHEMA=$SCHEMAANNOT ${pf:r}.par
    if ( $status != 0 ) then 
      echo "WARNING: $0:t : input BPF ${pf:r}.par conversion to ${pf:r}_annot.json failed - skipping this recording" >> /dev/stderr
      echo "WARNING: $0:t : input BPF ${pf:r}.par conversion to ${pf:r}_annot.json failed - skipping this recording" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt 
      continue
    endif
  else
    cp ${pf:r}_annot.json $TEMP/${emuRDBname}_emuDB/0000_ses/${pf:t:r}_bndl
  endif

end

if ( "$doFormantAnalysis" == TRUE ) then 
  if ( $v > 0 ) echo "DEBUG: ${0:t} : do automatic segment extraction of $sounds and formant analysis; write results in root dir of emuDB"
  mkdir $TEMP/${emuRDBname}_emuDB/FormantAnalysis
  if ( $v > 1 ) echo "DEBUG: ${0:t} : calling: Rscript $FORMANTANALYSIS --input $TEMP/${emuRDBname}_emuDB --output $TEMP/${emuRDBname}_emuDB/FormantAnalysis --sounds $sounds --gender $Rgender --outlierMetric $outlierMetric --outlierThreshold $outlierThreshold --midpoint $midpoint --eRatio $computeERatio --saveTracks true --verbosity $v"
  Rscript $FORMANTANALYSIS --input $TEMP/${emuRDBname}_emuDB --output $TEMP/${emuRDBname}_emuDB/FormantAnalysis \
    --sounds "$sounds" --gender "$Rgender" --outlierMetric "$outlierMetric" \
    --outlierThreshold "$outlierThreshold" --midpoint "$midpoint" --eRatio "$computeERatio" --saveTracks true \
    --verbosity "$v" >>& $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt
  if ( $status != 0 ) then
    echo "WARNING: $0:t : ${FORMANTANALYSIS:t} reports error" >> /dev/stderr
    echo "WARNING: $0:t : ${FORMANTANALYSIS:t} reports error" >> $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt
  endif
  grep -q 'WARNING: FormantAnalysis' $TEMP/${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt
  if ( $status == 0 ) then
    echo "WARNING: $0:t : ${FORMANTANALYSIS:t} reports WARNING; consult the log file ${emuRDBname}_emuDB/mausbpfDB2emuDBErrorLog.txt in the result ZIP" >> /dev/stderr
  endif
  # add README to formant analysis results dir
  set DATE = `date`
  cat <<EnD | sed "s/##DATE##/${DATE}/" > $TEMP/${emuRDBname}_emuDB/FormantAnalysis/README

BAS WebService FormantAnalysis  -  Results 

This directory contains the results of the formant analysis performed by the BAS WebService
'FormantAnalysis' on ##DATE##. 

If the following listed files are not present in this directory, an error occurred during the 
analysis; please consult the file ../mausbpfDB2emuDBErrorLog.txt for error messages.

SelectedParameters.txt   : list of parameters that were applied in this analysis
Formant_analysis.R       : the R script used to perform the analysis; you can reproduce
                           the analysis by running this script with the parameters listed
                           in 'SelectedParameters.txt' and the EMU database stored in ../
csv_output               : CSV style tables with the results of the analysis; 
                           see file csv_output/README_CSV.asc for details
plots                    : visualizations of results; see file 
                           plots/README_PLOTS.asc for details
EnD

  # copy a PNG version of VowelSpacePlotMedian.pdf to the dir of OUTZIP
  which pdftoppm >& /dev/null
  if ( $status == 0 ) then
    pdftoppm -png $TEMP/${emuRDBname}_emuDB/FormantAnalysis/plots/VowelSpacePlotMedian.pdf >! ${OUTZIP:h}/VowelSpacePlotMedian.png
    if ( $status != 0 ) echo "WARNING: $0:t : error in pdftoppm conversion: cannot create preview plot" >> /dev/stderr
  else
    echo "WARNING: $0:t : converter 'pdftoppm' not found; cannot create preview plot" >> /dev/stderr
  endif
endif 


# pack emuR structure in result ZIP
if ( $v > 0 ) echo "DEBUG: ${0:t} : creating ZIP $OUTZIP"
set PWD = `pwd`
cd $TEMP
zip -qr ${OUTZIP:t} ${emuRDBname}_emuDB
cd $PWD
mv $TEMP/${OUTZIP:t} $OUTZIP

rm -rf $TEMP

exit 0

