Project

General

Profile

Install Professor

The semi-easy way ...

    ssh geant4gpvm01.fnal.gov

    source /geant4/app/altups/setup
    export PRODUCTS=${PRODUCTS}:/geant4/app/externals:/grid/fermiapp/products/common/db:/grid/fermiapp/products/larsoft

    # setup the dependent products
    setup geant4 v4_10_3 -q debug:e10
    setup art v2_06_03 -q debug:e10:nu

    cd /geant4/app/altups/professor
    ../altscripts/make_professor_ups_skeleton 2.2.2beta2 debug:e10

    setup professor 2.2.2beta2 -q debug:e10

    ../altscripts/make_professor_install

The messy details

make_professor_ups_skeleton

#! /usr/bin/env bash
# create a skeleton UPS setup for professor (and aux packages)
#
b0=`basename $0`

# echo -e "${OUTCYAN}start from UPS scratch${OUTNOCOL}" 
# source /geant4/app/users/altups/setup
# export PRODUCTS=${PRODUCTS}:/geant4/app/externals:/grid/fermiapp/products/common/db:/grid/fermiapp/products/larsoft
# setup geant4 v4_10_3 -q debug:e10
# setup art v2_06_03 -q debug:e10:nu
echo -e "${OUTCYAN}${SETUP_GEANT4}${OUTNOCOL}" 
echo -e "${OUTCYAN}${SETUP_ART}${OUTNOCOL}" 
echo -e "${OUTCYAN}start from UPS scratch${OUTNOCOL}" 

export HERE=`pwd`
#
###############################################################################
# some defaults
###############################################################################
export PRODUCT="professor" 
export VERSION_EXAMPLE="2.2.2beta2" 
export QUALIFIER_EXAMPLE="debug:e10" 
export FLAVOR="" 

export VERBOSE=0
export ALLOWQUALMISMATCH=0

export DEPEND1PRD="geant4" 
export DEPEND1VER_DEFAULT="<not-specified>" 
export DEPEND1QUAL_DEFAULT="<not-specified>" 
export DEPEND2PRD="art" 
export DEPEND2VER_DEFAULT="<not-specified>" 
export DEPEND2QUAL_DEFAULT="<not-specified>" 
#
export showusage=0
export showpurpose=0
export showconfig=0
export doexit=-1

###############################################################################
# usage function
###############################################################################
purpose() {
  echo " " >&2
  echo "Purpose:  Create a skeleton UPS area for a version of $PRODUCT" >&2
  echo "  * Assumes $b0 is run from UPS area <path>/$PRODUCT" >&2
  echo "    where <path> is in \$PRODUCTS" >&2
  echo "  * Assumes that ${DEPENDPRD1} and ${DEPENDPRD2} have been setup " >&2
}
usage() {
  echo " " >&2
  echo "Usage:  $b0 [options] <ups-version> <ups-qualifier> [svn-tag]" >&2
  echo "  -h | --help        this message and quit" >&2
  echo "  -t | --test        don't perform actual actions" >&2
  echo "  -v | --verbose     increase verbosity" >&2
  echo "  --show-config      show the configuration" >&2
  echo "  --qual-mismatch    allow GENIE/ROOT qualifier to be different" >&2
  echo "  --checkout[=<val>] do SVN checkout [$CHECKOUT]" >&2
  echo "                        [true]/false - do/don't attempt SVN checkout"  >&2
  echo "                        ssh          - checkout w/ write privs" >&2
}
current_config() {
  echo " " >&2
  echo "Current Settings: PRODUCT=$PRODUCT" >&2
  echo "<version>='${VERSION}'"     >&2
  echo "<qualifier>='${QUALIFIER}'" >&2
  echo "<flavor>='${FLAVOR}'"       >&2
  echo "ISTEST=${ISTEST} VERBOSE=${VERBOSE}" >&2
  echo "PRODUCTS=${PRODUCTS}"       >&2
  echo "will setup $DEPENDPRD1 $DEPENDVER1 -q $DEPENDQUAL1" >&2
  echo "will setup $DEPENDPRD2 $DEPENDVER2 -q $DEPENDQUAL2" >&2
  if [ "$GCCSETUP" != "native" ]; then
    echo "will setup gcc $GCCSETUP" 
  fi
  which gcc >&2
  gcc --version | head -1 >&2
}

