#!/usr/bin/bash

ADC_MIN=1
ADC_MAX=8
INT_MIN=1
INT_MAX=8192
NEW_EXT=".tv"

usage="
Usage: `basename $0` [OPTION]... [FILE]...
Transform mpa FILEs in the current directory.
The output file will be named as FILE_[ADC_number].tv
If no FILEs are specified all the mpa files in the directory will be transformed.
If no options are given the output will be a single column ascii file for each ADC present in the FILEs.

  -h, --help                    display this help and exit
  -d, --deadtime-correction     calculate the spectrum corrected for deadtime
  -2, --simnra, --two-columns   output two column file (channel_no content)
  -c, --calibration             It uses the calibration coefficients for calibration
                                NOTE: It has to be used with the two columns flag!!!
  -f, --force                   force convertion of file in case it already exists
  -g, --gupix                   output file for gupix
  -v, --verbose                 increase the information printed
  -s, --sum                     sum the spectra that will be processed
      --adc=ADC_No              output spectrum only for the ADC_No ADC.
                                ADC_no is an integer in the range ${ADC_MIN} to ${ADC_MAX}
      --adc_min=ADC_No          change the ADC_MIN value.
                                It is used to transform a range of ADCs.
                                NOTE: incompatible with the --adc option
      --adc_max=ADC_No          change the ADC_MAX value.
                                It is used to transform a range of ADCs.
                                NOTE: incompatible with the --adc option
      --int_min=channel_No      give the min channel for integration (default is 1)
      --int_max=channel_No      give the max channel for integration (default is 8192)
"

function mpa_to_ascii
{
   for ADC in `eval echo "{${ADC_MIN}..${ADC_MAX}}"` ; do
      if [ ${only_adc} ] && [ "${ADC}" != "${only_adc}" ] ; then continue ; fi
      if grep -q DATA$((ADC-1)) ${file} ; then
         newfilename=$(echo ${file} | sed "s/\.mpa/\_${ADC}${NEW_EXT}/")
         if [ -f ${newfilename} ] && [ ${force} ] ; then
            if [ ${verbose} ] ; then echo "File ${newfilename} already exists! Deleting it!!!" ; fi
            rm -f ${newfilename}
         fi
         if [ -f ${newfilename} ] ; then
            if [ ${verbose} ] ; then echo "File ${newfilename} already exists! Skiping it!!!" ; fi
            if [ ${sumation} ] ; then
               if [ ${verbose} ] ; then echo "Adding file ${newfilename} to sumation file." ; fi
               if [ -f sumdum${ADC} ] ; then paste -d+ sumdum${ADC} ${newfilename} > sumdum${ADC}.dum ; mv -f sumdum${ADC}.dum sumdum${ADC} 
               else cp ${newfilename} sumdum${ADC} ; fi
               echo ${newfilename} >> suminfo_${ADC}
            fi
            if [ ${integration} ] ; then
               if [ ${verbose} ] ; then echo "Integrating file ${newfilename} between channels ${INT_MIN} and ${INT_MAX} to integration file." ; fi
               int=`bc -l <<< $(sed -n "${INT_MIN},${INT_MAX} p" ${newfilename} | tr '\n' '\+' | sed "s/\+$/\n/")`
               echo -e "${int}\t${newfilename}" >> integrations_${INT_MIN}-${INT_MAX}_${ADC}.txt
            fi
            continue
         fi
         if [ ${dtc} ] ; then
            realtime=$(sed -n "/ADC${ADC}/,/[DA][AD][TC][0-9A]/ p" ${file} | sed -n "/realtime/p" | sed "s/.*=\(.*\)/\1/")     #"
            livetime=$(sed -n "/ADC${ADC}/,/[DA][AD][TC][0-9A]/ p" ${file} | sed -n "/livetime/p" | sed "s/.*=\(.*\)/\1/")     #"
            factor=`bc -l <<< ${realtime}/${livetime}`
            if [ ${verbose} ] ; then echo "For adc ${ADC} of file ${file} we have realtime: ${realtime}, and livetime: ${livetime}." ; fi
            if [ ${verbose} ] ; then echo "For adc ${ADC} of file ${file} the factor that will be used for deadtime correction is: ${factor}." ; fi
         fi
         if [ ${use_calibration} ] ; then
            unset cal
            cal[0]=$(sed -n "/ADC${ADC}/,/[DA][AD][TC][0-9A]/ p" ${file} | sed -n "/caloff/p" | sed "s/.*=\(.*\)/\1/")     #"
            cal[1]=$(sed -n "/ADC${ADC}/,/[DA][AD][TC][0-9A]/ p" ${file} | sed -n "/calfact=/p" | sed "s/.*=\(.*\)/\1/")     #"
            cal[2]=$(sed -n "/ADC${ADC}/,/[DA][AD][TC][0-9A]/ p" ${file} | sed -n "/calfact2/p" | sed "s/.*=\(.*\)/\1/")     #"
            cal[3]=$(sed -n "/ADC${ADC}/,/[DA][AD][TC][0-9A]/ p" ${file} | sed -n "/calfact3/p" | sed "s/.*=\(.*\)/\1/")     #"
            if [ ${verbose} ] ; then echo "For adc ${ADC} of file ${file} we will use the following coefficients for calibration:" ; fi
            if [ ${verbose} ] ; then echo "Offset: ${cal[0]}" ; fi
            if [ ${verbose} ] ; then echo "Linear: ${cal[1]}" ; fi
            if [ ${verbose} ] ; then echo "Square: ${cal[2]}" ; fi
            if [ ${verbose} ] ; then echo "Cube  : ${cal[3]}" ; fi
         fi
         if [ ${verbose} ] ; then echo "Creating file ${newfilename}, for adc ${ADC} of file ${file}." ; fi
         sed -n "/DATA$((ADC-1))/,/DATA${ADC}/ p" ${file} | sed "/DATA/ d" > ${newfilename}
         sed -i 's/\r$//' ${newfilename}
         if [ ${dtc} ] ; then
            if [ ${verbose} ] ; then echo "Applying deadtime correction to file ${newfilename}." ; fi
            sed "s/\([0-9]\+\)/\1*${factor}/" ${newfilename} | bc -l > dumpfile ; mv -f dumpfile ${newfilename}
         fi
         if [ ${sumation} ] ; then
            if [ ${verbose} ] ; then echo "Adding file ${newfilename} to sumation file." ; fi
            if [ -f sumdum${ADC} ] ; then paste -d+ sumdum${ADC} ${newfilename} > sumdum${ADC}.dum ; mv -f sumdum${ADC}.dum sumdum${ADC} 
            else cp ${newfilename} sumdum${ADC} ; fi
            echo ${newfilename} >> suminfo_${ADC}
         fi
         if [ ${integration} ] ; then
            if [ ${verbose} ] ; then echo "Integrating file ${newfilename} between channels ${INT_MIN} and ${INT_MAX} to integration file." ; fi
            int=`bc -l <<< $(sed -n "${INT_MIN},${INT_MAX} p" ${newfilename} | tr '\n' '\+' | sed "s/\+$/\n/")`
            echo -e "${int}\t${newfilename}" >> integrations_${INT_MIN}-${INT_MAX}_${ADC}.txt
         fi
         if [ ${tc} ] ; then
            if [ ${verbose} ] ; then echo "Adding additional first column to file ${newfilename}." ; fi
            nl -nln -w6 ${newfilename} > dumpfile ; mv -f dumpfile ${newfilename}
         fi
         if [ ${use_calibration} ] ; then
            if [ ${verbose} ] ; then echo "Calibrating file ${newfilename}." ; fi
#            cut -f1 $newfilename | sed "s/\([0-9]\+\)/${cal[0]}+(${cal[1]}*\1^1)+(${cal[2]}*\1^2)+(${cal[3]}*\1^3)/" | bc -l
            sed -i "s/\([0-9]\+\)[\ \t]\+\([0-9]\+\)/echo $\(echo \"${cal[0]}+(${cal[1]}*\1^1)+(${cal[2]}*\1^2)+(${cal[3]}*\1^3)\" | bc -l\)\t\2/e" ${newfilename}
         fi
         if [ ${gupix} ] ; then
            if [ ${verbose} ] ; then echo "Adding header line for gupix to ${newfilename}." ; fi
            sed -i "1i `sed -n "$=" ${newfilename}` 0" ${newfilename}
         fi
         unset realtime
         unset livetime
      fi
   done
}