###############################################################################
# helper functions
###############################################################################
ESC="\e" 
if [ "Darwin" == `uname` ]; then ESC="\x1B"; fi
OUTRED="${ESC}[0;31m" 
OUTGREEN="${ESC}[0;32m" 
OUTCYAN="${ESC}[0;36m" 
OUTNOC="${ESC}[0m" # No Color
#echo -e "${OUTRED}Hello Stack${OUTNOC}" 
err_red() {
  echo -n $'\e[0;31m'  >&2 # works on Mac OS X as well
#  echo -n -e "${OUTRED}" >&2
}
err_green() {
  echo -n $'\e[0;32m' >&2
}
err_cyan() {
  echo -n $'\e[0;36m' >&2
}
err_nocolor() {
  echo -n $'\e[0m' >&2
#  echo -n -e "${OUTNOC}" >&2
}

sortqual()
{
  # alphabetize the qual components, remove trailing ":" 
  echo $1 | tr ":" "\n" | sort | tr "\n" ":" | sed -e "s/:$//" 
}

check_cwd() {
  # ensure that the product matches the current directory
  PRDDIR=`basename $HERE`
  if [ "$PRDDIR" != "$PRODUCT" ]; then
    echo " " >&2
    err_red
    echo "$b0: HEY? working in '$PRDDIR' but skeleton for product '$PRODUCT'?" >&2
    err_nocolor
    showusage=1
    doexit=2
  fi
}

find_ups_top() {
  # assume we're somewhere in the UPS area we want to add to
  # but don't count on the user to really set it correctly
  THISUPSTOP=`pwd`
  while [ ! -d .upsfiles ]; do
    cd ..
    export THISUPSTOP=`pwd`
  done
}

check_upsloc() {
  # ensure that UPS has been enabled for this location
  # (otherwise other steps might not work) and that the subdir matches product
  LOCALDB=`dirname $HERE`
  isthere=`echo $PRODUCTS | grep -c $LOCALDB`
  # echo "isthere='${isthere}' LOCALDB=$LOCALDB" 
  if [ $isthere -lt 1 ]; then
    echo " " >&2
    err_red
    echo "$b0: HEY? working in " >&2
    echo "  $HERE " >&2
    echo "but base path not listed in \$PRODUCTS" >&2
    echo "     \$PRODUCTS=${PRODUCTS}" >&2
    echo " " 
#    if [ -z "$PRODUCTS" ]; then
       err_green
       echo "you probably want to do:" 
       err_cyan
       echo "source ${THISUPSTOP}/setup" 
       echo "export PRODUCTS=\${PRODUCTS}:/geant4/app/externals:/grid/fermiapp/products/common/db:/grid/fermiapp/products/larsoft" 
#    fi
    err_red
    echo " " 
    echo "since it is unlikely to end happily ... I'll stop here" 
    err_nocolor
  showpurpose=1
  showusage=1
  doexit=3
  fi
}

check_depend() {

  # this depends on GEANT4 & ART (just for consistency)
  DEPEND1_SETUPVAR=`echo SETUP_${DEPEND1PRD} | tr [a-z] [A-Z]`
  DEPEND1_SETUP="${!DEPEND1_SETUPVAR}" 
  if [ -z "${DEPEND1_SETUP}" ]; then
    echo setup ${DEPEND1PRD} ${DEPEND1VER_DEFAULT} -q ${DEPEND1QUAL_DEFAULT}
    echo setup ${DEPEND1PRD} ${DEPEND1VER_DEFAULT} -q ${DEPEND1QUAL_DEFAULT}
  fi

  DEPEND1VER=`echo ${DEPEND1_SETUP} | tr -s ' ' | cut -d' ' -f2`
  DEPEND1QUAL=`echo ${DEPEND1_SETUP} | tr -s ' ' | cut -d' ' -f8`

  DEPEND2_SETUPVAR=`echo SETUP_${DEPEND2PRD} | tr [a-z] [A-Z]`
  DEPEND2_SETUP="${!DEPEND2_SETUPVAR}" 
  if [ -z "${DEPEND2_SETUP}" ]; then
    echo setup ${DEPEND2PRD} ${DEPEND2VER_DEFAULT} -q ${DEPEND2QUAL_DEFAULT}
    echo setup ${DEPEND2PRD} ${DEPEND2VER_DEFAULT} -q ${DEPEND2QUAL_DEFAULT}
  fi

  DEPEND2VER=`echo ${DEPEND2_SETUP} | tr -s ' ' | cut -d' ' -f2`
  DEPEND2QUAL=`echo ${DEPEND2_SETUP} | tr -s ' ' | cut -d' ' -f8`

  # hack out "nu" from ART qualifier (for now)
  if [ "${DEPEND2PRD}" == "art" ]; then
    # art should setup "nu" version, but other components won't have this
    cnu=`echo ${DEPEND2QUAL} | grep -c nu`
    if [ $cnu -gt 0 ]; then
      DEPEND2QUAL=`echo ${DEPEND2QUAL} | sed -e 's/:nu//' -e 's/nu://' `
    fi
  fi

  # which gcc ... if dependent on UPS version it should be setup already
  GCCSETUP=`echo ${SETUP_GCC} | tr -s ' ' | cut -d' ' -f2`
  GCCTABLELINE="setupRequired( gcc ${GCCSETUP} )" 

  good_depend=1
  # check for qualifier mismatch
  if [ $ALLOWQUALMISMATCH -eq 0 ]; then
    prdqual=`sortqual $QUALIFIER`
    depqual1=`sortqual $DEPEND1QUAL`
    depqual2=`sortqual $DEPEND2QUAL`
    if [ "$prdqual" != "$depqual1" -o "$prdqual" != "$depqual2" ]; then
      echo " " >&2
      err_red
      echo "$b0: HEY? mismatch qualifiers" >&2
      echo "  $PRODUCT $QUALIFIER ($prdqual)" >&2
      echo "  $DEPENDPRD1 $DEPENDQUAL1 ($depqual1)" >&2
      echo "  $DEPENDPRD2 $DEPENDQUAL2 ($depqual2)" >&2
      err_nocolor
      good_depend=0
    fi
  fi
  if [ ${good_depend} -eq 0 ]; then
    echo " " >&2
    err_red
    echo "$b0: HEY? dependency should require '${DEPENDPRD}'" >&2
    echo "  but that has not been properly setup at this point" >&2
    err_nocolor
    showpurpose=1
    showusage=1
    doexit=4
  fi

  # hack "nu" back into ART qualifier
  if [ "${DEPEND2PRD}" == "art" ]; then
    cnu=`echo ${DEPEND2QUAL} | grep -c nu`  # art should setup "nu" version
    if [ $cnu -eq 0 ]; then
      DEPEND2QUAL="${DEPEND2QUAL}:nu" 
    fi
  fi

}