for arg in "$@" ; do
   case $1 in
      -d|--deadtime-correction)
         dtc="1"
         shift
      ;;
      -2|--simnra|--two-columns)
         tc=1
         NEW_EXT=".dat"
         shift
      ;;
      -c|--calibration)
         use_calibration=1
         shift
      ;;
      -f|--force)
         force=1
         shift
      ;;
      -g|--gupix)
         gupix=1
         shift
      ;;
      -h|--help)
         echo "${usage}"
         exit 0
      ;;
      -v|--verbose)
         verbose=1
         shift
      ;;
      -s|--sum)
         sumation=1
         shift
      ;;
      --adc=*)
         only_adc=`echo ${arg} | sed "s/\-\-adc\=\([0-9]\+\)/\1/"`
         if [ ${only_adc} -lt ${ADC_MIN} ] || [ ${only_adc} -gt ${ADC_MAX} ] ; then
            echo "ADC number ${only_adc} is out of range (${ADC_MIN}-${ADC_MAX})."
            exit 1
         fi
         shift
      ;;
      --adc_min=*)
         dumadc=`echo ${arg} | sed "s/\-\-adc\_min\=\([0-9]\+\)/\1/"`
         if [ ${dumadc} -lt ${ADC_MIN} ] || [ ${dumadc} -gt ${ADC_MAX} ] ; then
            echo "ADC number ${dumadc} is out of range (${ADC_MIN}-${ADC_MAX})."
            exit 1
         fi
         ADC_MIN=${dumadc}
         unset dumadc
         shift
      ;;
      --adc_max=*)
         dumadc=`echo ${arg} | sed "s/\-\-adc\_max\=\([0-9]\+\)/\1/"`
         if [ ${dumadc} -lt ${ADC_MIN} ] || [ ${dumadc} -gt ${ADC_MAX} ] ; then
            echo "ADC number ${dumadc} is out of range (${ADC_MIN}-${ADC_MAX})."
            exit 1
         fi
         ADC_MAX=${dumadc}
         unset dumadc
         shift
      ;;
      --int_min=*)
         dumint=`echo ${arg} | sed "s/\-\-int\_min=\([0-9]\+\)/\1/"`
         if [ ${dumint} -lt ${INT_MIN} ] || [ ${dumint} -gt ${INT_MAX} ] ; then
            echo "Integration channel ${dumint} is out of range (${INT_MIN}-${INT_MAX})."
            exit 2
         fi
         INT_MIN=${dumint}
         integration=1
         unset dumint
         shift
      ;;
      --int_max=*)
         dumint=`echo ${arg} | sed "s/\-\-int\_max=\([0-9]\+\)/\1/"`
         if [ ${dumint} -lt ${INT_MIN} ] || [ ${dumint} -gt ${INT_MAX} ] ; then
            echo "Integration channel ${dumint} is out of range (${INT_MIN}-${INT_MAX})."
            exit 2
         fi
         INT_MAX=${dumint}
         integration=1
         unset dumint
         shift
      ;;
      -*|--*)
         echo "Unknown option."
         echo "Type mpa2ascii -h or --help for usage"
         exit 3
      ;;
      *)
         files+=("${arg}")
         shift
      ;;
   esac
done

if [ ${use_calibration} ] && [ ! ${tc} ] ; then echo "You have specified the calibration flag without the two columns one!!!\nExiting" ; exit 4 ; fi

if [ ${sumation} ] ; then
   if [ ${verbose} ] ; then echo "Deleting sumation files sum_<ADC_No>${NEW_EXT}!!!" ; fi
   rm -f sum_*${NEW_EXT} suminfo_*
fi

if [ ${integration} ] ; then
   if [ ${verbose} ] ; then echo "Deleting integration files integrations_<ADC_No>_${INT_MIN}-${INT_MAX}.txt!!!" ; fi
   rm -f integrations_${INT_MIN}-${INT_MAX}_*.txt
fi

if [ ! ${files} ] ; then
   ls *.mpa &>/dev/null
   if [ $? = "0" ] ; then   
      echo -e "\a!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      echo -e "Converting all mpa files in the directory"
      echo -e "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      files=(`ls *.mpa`)
   else
      echo -e "\a!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      echo -e "There are no mpa files in the directory"
      echo -e "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
   fi
fi

file_index=0
for file in ${files[@]} ; do
   file_index=$((${file_index} + 1))
   if [ -f ${file} ] ; then
      echo -ne "Processing file ${file} (${file_index}/${#files[@]})                \r"
      mpa_to_ascii
   else
      echo -e "\a!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      echo -e "File ${file} doesn't exist"
      echo -e "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
   fi
done

unset ADC
if [ ${sumation} ] ; then
   for ADC in `eval echo "{${ADC_MIN}..${ADC_MAX}}"` ; do
      if [ ! -f sumdum${ADC} ] ; then continue ; fi
      if [ ${verbose} ] ; then echo "Summing files for adc ${ADC} to sum_${ADC}${NEW_EXT} (Files summed can be found in file suminfo_${ADC})." ; fi
      bc -l < sumdum${ADC} > sum_${ADC}${NEW_EXT}
      rm -f sumdum${ADC}
      if [ ${integration} ] ; then
         if [ ${verbose} ] ; then echo "Integrating file sum_${ADC}${NEW_EXT} between channels ${INT_MIN} and ${INT_MAX} to integration file." ; fi
         int=`bc -l <<< $(sed -n "${INT_MIN},${INT_MAX} p" sum_${ADC}${NEW_EXT} | tr '\n' '\+' | sed "s/\+$/\n/")`
         echo -e "${int}\tsum_${ADC}${NEW_EXT}" >> integrations_${INT_MIN}-${INT_MAX}_${ADC}.txt
      fi
   done
fi

echo ""

exit 0