###############################################################################
# process script args function
###############################################################################
#  longarg "::" means optional arg, if not supplied given as null string
process_args() {

  opterr=/tmp/getopt.err.$$

  TEMP=`getopt -n $b0 -s bash -a \
      --longoptions="help test verbose qual-mismatch-ok \
                     flavor: show-config product: " \
      -o htvf -- "$@" 2> $opterr `
  getoptstat=$?
  eval set --"${TEMP}" 

  dohelp=0
  if [ $getoptstat -ne 0 ]; then
    showusage=1
    doexit=1
    err_red
    echo " " >&2
    cat $opterr >&2
    err_nocolor
  fi
  rm $opterr

  while [ $# -gt 0 ]; do
    case "$1" in
      "--"               ) shift; break                 ;;
      -h | --help        ) dohelp=1                     ;;
      -t | --test        ) ISTEST=1                     ;;
      -v | --verbose     ) let VERBOSE=${VERBOSE}+1     ;;
      -f | --flavor      ) FLAVOR="$2"; shift           ;;
      --show-config      ) showconfig=1                 ;;
      --qual-mismatch-ok ) ALLOWQUALMISMATCH=1          ;;
      --product          ) PRODUCT=$2; shift            ;;
    esac
    shift # eat up this arg
  done

  if [ $dohelp -ne 0 ]; then
    doexit=0
    showpurpose=1
    showusage=1
  else
    # should be at least two positional parameters, the VERSION and QUALIFIER
    VERSION=$1
    QUALIFIER=`sortqual $2`
    if [ $# -lt 2 ]; then
      err_red
      echo " " >&2
      if [ $# -eq 0 ]; then
        echo "$b0: missing <version> and <qualifier> parameters" >&2
        echo "     consider ${VERSION_EXAMPLE} ${QUALIFIER_EXAMPLE}" 
      else
        echo "$b0: missing <qualifier> parameter" >&2
        echo "     consider ${QUALIFIER_EXAMPLE}" 
      fi
      echo " " >&2
      err_nocolor
      doexit=1
      showusage=1
      showconfig=1
    fi
  fi

}

###############################################################################
# main program
###############################################################################

find_ups_top
if [ -n "$THISUPSTOP" ]; then
  if [ -d ${THISUPSTOP}/${PRODUCT} ]; then
    #echo cd ${THISUPSTOP}/${PRODUCT}
         cd $THISUPSTOP/${PRODUCT}
    export HERE=`pwd`
  fi
fi

process_args "$@" 

if [ $VERBOSE -gt 0 ]; then
  echo -e "${OUTGREEN}...done process_args ... start checks ${OUTNOC}" 
fi

check_cwd
check_upsloc
check_depend

PYVERSION=`python --version 2>&1 | cut -d' ' -f2 | cut -d. -f1,2`
PRODUCTUC=`echo $PRODUCT | tr [a-z] [A-Z]`

echo -e "${OUTCYAN}PYVERSION=${PYVERSION} PRODUCTUC=${PRODUCTUC}${OUTNOCOL}" 

# flavor still unset?
if [ -z "$FLAVOR" ]; then
  FLAVOR=`ups flavor ` # not -2
fi

if [ $VERBOSE -gt 0 ]; then
  echo -e "${OUTGREEN}...cross-checks complete${OUTNOC}" 
fi

# print help/config after parsing everything so that we can see what got set
if [ $showpurpose -gt 0 ]; then purpose ; fi
if [ $showusage   -gt 0 ]; then usage   ; fi
if [ $showconfig  -gt 0 ]; then current_config ; fi
echo " " >&2

if [ $doexit -ge 0 ]; then 
  exit $doexit
fi

if [ $VERBOSE -gt 0 ]; then
  echo -e "${OUTGREEN}...start processing${OUTNOC}" 
fi
#
#

# odd case for .version file if NULL, examples have trailing _
FLAVORVF=${FLAVOR}
if [ "$FLAVOR" == "NULL" ]; then FLAVORVF="NULL_"; fi
if [ -z "$FLAVOR" ]; then 
  echo "FLAVOR was null -- can not proceed" 
  exit
fi

# convert colon to dash, sort, remove trailing dash or newline
echo QUALIFIER=${QUALIFIER}
QPATH=`echo $QUALIFIER | tr ":" "\n" | sort | tr "\n" "-" | sed -e 's/-$//' | tr -d "\n" `
echo QPATH=${QPATH}

#echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" 
echo "prepare to generate ups framework for" 
echo "   setup ${PRODUCT} ${VERSION} -f ${FLAVOR} -q ${QUALIFIER}" 
#echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" 

for p in ${VERSION}/${FLAVOR}-${QPATH}/ups \
         ${VERSION}/${FLAVOR}-${QPATH}/build \
         ${VERSION}/source \
         ${VERSION}.version
do
  if [ ! -d $p ]; then mkdir -p $p; fi
done

tableFile=${VERSION}/${FLAVOR}-${QPATH}/ups/${PRODUCT}.table
versionFile=${VERSION}.version/${FLAVORVF}-${QPATH}

#
# create the table file
#
cat > ${tableFile} <<EOF
File=Table
Product=${PRODUCT}
#*************************************************
# Starting Group definition

Group:

Flavor=${FLAVOR}
Qualifiers="${QUALIFIER}" 

Common:
   Action=setup
      proddir()
      setupenv()
      setupRequired( ${DEPEND1PRD}  ${DEPEND1VER} -q ${DEPEND1QUAL} )
      setupRequired( ${DEPEND2PRD}  ${DEPEND2VER} -q ${DEPEND2QUAL} )
      ${GCCTABLELINE}

      envSet(${PRODUCTUC}_DIR, \${UPS_PROD_DIR})
      envSet(${PRODUCTUC}_FQ, ${FLAVOR}-${QPATH})
      envSet(${PRODUCTUC}_FQ_DIR, \${UPS_PROD_DIR}/\${${PRODUCTUC}_FQ})
      envSet(${PRODUCTUC}_VERSION, ${VERSION})
      envSet(${PRODUCTUC}_SOURCE, \${UPS_PROD_DIR}/source)

      pathAppend(LD_LIBRARY_PATH, \${UPS_PROD_DIR}/\${${PRODUCTUC}_FQ}/lib)
      pathAppend(PATH, \${UPS_PROD_DIR}/\${${PRODUCTUC}_FQ}/bin)
      pathAppend(PYTHONPATH, \${UPS_PROD_DIR}/\${${PRODUCTUC}_FQ}/lib/python${PYVERSION}/site-packages)

End:
# End Group definition
#*************************************************
EOF

#
# create the version file, if it doesn't exist
#
if [ ! -f ${versionFile} ]; then
cat > ${versionFile} <<EOF
FILE = version
PRODUCT = ${PRODUCT}
VERSION = ${VERSION}

#*************************************************
EOF
fi

iam=`whoami`
if [ "$iam" == "nusoft" ]; then
  altiam=`klist | grep "Default principal" | cut -d':' -f2 | cut -d'@' -f1 | tr -d ' ' `
  if [ -n "$altiam" ]; then
    iam=${altiam}
    echo "i am \"${iam}\"" 
  fi
fi
nowGMT=`date -u "+%Y-%m-%d %H:%M:%S"`

nf=`grep QUALIFIERS ${versionFile} | grep -c \"${QUALIFIER}\"`
if [ $nf -ne 0 ]; then
  echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" 
  echo "${versionFile} already has an entry for \"${QUALIFIER}\"" 
  echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" 
else
#
# add this version to the version file
#
cat >> ${versionFile} <<EOF
#
FLAVOR = ${FLAVOR}
QUALIFIERS   = "${QUALIFIER}" 
  DECLARER   = ${iam}
  DECLARED   = ${nowGMT} GMT
  MODIFIER   = ${iam}
  MODIFIED   = ${nowGMT} GMT
  PROD_DIR   = ${PRODUCT}/${VERSION}
  UPS_DIR    = ${FLAVOR}-${QPATH}/ups
  TABLE_FILE = ${PRODUCT}.table
#
#*************************************************
EOF
fi

# optional checkout
if [ "$CHECKOUT" == "true" -o "$CHECKOUT" == "ssh" ]; then
  # alias/function doesn't carry into sub-shell
  # setup dk2nu $VERSION -f $FLAVOR -q $QUALIFIER
  # setup == source `$UPS_DIR/bin/ups setup <args>`
  #     'ups setup' creates a script that must be sourced
  source `${UPS_DIR}/bin/ups setup dk2nu $VERSION -f $FLAVOR -q $QUALIFIER`
  cd $DK2NU_DIR
  echo "starting checkout, currently in:" 
  echo "   `pwd`" 
  echo svn checkout $FULLSVNPATH > svn.checkout.log 2>&1
  svn checkout $FULLSVNPATH > svn.checkout.log 2>&1
fi

# end-of-script

make_professor_install

#! /usr/bin/env bash

YODA_VER=1.6.6
EIGEN_VER=3.3.3
PROF_VER=2.2.2beta2
PROF_QUAL="debug:e10" 

SKIP_WXPYTHON=1

# source /geant4/app/users/altups/setup
# export PRODUCTS=${PRODUCTS}:/geant4/app/externals:/grid/fermiapp/products/common/db:/grid/fermiapp/products/larsoft

# # need to setup within the script rather than rely on environment
# #  ... seems not to correctly work otherwise
# setup professor ${PROF_VER} -q ${PROF_QUAL}

# shorter ...
export PROFINSTALL=${PROFESSOR_FQ_DIR}

# needed during build ... but UPS has munged this
export PYTHON_VERSION=`python --version 2>&1 | cut -d' ' -f2 | cut -d. -f1,2`
export PYTHON_SITEPKG=${PROFINSTALL}/lib/python${PYTHON_VERSION}/site-packages

if [[ -z "${PROFESSOR_FQ_DIR}" || ! -d ${PROFESSOR_FQ_DIR} ]]; then
  echo -e "${OUTRED}no \${PROFESSOR_FQ_DIR} defined" 
  echo -e "or directory ${PROFESSOR_FQ_DIR} doesn't exist ${OUTNOCOL}" 
  exit 1
fi

if [ -z "${PROFESSOR_SOURCE}" ]; then
  export PROFESSOR_SOURCE=${PROFESSOR_DIR}/source
fi
if [ ! -d "${PROFESSOR_SOURCE}" ]; then
  mkdir -p ${PROFESSOR_SOURCE}
fi

#
# pip = pip installs python
#   uses caches /tmp/pip-*
#
rm -rf /tmp/pip-*

# cython
# might take a while ... compiling stuff
echo -e "${OUTGREEN}checking cython...${OUTNOCOL}" 

cd ${PROFESSOR_SOURCE}

#echo ${PYTHON_SITEPKG}/Cython
if [[ ! -d ${PYTHON_SITEPKG}/Cython || ! -f ${PROFESSOR_FQ_DIR}/bin/cython ]]; then
  echo -e "${OUTGREEN}...building cython...${OUTNOCOL}" 
  pip install --install-option="--prefix=${PROFINSTALL}" cython \
              > cython.pip.log 2>&1
  if [ $? -ne 0 ]; then
    echo -e "${OUTRED}cython installed failed${OUTNOCOL}" 
    exit 2
  fi
fi
CVERSION=`cython --version 2>&1`
cython --version > /dev/null 2>&1
if [ $? -ne 0 ]; then
  echo -e "${OUTRED}cython --version failed${OUTNOCOL}" 
  exit 2
fi
echo -e "${OUTGREEN}cython version (${CVERSION}) complete ${OUTNOCOL}" 

# yoda
echo -e "${OUTGREEN}checking yoda...${OUTNOCOL}" 

cd ${PROFESSOR_SOURCE}

if [ ! -f YODA-${YODA_VER}.tar.gz ]; then
  echo -e "${OUTGREEN}...download yoda...${OUTNOCOL}" 
  curl -O  https://www.hepforge.org/archive/yoda/YODA-${YODA_VER}.tar.gz
  tar xzf YODA-${YODA_VER}.tar.gz
fi

if [ ! -f ${PROFINSTALL}/lib/libYODA.so ]; then
  echo -e "${OUTGREEN}...configure yoda...${OUTNOCOL}" 
  cd YODA-${YODA_VER}

  ./configure --prefix=${PROFINSTALL} > yoda.config.log 2>&1
  if [ $? -ne 0 ]; then
    echo -e "${OUTRED}yoda config failed${OUTNOCOL}" 
    exit 2
  fi

  echo -e "${OUTGREEN}...build yoda...${OUTNOCOL}" 
  make -j2 > yoda.build.log 2>&1
  if [ $? -ne 0 ]; then
    echo -e "${OUTRED}yoda build failed${OUTNOCOL}" 
    exit 2
  fi

  echo -e "${OUTGREEN}...install yoda...${OUTNOCOL}" 
  make -j2 install > yoda.install.log 2>&1
  if [ $? -ne 0 ]; then
    echo -e "${OUTRED}yoda installed failed${OUTNOCOL}" 
    exit 2
  fi

fi

echo -e "${OUTGREEN}yoda complete${OUTNOCOL}" 

# eigen
echo -e "${OUTGREEN}checking eigen...${OUTNOCOL}" 

cd ${PROFESSOR_SOURCE}

if [ ! -f eigen_${EIGEN_VER}.tar.gz ]; then
  echo -e "${OUTGREEN}..download eigen...${OUTNOCOL}" 
  curl -O https://bitbucket.org/eigen/eigen/get/${EIGEN_VER}.tar.gz
  EIGENHEAD=`tar -tzf 3.3.3.tar.gz | cut -d/ -f1 | sort -u`
  mv ${EIGEN_VER}.tar.gz eigen_${EIGEN_VER}.tar.gz
  tar xzf eigen_${EIGEN_VER}.tar.gz
  mv ${EIGENHEAD} eigen_${EIGEN_VER}
fi

# headers only
# cmake method doesn't seem to work ... so just copy ...

if [ ! -d ${PROFINSTALL}/include/Eigen ]; then
  echo -e "${OUTGREEN}...install eigen...${OUTNOCOL}" 
  cp -a eigen_${EIGEN_VER}/Eigen ${PROFINSTALL}/include > eigen.cp.log 2>&1
  if [ $? -ne 0 ]; then
    echo -e "${OUTRED}eigen installed failed${OUTNOCOL}" 
    exit 2
  fi
fi

echo -e "${OUTGREEN}eigen complete${OUTNOCOL}" 

# iMinuit
echo -e "${OUTGREEN}checking iminuit...${OUTNOCOL}" 

cd ${PROFESSOR_SOURCE}

# git clone https://github.com/iminuit/iminuit
# cd iminuit

if [ ! -d ${PYTHON_SITEPKG}/iminuit ]; then
  echo -e "${OUTGREEN}...build iminuit...${OUTNOCOL}" 
  pip install --install-option="--prefix=${PROFINSTALL}" iminuit \
               > iminuit.pip.log 2>&1
  if [ $? -ne 0 ]; then
    echo -e "${OUTRED}iminuit installed failed${OUTNOCOL}" 
    exit 2
  fi
fi
echo -e "${OUTGREEN}iminuit complete${OUTNOCOL}" 

# Matplotlib
# takes a while, installs other "stuff" 
echo -e "${OUTGREEN}checking matplotlib...${OUTNOCOL}" 

cd ${PROFESSOR_SOURCE}

if [ ! -d ${PYTHON_SITEPKG}/matplotlib ]; then
  echo -e "${OUTGREEN}...building matplotlib...${OUTNOCOL}" 
  pip install --install-option="--prefix=${PROFINSTALL}" matplotlib \
              > matplotlib.pip.log 2>&1
  if [ $? -ne 0 ]; then
    echo -e "${OUTRED}matplotlib installed failed${OUTNOCOL}" 
    exit 2
  fi
fi
echo -e "${OUTGREEN}matplotlib complete${OUTNOCOL}" 

# sympy
echo -e "${OUTGREEN}checking sympy...${OUTNOCOL}" 

cd ${PROFESSOR_SOURCE}

if [ ! -d ${PYTHON_SITEPKG}/sympy ]; then
  echo -e "${OUTGREEN}...building sympy...${OUTNOCOL}" 
  pip install --install-option="--prefix=${PROFINSTALL}" sympy \
              > sympy.pip.log 2>&1
  if [ $? -ne 0 ]; then
    echo -e "${OUTRED}sympy installed failed${OUTNOCOL}" 
    exit 2
  fi
fi
echo -e "${OUTGREEN}sympy complete${OUTNOCOL}" 

# wxWindows
echo -e "${OUTGREEN}checking wxpython / wxWindows...${OUTNOCOL}" 

cd ${PROFESSOR_SOURCE}

if [ ${SKIP_WXPYTHON} -eq 1 ]; then
  echo -e "${OUTCYAN}skip wxpython ....${OUTNOCOL}" 
else
if [ ! -d ${PYTHON_SITEPKG}/wxpython ]; then
  echo -e "${OUTGREEN}...building wxpython...${OUTNOCOL}" 
  pip install --install-option="--prefix=${PROFINSTALL}" wxpython \
              > wxpython.pip.log
  if [ $? -ne 0 ]; then
    echo -e "${OUTRED}wxpython installed failed${OUTNOCOL}" 
    #exit 2
    echo -e "${OUTCYAN}wxpython installed failed ... continue anyway${OUTNOCOL}" 
  fi
fi
fi
echo -e "${OUTGREEN}wxpython complete${OUTNOCOL}" 

# professor itself
echo -e "${OUTGREEN}checking professor...${OUTNOCOL}" 

cd ${PROFESSOR_SOURCE}

if [ ! -f Professor-${PROF_VER}.tar.gz ]; then
  echo -e "${OUTGREEN}...download professor...${OUTNOCOL}" 
  curl -O https://www.hepforge.org/archive/professor/Professor-${PROF_VER}.tar.gz
  tar xzf Professor-${PROF_VER}.tar.gz
fi

cd Professor-${PROF_VER}

echo -e "${OUTGREEN}...build professor...${OUTNOCOL}" 
CXXFLAGS="-I${PROFINSTALL}/include -O4" make all > professor.build.log 2>&1
if [ $? -ne 0 ]; then
  echo -e "${OUTRED}professor build failed${OUTNOCOL}" 
  exit 2
fi

echo -e "${OUTGREEN}...install professor...${OUTNOCOL}" 
make install PREFIX=$PROFINSTALL > professor.install.log 2>&1
if [ $? -ne 0 ]; then
  echo -e "${OUTRED}professor install failed${OUTNOCOL}" 
  exit 2
fi

# end-of-script