#!/bin/sh
# PURPOSE:     	createCalibMap - creates an HTML calibmap from an OCA rules file
# AUTHOR:  	Reinhard Hanuschik, ESO-DMO
# VERSION:	1.0 -- created
#		1.0.1- improvements for multiple raw_type definitions; match rule includes PRO.CATG (2011-10-14)
#		1.0.2- added: comments; improved check for multiple cell entries; dfosRLSmassage.py for option -C
#		1.0.3- slightly changed handling of validity_date for CALSELECTOR (2011-11-25)
#		1.1 -- added support for CALSELECTOR validity (2011-12-12)
#		1.2 -- added: support for bulk creation of calib maps (2012-01-10)
#		1.3 -- DO_CLASS added for CALSELECTOR; row-numbers added for products; PACK_DIR suppressed; improved navigation (2012-02-09)
#		1.3.1- modified handling for RASSOCs in CALSELECTOR (2012-03-16)
#		1.4 -- replace stargate1 by $DFO_WEB_SERVER (2013-10-30)
#		1.4.1- replace 'switch' by 'change' in awk commands (for OS upgrade) (2014-02-17)
#		2.0 -- adapted to the needs of calSelector v2.0; supports step2 cascades; includes recipe row (2014-11-13)
#		2.0.1- added: check for calSelector raw2master files existing (2015-01-26)
#		2.0.2- minor bug fix (2015-02-06)
#		2.1 -- marks EXPOSE_TO_CALSELECTOR=T (exceptional case) (2017-06-27)
#		2.1.1- transfers list_static_mcals_<instr>.txt to qcweb server (2018-06-25)
#
# PARAMETERS:	-r <pathname RLS file> 
#		-m <mode> 
# TOOLS CALLED: dfosRLSmassage.py
# CONFIG:	config.createCalibMap under path to RLS file 
#		config.createCalibMap.calsel for CALSELECTOR files
# OUTPUT:	calib maps called cascade_<inst>_<mode>.html	
# supported: DFOS_OPS | CALCHECKER | CALSELECTOR 
# upload of list_static_mcals to qcweb for OPSHUB environment
# =========================================================================
TOOL_VERSION="2.1.1"
TOOL_NAME="createCalibMap"	#only needed during testing the new version

rm -f $TMP_DIR/cm_rawTypes* $TMP_DIR/cm_rawTypeRules $TMP_DIR/cm_groupRules $TMP_DIR/cm_assocRules*

WEB_DIR="/home/qc/qc/ALL/OCA"		# target dir for OCA rules and calibMap on  web server
WEB_URL="http://www.eso.org/qc/ALL/OCA"	# URL of $WEB_DIR

# ==============================================================
# 0.1 usage
# ==============================================================
cat > $TMP_DIR/usage <<EOT
USAGE: createCalibMap [-r <pathname of RLS file> [-d <start-date>] [-C|-A|-n] [-m <ins_mode> [-E <raw_type>] ] [-D]] | [-X|-h|-v]
  tool to create calibration maps for specified OCA rules file

 -h this help
 -v display version and exit

 -r <pathname of OCA RLS file> (default: $DFO_CONFIG_DIR/OCA/${DFO_INSTRUMENT}.RLS)
 -m <ins_mode> specified ins_mode, defined in config file; optional, default: ALL

 -n no scp, only local version (for debugging)
 -A create calibmap for all modes as configured
 -C compile the OCA rules under the specified path
 -D display raw_types and pro_catgs for this mode and exit
 -E <raw_type> for selected science raw_type, analyze and display: all depending mcalibs and gencalibs, plus their raw_types

 -X call a menue and create all configured calibmaps 

EOT

# ==============================================================
# 0.2 Options
# ==============================================================

CREATE_ALL=NO
DISP_FLAG=NO
EXPLORE=NO
COMPILE=NO
SCP=YES
CREATE_COMPLETE=NO

while getopts r:m:nACDXE:hv OPTION
do
	case "$OPTION" in
	 h ) cat $TMP_DIR/usage ; exit ;;
         v ) echo $TOOL_VERSION ; exit ;;
	 m ) INS_MODE=$OPTARG ;;
	 r ) RLS_FILE=$OPTARG ;;
	 n ) SCP=NO ;;
	 A ) CREATE_ALL=YES ;;
	 X ) CREATE_COMPLETE=YES ;;
	 C ) COMPILE=YES ;;
	 D ) DISP_FLAG=YES ;;
	 E ) EXPLORE=YES ; RAWTYPE=$OPTARG ;;
	 * ) cat $TMP_DIR/usage ; exit ;;
	esac
done

# ==============================================================
# 0.3 Special case X: create menue 
# ==============================================================

INSTRUMENT=${DFO_INSTRUMENT}

if [ $CREATE_COMPLETE = YES ]
then
	rm -f $TMP_DIR/cs_menue
	echo "You have the following calibration maps:"
	if [ -s $DFO_CONFIG_DIR/OCA/config.createCalibMap ]
	then
		echo "1   - DFOS_OPS		(\$DFO_CONFIG_DIR/OCA/${DFO_INSTRUMENT}.RLS)" | tee -a $TMP_DIR/cs_menue
	else
		echo "x   - DFOS_OPS:		not configured"
	fi
	
	if [ -s $DFO_CONFIG_DIR/CALCHECK/OCA/config.createCalibMap ]
	then
		echo "2   - CALCHECKER	(\$DFO_CONFIG_DIR/CALCHECK/OCA/${DFO_INSTRUMENT}.RLS)" | tee -a $TMP_DIR/cs_menue
	else
		echo "x   - CALCHECKER:	not configured"
	fi

	if [ ! -s $DFO_CONFIG_DIR/CALSELECTOR ]
	then
		echo "x   - CALSELECTOR:	not configured"
	else
		echo ""
		grep "^START_DATE" $DFO_CONFIG_DIR/CALSELECTOR/config.createCalibMap.calsel | awk '{print NR,"- CALSELECTOR_"$0}' | sed "s/START_DATE[[:space:]]*//" | sed "s/^.*/3.&/" | sed "s/\&\&//g" | tee -a $TMP_DIR/cs_menue
	fi

# for special cases; normally this is not needed
	INSTRUMENT=`grep "^INSTRUMENT" $DFO_CONFIG_DIR/CALSELECTOR/config.createCalibMap.calsel | awk '{print $2}'`
	if [ Q$INSTRUMENT = Q ]
	then
		INSTRUMENT=${DFO_INSTRUMENT}
	fi

# special check for CALSELECTOR
	rm -f $TMP_DIR/ha_versions
	grep "^START_DATE" $DFO_CONFIG_DIR/CALSELECTOR/config.createCalibMap.calsel | awk '{print $2}' > $TMP_DIR/ha_versions
	if [ -s $TMP_DIR/ha_versions ]
	then
		for S in `cat $TMP_DIR/ha_versions`
		do
			if [ ! -s $DFO_CONFIG_DIR/CALSELECTOR/$S/${INSTRUMENT}_raw2master.${S}.RLS ]
			then
				echo "***ERROR: $S/${INSTRUMENT}_raw2master.${S}.RLS is configured in $DFO_CONFIG_DIR/CALSELECTOR/config.createCalibMap.calsel but does not exist.
Fix your configuration and then try again."
				exit -1
			fi
		done
	fi

	echo "
Enter your choice (first number), or 'A' for 'all', or '.' to exit:"
	read MENUE

	rm -f $TMP_DIR/cs_menuelist
	if [ Q$MENUE = Q. ] || [ Q$MENUE = Q ]
	then
		exit
	elif [ $MENUE = A ]
	then
		cat $TMP_DIR/cs_menue | awk '{print $1}' > $TMP_DIR/cs_menuelist
	else
		CHECK_MENUE=`grep "^$MENUE " $TMP_DIR/cs_menue | head -1`
		if [ "Q$CHECK_MENUE" = Q ]
		then
			echo "Option $MENUE not found."
			exit
		fi

		echo $MENUE > $TMP_DIR/cs_menuelist
	fi

# NUM_MENUE=1: we offer a dialog; >1: we don't do
	NUM_MENUE=`cat $TMP_DIR/cs_menuelist | wc -l`
	if [ $NUM_MENUE != 1 ]	
	then
		echo "
We call
	$TOOL_NAME -r <CONFIG> -A
	$TOOL_NAME -r <CONFIG>
for all configured calib maps.
Hit return to start:
"
		read input
	fi

	for M in `cat $TMP_DIR/cs_menuelist`
	do
		ITEM=`grep "^$M " $TMP_DIR/cs_menue | awk '{print $3}' | sed "s/_.*//"`
		if [ $ITEM != CALSELECTOR ]
		then
			CONFIG=`grep "^$M " $TMP_DIR/cs_menue | awk '{print $4}' | sed "s/(//" | sed "s/)//"`
		else
			CONFIG=`grep "^$M " $TMP_DIR/cs_menue | awk '{print $3}' | sed "s/^.*_//"`
			#CONFIG="$DFO_CONFIG_DIR/CALSELECTOR/$CONFIG/${DFO_INSTRUMENT}_raw2raw.$CONFIG.RLS"
			CONFIG="$DFO_CONFIG_DIR/CALSELECTOR/$CONFIG/${DFO_INSTRUMENT}_raw2master.$CONFIG.RLS"
		fi

		if [ $NUM_MENUE = 1 ]	
		then
			echo "
We call
	$TOOL_NAME -r $CONFIG -A
then
	$TOOL_NAME -r $CONFIG
Hit return to start:
"
			read input
		fi
			
		CONFIG=`eval "echo $CONFIG"`
		$TOOL_NAME -r $CONFIG -A <<EOT

EOT
		$TOOL_NAME -r $CONFIG
	done
	exit
fi

# ==============================================================
# 0.4 Read configuration and prepare
# ==============================================================

if [ Q$INS_MODE = Q ]
then
	INS_MODE=ALL
fi

if [ Q$RLS_FILE = Q ] && [ $COMPILE = NO ]
then
	RLS_FILE=$DFO_CONFIG_DIR/OCA/${DFO_INSTRUMENT}.RLS
	echo "No rules file specified, default chosen: \$DFO_CONFIG_DIR/OCA/${DFO_INSTRUMENT}.RLS. Hit return:"
	read input
elif [ Q$RLS_FILE = Q ] && [ $COMPILE = YES ]
then
	RLS_FILE=$DFO_CONFIG_DIR/OCA/${DFO_INSTRUMENT}.RLS
	RLS_PATH=`dirname $RLS_FILE`
	echo "Default RLS_path: $RLS_PATH."
fi
RLS_PATH=`dirname $RLS_FILE`

if [ ! -s $RLS_FILE ]
then
	echo "***ERROR: $RLS_FILE not found. Exit."
	exit
fi

if [ ! -s $RLS_PATH/config.createCalibMap ]
then
	echo "***ERROR: config file $RLS_PATH/config.createCalibMap expected but not found. Can't do. Exit."
	exit -1
fi

INFO_FILE="$RLS_PATH/info.createCalibMap"

cd $RLS_PATH
NAME=`grep "^NAME" $RLS_PATH/config.createCalibMap | awk '{print $2}'`
if [ Q$NAME = Q ]
then
	echo "***ERROR: no NAME specified in $RLS_PATH/config.createCalibMap, don't know what syntax to follow."
	exit 0
fi

if [ $NAME = CALSELECTOR ]
then
	START_DATE=`basename $RLS_PATH`
# some plausibility checks
	LENGTH=`echo $START_DATE | awk '{print length}'`
	BEGIN=`echo $START_DATE | cut -c 1,2`
	if [ $LENGTH != 10 ] || [ $BEGIN != 20 ]
	then
		echo "***ERROR: $START_DATE doesn't seem to be a date. Check and start again."
		exit
	else
# config.createCalibMap.calsel is one level higher than $RLS_PATH, i.e. in $DFO_CONFIG_DIR/CALSELECTOR
		RLS_PATH1=`dirname $RLS_PATH`
		if [ -s ${RLS_PATH1}/config.createCalibMap.calsel ]
		then
			CHECK_EXIST=`grep "^START_DATE" ${RLS_PATH1}/config.createCalibMap.calsel | grep $START_DATE | awk '{print $1}'`
			if [ "Q$CHECK_EXIST" = Q ]
			then
				echo "***ERROR: $START_DATE is not included in ${RLS_PATH1}/config.createCalibMap.calsel. Please fix and try again."
				exit -1
			fi
		else
			echo "***ERROR: ${RLS_PATH1}/config.createCalibMap.calsel does not yet exist. Create and try again."
			exit -1
		fi
	fi
fi

# KEEP_SHORT
KEEP_SHORT=`grep "^KEEP_SHORT" $RLS_PATH/config.createCalibMap | awk '{print $2}'`
if [ Q$KEEP_SHORT != QNO ]
then
	KEEP_SHORT=YES
fi
	
SHORT_CHAR=`grep "^SHORT_CHAR" $RLS_PATH/config.createCalibMap | awk '{print $2}'`
if [ Q$SHORT_CHAR = Q ]
then
	SHORT_CHAR=15
fi

# Display options (DO_CLASS); type of association (RAW2RAW, RASSOC)
case $NAME in
 CALCHECKER  ) RAW2RAW=YES ; RASSOC=NO;  DO_CLASS=NO ;;
 #R2R: CALSELECTOR ) RAW2RAW=YES ; RASSOC=YES; DO_CLASS=YES ;;
 CALSELECTOR ) RAW2RAW=NO  ; RASSOC=NO; DO_CLASS=YES ;;
 DFOS_OPS    ) RAW2RAW=NO  ; RASSOC=NO;  DO_CLASS=YES ;; 
 *          )  RAW2RAW=NO  ; RASSOC=NO;  DO_CLASS=YES ;;
esac


# ==============================================================
# 0.4 procedure getBetween
# $1: $MATCH_RULE
# ==============================================================
getBetween(){
echo "$1" |\
 sed "s/and inputFile/&FROM/" |\
 sed "s/and inputFileFROM.*MJD-OBS between inputFile.MJD-OBS */BETWEEN/" |\
 sed "s/- */-/"g | sed "s/+ */+/"g |\
 sed "s/ and inputFile.MJD-OBS *//g" |\
 sed "s/and *MJD-OBS *tryBetween *inputFile.MJD-OBS */TRYBETWEEN/" |\
 sed "s/ and inputFile.*TRYBETWEEN/ TRYBETWEEN/" |\
 sed "/MJD-OBS/s/and inputFile.*/OTHER/" |\
 sed "s/and inputFile.*/NONE/" |\
 awk '{print $2,$3}' | tr " " "\012" > $TMP_DIR/cm_check_between 
}

# ==============================================================
# 1.0 Higher level options
# 1.1 -A: create all calibmaps for sub-cascades
#     Sub-cascades: these are 
#     essentially self-contained cascades which might overlap 
#     only in a few (e.g. detector-type) raw_types; overview is much easier if
#     the instrument cascade is split into sub-cascades
#     Sub-cascades are defined in config.createCalibMap
# ==============================================================

if [ $CREATE_ALL = YES ]
then
	echo "We now create all calibmaps for the configured modes in $RLS_PATH/config.createCalibMap:
"
	grep "^ALL_MODES" $RLS_PATH/config.createCalibMap | awk '{print $2}' | grep -v "^DET$" | grep -v "^DET[[:space:]]" > $TMP_DIR/cm_allmodes
	cat $TMP_DIR/cm_allmodes

	echo "
OK (Y/N; default: Y)?"
	read ALL_MODES
	if [ Q$ALL_MODES != QN ]
	then
		for M in `cat $TMP_DIR/cm_allmodes`
		do
			$TOOL_NAME -r $RLS_FILE -m $M
		done
	else
		echo "Exit."
	fi
	echo "... done."
	exit
fi

# ==============================================================
# 1.2 -C: COMPILE
# If any of the OCA files has been modified, it is necessary to
# compile them to become the RLS file. Also, you need to do this
# if a macro has been modified or added.
# ==============================================================

if [ $COMPILE = YES ]
then
	echo "We compile the OCA files under $RLS_PATH ..." 
	cd $RLS_PATH
	if [ $NAME = DFOS_OPS ] || [ $NAME = CALCHECKER ]
	then
		if [ -s ${DFO_INSTRUMENT}.h ]
		then
# this is the standard precompilation for OCA files, requires complete set of .h files
			rm -f ${DFO_INSTRUMENT}.RLS
			if [ -s $DFO_BIN_DIR/dfosRLSmassage.py ]
			then
				gcc -E "${DFO_INSTRUMENT}.h" | grep -v "^#" | grep -v "^$" | dfosRLSmassage.py > ${DFO_INSTRUMENT}.RLS
			else
				gcc -E "${DFO_INSTRUMENT}.h" | grep -v "^#" | grep -v "^$" > ${DFO_INSTRUMENT}.RLS
			fi
			echo "Check out $RLS_FILE."
		else
			echo "No ${DFO_INSTRUMENT}.h found under $RLS_PATH, can't compile."
		fi
	else
# this is the C preprocessing of the DEF macros defined in $RLS_FILE
		cp $RLS_FILE ${RLS_FILE}_old
		cpp -P $RLS_FILE ${RLS_FILE}_preprocessed
		if [ -s ${RLS_FILE}_preprocessed ]
		then
			cp ${RLS_FILE}_preprocessed ${RLS_FILE}
			echo "Check out the modified ${RLS_FILE}. 
Find the old file as ${RLS_FILE}_old.
"
		else
			echo "No new RLS file created. Check out for errors."
		fi
	fi
	exit
fi

# ==============================================================
# 2. PARSER
# 2.1 Parse RLS to find all possible raw_types
# ==============================================================

if [ $SCP = NO ]
then
	echo "Option -n: no scp; only local creation of calib map; hit return to continue:"
	read input
fi

echo "
INS_MODE=${INS_MODE}"

echo "- Parse $RLS_FILE: 
   classification ..."
cat $RLS_FILE |
 awk '{
  if ( $1 == "if" ) { change=1; doclass="none"; packdir="none" }
  if ( change == 1 && $1 == "RAW.TYPE" ) { rawtype=$3 }
  if ( change == 1 && $1 == "DO.CLASS" ) { doclass=$3 }
  if ( change == 1 && $1 == "PACK.DIR" ) { packdir=$3 }
  if ( change == 1 && $1 == "CATG" )     { catg=$3; print rawtype, doclass, packdir, catg; change=0 }
 }' change=0 doclass="none" packdir="none" |\
 sed "s/\"//g" |\
 sed "s/;//"g |\
 sed "/^$/d" \
 > $TMP_DIR/cm_rawTypes

# check for EXPOSE_TO_CALSELECTOR
cat $RLS_FILE |
 awk '{
  if ( $1 == "if" ) { change=1 }
  if ( change == 1 && $1 == "RAW.TYPE" ) { rawtype=$3 }
  if ( change == 1 && $1 == "EXPOSE_TO_CALSELECTOR=T;" ) { print rawtype, "EXPOSE_TO_CALSELECTOR=T"; change=0 }
 }' change=0 |\
 sed "s/\"//g" |\
 sed "s/;//"g |\
 sed "/^$/d" \
 > $TMP_DIR/cm_rawTypes2

# check for ACQ configured as CALIB and send warning
rm -f $TMP_DIR/cm_acqWarning
grep ACQ $TMP_DIR/cm_rawTypes | grep CALIB > $TMP_DIR/cm_acqWarning
if [ -s $TMP_DIR/cm_acqWarning ]
then
	echo "   WARNING: ACQUISITION(s) found configured as CATG = \"CALIB\". You may prefer to configure them as CATG = \"ACQUISITION\":"
	cat $TMP_DIR/cm_acqWarning
fi

# find and store rules
SHORT_CHAR1=`echo $SHORT_CHAR | awk '{print $1+1}'`
cat $RLS_FILE |
 awk '{
  if ( $1 == "if" ) { change=1 }
  if ( change == 1 && $1 != "{" && $1 != "then" ) { classif=$0 }
  if ( change == 1 && $1 == "{" ) { change=2 }
  if ( change == 2 && $1 == "RAW.TYPE" ) {tag=""; raw_short=substr($3,1,short); if (length(raw_short)<length($3)) tag="..."; print $3": "classif; change=0}
 }' short=$SHORT_CHAR1 |\
 sed "s/TITLE */TITLE/" |\
 sed "s/\"//"g |\
 sed "s/if //" |\
 sed "s/ then//" |\
 sed "s/then//" |\
 sed "s/TITLE/\"/g" |\
 sed "s/;//"g |\
 sed "s/  //"g \
 > $TMP_DIR/cm_rawTypeRules

# check for multiple raw_types and consolidate (support multiple DO_CLASS as comma-separated list)
PREV=PREV
rm -f $TMP_DIR/cm_rawTypes1 $TMP_DIR/cm_rawTypeRules1
for RT in `cat $TMP_DIR/cm_rawTypes | awk '{print $1}'`
do
	if [ $RT = $PREV ]
	then
		continue
	fi
	CHECK_MULT=`grep "^$RT " $TMP_DIR/cm_rawTypes | awk '{print $1}' | wc -l`

# CALSELECTOR raw2master: we *always* suppress RT which are not listed
	if [ $INS_MODE != ALL ] || [ $NAME = "CALSELECTOR" ]
	then
		CHECK_CONFIG=`grep "^MODE" $RLS_PATH/config.createCalibMap | grep "[[:space:]]${RT}[[:space:]]" | grep "[[:space:]]${INS_MODE}$" | awk '{print $2}'`
	fi

	if [ $CHECK_MULT != 1 ]
	then
		if [ Q$CHECK_CONFIG != Q ]
		then
			echo "***INFO: raw_type $RT defined more than once, its properties are cumulated"
		fi
		DO_CLASS_TAG=`grep "^$RT " $TMP_DIR/cm_rawTypes | awk '{print $2}' | sort -u | tr "\012" "," | sed "s/,$//"`
		RT_RULE=`grep  "^$RT: " $TMP_DIR/cm_rawTypeRules | sed "s/^$RT: //" | sort -u | sed "s/^.*/[[&]] OR/" | tr "\012" " " | sed "s/OR $//"`
		INDICATOR="<font size=1 color=red><a title=\"multiple definition\"> M </a></font>"
	else
		DO_CLASS_TAG=`grep "^$RT " $TMP_DIR/cm_rawTypes | awk '{print $2}'`
		RT_RULE=`grep  "^$RT: " $TMP_DIR/cm_rawTypeRules | sed "s/^$RT: //"`
		INDICATOR=""
	fi
	OTHER=`grep "^$RT " $TMP_DIR/cm_rawTypes | awk '{print $3,$4}' | head -1`
	echo "$RT $DO_CLASS_TAG $OTHER" >> $TMP_DIR/cm_rawTypes1
	echo "<a title=\"$RT: $RT_RULE\">$RT</a> $INDICATOR" >> $TMP_DIR/cm_rawTypeRules1

	PREV=$RT
done
mv $TMP_DIR/cm_rawTypes1 $TMP_DIR/cm_rawTypes
sed -i -e "/^$/d" $TMP_DIR/cm_rawTypes
mv $TMP_DIR/cm_rawTypeRules1 $TMP_DIR/cm_rawTypeRules

# =====================================================================
# 2.2 Select raw_types by mode if defined and supported in config file;
#     CALSELECTOR: do this always              
# =====================================================================

if [ ${INS_MODE} != ALL ] || [ $NAME = "CALSELECTOR" ]
then
	rm -f $TMP_DIR/cm_insmodes $TMP_DIR/cm_rawTypes1
# check if MODE defined	(unless for CALSELECTOR)
	if [ ${INS_MODE} != ALL ]
	then
		grep "^MODE" $RLS_PATH/config.createCalibMap | grep "[[:space:]]${INS_MODE}$" | awk '{print $2,$3}'  > $TMP_DIR/cm_insmodes
		if [ ! -s $TMP_DIR/cm_insmodes ]
		then
			echo "***ERROR: ${INS_MODE} not defined in MODE section in $RLS_PATH/config.createCalibMap, can't do. Exit."
			exit -1
		fi
	
		CHECK_EXIST=`grep "^ALL_MODES" $RLS_PATH/config.createCalibMap | grep "[[:space:]]${INS_MODE}$"`
		if [ "Q$CHECK_EXIST" = Q ]
		then
			echo "***ERROR: ${INS_MODE} not defined in ALL_MODES section in $RLS_PATH/config.createCalibMap, can't do. Exit."
			exit -1
		fi
	fi

	if [ $NAME = CALSELECTOR ] && [ ${INS_MODE} = ALL ]
	then
		grep "^MODE" $RLS_PATH/config.createCalibMap | awk '{print $2,$3}'  > $TMP_DIR/cm_insmodes
	elif [ ${INS_MODE} != ALL ]
	then
		grep "^MODE" $RLS_PATH/config.createCalibMap | egrep "[[:space:]]DET$|[[:space:]]${INS_MODE}$" | awk '{print $2,$3}'  > $TMP_DIR/cm_insmodes
	fi

	if [ -s $TMP_DIR/cm_insmodes ]
	then
		for RTDO in `cat $TMP_DIR/cm_rawTypes | awk '{print $1"XYZ"$2}'`
		do
			RT=`echo $RTDO | sed "s/XYZ/ /" | awk '{print $1}'`
			DO=`echo $RTDO | sed "s/XYZ/ /" | awk '{print $2}'`
			CHECK_EXIST=`grep "^$RT " $TMP_DIR/cm_insmodes`
			if [ "Q$CHECK_EXIST" != Q ]
			then
				grep "^$RT $DO " $TMP_DIR/cm_rawTypes >> $TMP_DIR/cm_rawTypes1
			fi
		done

		if [ -s $TMP_DIR/cm_rawTypes1 ]
		then
			mv $TMP_DIR/cm_rawTypes1 $TMP_DIR/cm_rawTypes
		fi

# also clean up $TMP_DIR/cm_rawTypeRules
		rm -f $TMP_DIR/cm_rawTypeRules1
		for L in `cat $TMP_DIR/cm_rawTypeRules | sed "s/ /XYZ/g"`
		do
			RT=`echo $L | sed "s/:.*//" | sed "s/^.*\"//"`
			CHECK_RAWTYPE=`grep "^$RT " $TMP_DIR/cm_rawTypes`
			if [ "Q$CHECK_RAWTYPE" != Q ]
			then
				echo "$L" | sed "s/XYZ/ /g" >> $TMP_DIR/cm_rawTypeRules1
			fi
		done

		if [ -s $TMP_DIR/cm_rawTypeRules1 ]
		then
			mv $TMP_DIR/cm_rawTypeRules1 $TMP_DIR/cm_rawTypeRules
		fi
	fi
fi

# =====================================================================
# 2.3 Parse organisation part
# for step 2: sed "s/PRO.CATG==\"//" 
# otherwise   sed "s/RAW.TYPE==\"//"
# =====================================================================
echo "   organisation ..."

cat $RLS_FILE |\
 sed "s/select execute/selectexecute /" |\
 sed "s/group by/groupby/" |\
 awk '{
  if ( $1 == "selectexecute" ) { change=1 }
  if ( change == 1 && $1 == "selectexecute" ) { rawtype=$6; action=$2 }
  if ( change == 1 && $1 == "groupby" ) { rawmatch=$2; grprule="none"$4; print rawtype, rawmatch, grprule, action; change=0 }
 }' change=0 |\
 sed "s/RAW.TYPE==\"//" |\
 sed "s/PRO.CATG==\"//" |\
 sed "s/ none / NONE /" |\
 sed "s/ none/ /" |\
 sed "s/\"//g" |\
 sed "s/(//"g | sed "s/)//"g | sed "s/;//" > $TMP_DIR/cm_groupRules

# =====================================================================
# 2.4 Parse association part
# 2.4.1 $TMP_DIR/cm_assocRules1: raw_type, recipe [, products if any] 
# =====================================================================

# RASSOC=YES: cm_assocRules1 constructed later from cm_assocRules2
case $RASSOC in
	"NO"  ) echo "   association, find products ..." ;;
esac

# $TMP_DIR/cm_assocRules1: action-->raw_type, recipe, product 
cat $RLS_FILE |\
 sed "s/^}/AA}/" |\
 awk '{
  if ( $1 == "action" ) { change=1 ; action=$2; recipe="none"; product="";  }
  if ( change == 1 && $1 == "recipe" )  { recipe=$2 }
  if ( change == 1 && $1 == "product" ) { product=$2; print action, recipe, product }
  if ( change == 1 && $1 == "AA}" ) { print action, recipe, product; change=0 }
 }' change=0 |\
 sort -u |\
 sed "s/;//" > $TMP_DIR/cm_assocRules1

# map action name into raw_type
for A in `cat $TMP_DIR/cm_assocRules1 | awk '{print $1}' | sort -u`
do
	rm -f $TMP_DIR/cm_rawtypelist $TMP_DIR/cm_productlist
	grep "^$A " $TMP_DIR/cm_assocRules1  | awk '{print $1,$2,$3}' > $TMP_DIR/cm_productlist
	grep " ${A}$" $TMP_DIR/cm_groupRules | awk '{print $1}'       > $TMP_DIR/cm_rawtypelist
	for RT in `cat $TMP_DIR/cm_rawtypelist`
	do
		cat $TMP_DIR/cm_productlist | sed "s/^$A /$RT /" >> $TMP_DIR/cm_assocRules100
	done
done
mv $TMP_DIR/cm_assocRules100 $TMP_DIR/cm_assocRules1

# DISP_FLAG=YES: extract PRO.CATGs and exit
if [ $DISP_FLAG = YES ]
then
	echo "
Find the list of all configured 
- RAW.TYPEs in \$TMP_DIR/cm_rawTypes1
- PRO.CATGs in \$TMP_DIR/cm_list_procatg ."

	echo "RAW_TYPE DO_CLASS	CATG
====================================================" > $TMP_DIR/cm_rawTypes1
	cat $TMP_DIR/cm_rawTypes | awk '{print $1,$2,$4}' | grep " CALIB" | sed "s/ /	/g" >> $TMP_DIR/cm_rawTypes1
	echo "" >> $TMP_DIR/cm_rawTypes1
	cat $TMP_DIR/cm_rawTypes | awk '{print $1,$2,$4}' | grep " SCIENCE" | sed "s/ /	/g" >> $TMP_DIR/cm_rawTypes1

	cat $TMP_DIR/cm_assocRules1 |  awk '{print $3}' | sort -u | grep -v "^$" > $TMP_DIR/cm_list_procatg
	exit
fi

# recipes
cat $TMP_DIR/cm_assocRules1 | awk '{print $1,$2}' | sort -u > $TMP_DIR/cm_recipe

# =====================================================================
# 2.4.2 mcalibs 
# $TMP_DIR/cm_assocRules2: action-->raw_type, required_mcalibs, minRet, maxRet
#  CALSELECTOR: 	   action-->raw_type, required_rcalibs, minRet, maxRet
# =====================================================================

echo "   association, find matches ..."
cat $RLS_FILE |\
 sed "s/^}/AA}/" |\
 sed "s/select file/selectfile/"g |\
 awk '{
  if ( $1 == "action" ) { change=1 ; action=$2; minRet=-999; maxRet=-999 }
  if ( change == 1 && $1 == "minRet" )  { minRet=$3; maxRet=$6 }
  if ( change == 1 && $1 == "selectfile" ) { product=$3; print action, product, minRet, maxRet }
  if ( change == 1 && $1 == "AA}" ) { change=0 }
 }' change=0 |\
 sed "s/;//"g |\
 sed "s/and//" > $TMP_DIR/cm_assocRules2


# map action name into raw_type
for A in `cat $TMP_DIR/cm_assocRules2 | awk '{print $1}' | sort -u`
do
	rm -f $TMP_DIR/cm_rawtypelist $TMP_DIR/cm_productlist
	grep "^$A " $TMP_DIR/cm_assocRules2  | awk '{print $1,$2,$3,$4}' > $TMP_DIR/cm_productlist
	grep " ${A}$" $TMP_DIR/cm_groupRules | awk '{print $1}'          > $TMP_DIR/cm_rawtypelist
	for RT in `cat $TMP_DIR/cm_rawtypelist`
	do
		cat $TMP_DIR/cm_productlist | sed "s/^$A /$RT /" >> $TMP_DIR/cm_assocRules200
	done
done
mv $TMP_DIR/cm_assocRules200 $TMP_DIR/cm_assocRules2

# =====================================================================
# 2.4.3 matchrules
# $TMP_DIR/cm_assocRules3: action-->raw_type, matchrule 
# =====================================================================

cat $RLS_FILE |\
 sed "s/^}/AA}/" |\
 sed "s/select file/selectfile/"g |\
 awk '{
  if ( $1 == "action" ) { change=1 ; action=$2 }
  if ( change == 1 && $1 == "selectfile" ) { print action, $0 }
  if ( change == 1 && $1 == "AA}" ) { change=0 }
 }' change=0 |\
 sed "s/;//"g |\
 sed "s/selectfile as .* where PRO.CATG==/ /" |\
 sed "s/selectfile as .* where RAW.TYPE==/ /" |\
 sed "s/selectfile as .* where PRO.CATG == / /" |\
 sed "s/selectfile as .* where RAW.TYPE == / /" |\
 sed "s/\"//g" |\
 sed "s/ and//" |\
 sed "s/  / /g" |\
 sed "s/  / /g" |\
 sed "s/  / /g" |\
 sed "s/^.*/& /" \
  > $TMP_DIR/cm_assocRules3

# map action name into raw_type
for A in `cat $TMP_DIR/cm_assocRules3 | awk '{print $1}' | sort -u`
do
	rm -f $TMP_DIR/cm_rawtypelist $TMP_DIR/cm_productlist
	grep "^$A " $TMP_DIR/cm_assocRules3  | awk '{print $0}' > $TMP_DIR/cm_productlist
	grep " ${A}$" $TMP_DIR/cm_groupRules | awk '{print $1}' > $TMP_DIR/cm_rawtypelist
	for RT in `cat $TMP_DIR/cm_rawtypelist`
	do
		cat $TMP_DIR/cm_productlist | sed "s/^$A /$RT /" >> $TMP_DIR/cm_assocRules300
	done
done
mv $TMP_DIR/cm_assocRules300 $TMP_DIR/cm_assocRules3

# =====================================================================
# 2.4.4 validity
# CALCHECKER: get validity from _association.h 
# (this is non-standard but validity is not handled by OCA)
# =====================================================================

if [ $NAME = CALCHECKER ]
then
	ASSOC_FILE=`echo $RLS_FILE | sed "s/.RLS/_association.h/"`
	if [ ! -s $ASSOC_FILE ]
	then
		echo "***ERROR: $ASSOC_FILE not found, required for validity analysis!"
	fi
	grep DELTAT_RULE $ASSOC_FILE |\
 sed "s/^.*ACTION_//" |\
 sed "s/DELTAT_RULE=//" |\
 awk '{print $1,$2,$3}' \
  > $TMP_DIR/cm_assocRules4
fi	

# =====================================================================
# 2.4.5 RASSOC=YES: construct cm_assocRules1 from cm_assocRules2
# seems obsolete with R2M
# =====================================================================

if [ $RASSOC = YES ]
then
	cat $TMP_DIR/cm_assocRules2 | awk '{print $2,"none",$2}' | sort -u > $TMP_DIR/cm_assocRules1
fi

# =====================================================================
# 2.4.6 DFOS_OPS: include MASSOCs 
# (could belong logically to processing cascade)
# =====================================================================

# DFOS_OPS: include MASSOCs (could belong logically to processing cascade)
if [ $NAME = DFOS_OPS ]
then
	#sed -i -e "s/_MASSOC//" $TMP_DIR/cm_assocRules2
# _MASSOC would lead to inconsistencies if someone has the same pro.catg with and without MASSOC
	sed -i -e "s/_massoc//" $TMP_DIR/cm_assocRules2
fi

# =====================================================================
# 2.4.7 required mcalibs per RAW_TYPE, incl minRet and maxRet --> $TMP_DIR/cm_allmcalibs
# =====================================================================
# RASSOC=NO:  RASSOC considered not essential, only MCALIB and MASSOC 
# RASSOC=YES: RASSOC crucial but MASSOC suppressed
case $RASSOC in
  "NO"  ) cat $TMP_DIR/cm_assocRules2 | awk '{print $1,$2,$3,$4}' | grep -v RASSOC | sort -u > $TMP_DIR/cm_allmcalibs ;;
  "YES" ) cat $TMP_DIR/cm_assocRules2 | awk '{print $1,$2,$3,$4}' | grep -v MASSOC | sort -u > $TMP_DIR/cm_allmcalibs ;;
esac

# =====================================================================
# 2.4.8 list of possible gencalibs: 
# the ones from $TMP_DIR/cm_allmcalibs without virtual calib prediction
# =====================================================================
echo "- Find gencalibs ..."
rm -f $TMP_DIR/cm_gencalibs*

for M in `cat $TMP_DIR/cm_allmcalibs | awk '{print $2}' | grep -v ASSOC | sort -u`
do
	CHECK_VIRTUAL=`grep "product $M " $RLS_FILE`

	if [ "Q$CHECK_VIRTUAL" = Q ]
	then
		echo $M >> $TMP_DIR/cm_gencalibs
	fi
done

# sort them in order of their appearance in the association part
for M in `cat $TMP_DIR/cm_allmcalibs | awk '{print $2}'`
do
	if [ -s $TMP_DIR/cm_gencalibs ]
	then
		CHECK_GENCAL=`grep "^${M}$" $TMP_DIR/cm_gencalibs`
		if [ "Q$CHECK_GENCAL" != Q ] && [ -s $TMP_DIR/cm_gencalibs1 ]
		then
			CHECK_EXIST=`grep "^${M}$" $TMP_DIR/cm_gencalibs1`
			if [ Q$CHECK_EXIST = Q ]
			then
				echo $M >> $TMP_DIR/cm_gencalibs1
			fi
		elif [ "Q$CHECK_GENCAL" != Q ]
		then
			echo $M >> $TMP_DIR/cm_gencalibs1
		fi
	fi
done

if [ -s $TMP_DIR/cm_gencalibs1 ]
then
	mv $TMP_DIR/cm_gencalibs1 $TMP_DIR/cm_gencalibs
fi

# CALCHECKER: check for pseudo gencalibs
if [ $NAME = CALCHECKER ] && [ -s $TMP_DIR/cm_gencalibs ]
then
	echo "
   ***WARNING: there appear PRO.CATGs for matches that are not defined as products:"
	cat $TMP_DIR/cm_gencalibs
	echo "   These will appear under GENCALIB. They should be included in the cascade as products."
	echo ""
fi

# =====================================================================
# 2.4.9 CALSELECTOR: check for time match rules for all gencalibs
#       (time match: the rules about MJD-OBS)
# =====================================================================

rm -f $TMP_DIR/cm_gencal_wo_MJD
if [ $NAME = CALSELECTOR ]
then
	echo "- CALSELECTOR: check time match rules ..."

	cat $TMP_DIR/cm_assocRules3 | grep -v MJD-OBS > $TMP_DIR/cm_gencal_wo_MJD
	if [ -s $TMP_DIR/cm_gencal_wo_MJD ]
	then
		echo "
   ***WARNING: the following match rules raw_to_mcalibs have no time match rule included:
RAW_TYPE	PRO.CATG			RULE
===========================================================================================..."
		cat $TMP_DIR/cm_gencal_wo_MJD | sed "s/ /	/" | sed "s/ /	/"
		echo "  They are marked 'T' or 'GT' in the map and should probably better receive a time match rule to avoid wrong associations."
		echo ""
	fi
fi

# =====================================================================
# 2.4.10 CALSELECTOR: remove all gencalibs from $TMP_DIR/cm_assocRules1
# =====================================================================

if [ $NAME = CALSELECTOR ]
then
	if [ -s $TMP_DIR/cm_gencalibs ]
	then
		for GEN in `cat $TMP_DIR/cm_gencalibs`
		do
			grep -v " ${GEN}$" $TMP_DIR/cm_assocRules1 > $TMP_DIR/cm_assocRules100
			mv $TMP_DIR/cm_assocRules100 $TMP_DIR/cm_assocRules1
		done
	fi
fi

# ===========================================================================
# 2.5 -E [EXPLORE]: explore dependencies for given RAW_TYPE
# ===========================================================================

if [ $EXPLORE = YES ]
then
	echo "- Analyze cascade for $RAWTYPE ... (hit return:)"
	read input
	rm -f $TMP_DIR/cm_depend*
	echo "List of involved calib products, as extracted from RLS file:"
	grep "^$RAWTYPE " $TMP_DIR/cm_assocRules2 | sort -u > $TMP_DIR/cm_depend1
	if [ ! -s $TMP_DIR/cm_depend1 ]
	then
		echo " <nothing>"
		exit
	fi

	for RT1 in `cat $TMP_DIR/cm_depend1 | awk '{print $2}'`
	do
		NUM=`grep " $RT1 " $TMP_DIR/cm_depend1 | awk '{print $3","$4}'`
		DEP=`grep " ${RT1}$" $TMP_DIR/cm_assocRules1 | awk '{print $1}' | tr "\012" "|" | sed "s/|$//"`
		RASSOC_YN=`echo $RT1 | sed "s/^.*_RASSOC/YES/"`
		MASSOC_YN=`echo $RT1 | sed "s/^.*_MASSOC/YES/"`

# special treatment if $RASSOC = YES
		if [ $RASSOC = YES ] && [ $RASSOC_YN = YES ]
		then
			echo " $RT1 ($NUM)	(rassoc) "
		elif [ "Q$DEP" != Q ]
		then
			if [ -s $TMP_DIR/cm_depend2 ]
			then
				CHECK_EXIST=`grep "^${DEP}$" $TMP_DIR/cm_depend2`
			fi
			if [ Q$CHECK_EXIST = Q ]
			then
				echo $DEP >> $TMP_DIR/cm_depend2
			fi
			echo " $RT1 ($NUM)	made from $DEP"
		elif [ $RASSOC_YN = YES ]
		then
			echo " $RT1 ($NUM)	(rassoc) "
		elif [ $MASSOC_YN = YES ]
		then
			echo " $RT1 ($NUM)	(massoc) "
		else
			echo " $RT1 ($NUM)	(gencalib) "
		fi
	done

# second pass: check for dependencies of these $RT
	echo $RAWTYPE >> $TMP_DIR/cm_depend2

	if [ -s $TMP_DIR/cm_depend2 ]
	then
		echo "
List of involved RAW_TYPES:"
		cat $TMP_DIR/cm_depend2
	fi
	exit
fi

# ===========================================================================
# 3. Output table
# 3.1 header (RAW_TYPEs...CATG)
# ===========================================================================

echo "- Top part of cascade ..."
START_COMMENT=""

case $NAME in
 "CALCHECKER"  ) COMMENT="(no DO_CLASS defined; no gencalibs, no HC calibs defined; validity indicated)" ;;
# "CALSELECTOR" ) COMMENT="(gencalibs defined but no HC calibs; raw2raw type of association)" 
 "CALSELECTOR" ) COMMENT="(raw2master type of association; versioning supported)" 
  		 START_COMMENT="<tr bgcolor=#eeeeee><td><font size=2>Start-date:</font></td><td><font size=2><b>$START_DATE</b></font></td></tr>"
		 OTHER_VERS="| <a href=${WEB_URL}/CALSELECTOR/${DFO_INSTRUMENT}/cascade_${DFO_INSTRUMENT}_ALL.html>other</a> versions" ;;
 "DFOS_OPS"    ) COMMENT="(current operational rules for QC; no versioning)" ;;
 *             ) COMMENT="" ;;
esac

cat > $TMP_DIR/cm_cascade.html <<EOT
<html>
<!-- created by createCalibMap v${TOOL_VERSION} -->
<title>$INSTRUMENT ${INS_MODE} $NAME calibration cascade</title>
<h2>$INSTRUMENT ${INS_MODE} $NAME calibration cascade</h2>
<a name=top></a>
<table>
  <tr>
    <td colspan=2>CROSSNAV</td>
  </tr>
  <tr bgcolor=#EEEEEE>
    <td><font size=2>OCA rule set:</font></td><td><font size=2><a href=$RLS_FILE>${RLS_FILE}</a> $OTHER_VERS </font></td>
  </tr>
  $START_COMMENT
  <tr bgcolor=#EEEEEE>
    <td>
      <font size=2>Type of rule set:</font></td><td><font size=2><b>$NAME</b> ${COMMENT}</font> 
    </td>
  </tr>
EOT

grep "^ALL_MODES" $RLS_PATH/config.createCalibMap > $TMP_DIR/cm_modes
cat >> $TMP_DIR/cm_cascade.html <<EOT	
  <tr bgcolor=#EEEEEE><td><font size=2>Sub-cascades:</font></td><td><font size=2>
EOT

if [ $INS_MODE = ALL ]
then
	echo "<a href=./cascade_${INSTRUMENT}_ALL.html title=\"full cascade\" style=\"background-color: #66CCFF;\">ALL</a> &nbsp; &nbsp; &nbsp; " >> $TMP_DIR/cm_cascade.html
else
	echo "<a href=./cascade_${INSTRUMENT}_ALL.html title=\"full cascade\">ALL</a> &nbsp; &nbsp; &nbsp; " >> $TMP_DIR/cm_cascade.html
fi

LAST_IM=`grep "^ALL_MODES" $RLS_PATH/config.createCalibMap  | grep -v "[[:space:]]DET$" | awk '{print $2}' | tail -1`
for IM in `grep "^ALL_MODES" $RLS_PATH/config.createCalibMap  | grep -v "[[:space:]]DET$" | awk '{print $2}'`
do
	if [ $IM != $LAST_IM ]
	then
		LAST=" | "
	else
		LAST=""
	fi

	if [ $IM = $INS_MODE ]
	then
		echo "<a href=./cascade_${INSTRUMENT}_${IM}.html style=\"background-color: #66CCFF;\">$IM</a> $LAST" >> $TMP_DIR/cm_cascade.html
	else
		echo "<a href=./cascade_${INSTRUMENT}_${IM}.html>$IM</a> $LAST" >> $TMP_DIR/cm_cascade.html
	fi
done

cat >> $TMP_DIR/cm_cascade.html <<EOT
</font></td></tr>
EOT

# Mode comment section
if [ -s $INFO_FILE ]
then
	if [ $INS_MODE = ALL ]
	then
		MODE_COMMENT=`grep "^MODE_COMMENT" $INFO_FILE | grep "[[:space:]]ALL[[:space:]]" | sed "s/\&\&$//" | sed "s/^.*\&\&//"`
	else
		MODE_COMMENT=`grep "^MODE_COMMENT" $INFO_FILE | grep "[[:space:]]${INS_MODE}[[:space:]]" | sed "s/\&\&$//" | sed "s/^.*\&\&//"`
	fi

	BGCOLOR=#FFFF99

else
	MODE_COMMENT=""
	BGCOLOR=#EEEEEE
fi

echo "<tr bgcolor=#EEEEEE><td><font size=2>General comment:</font></td><td bgcolor=${BGCOLOR}><font size=2>$MODE_COMMENT</font></td></tr>" >> $TMP_DIR/cm_cascade.html

# general comments
#if [ $NAME = CALSELECTOR ]
#then
#	CALCHECK_COMMENT="<br><font color=#9999FF><b>ok</b></font>: correct standard validity (+/-$GEN_VAL); <font color=red>29</font>: non-standard validity"
#	CALCHECK_COMMENT2="<br><font color=#9999FF><b>&lt;</b></font>&nbsp;: correct time match rule for static mcalib (PREVIOUS); <font color=red><b>?</b></font>: wrong time match rule"
if [ $NAME = CALCHECKER ] 
then
	CALCHECK_COMMENT="<br><font color=#9999FF><b>|| 7.0</b></font>&nbsp; validity (max. accepted mjd_obs time difference) for this match"
	CALCHECK_COMMENT2=""
elif [ $NAME = CALSELECTOR ]
then
	CALCHECK_COMMENT="<br><font color=#9999FF><b>||-7.0/+7.0</b></font>&nbsp; calib_plan validity (best mjd_obs time difference) and extended validity defined<br><font color=red><b>(-2.0/+2.0)</b></font>&nbsp; calib_plan validity not defined, only extended validity (maximum mjd_obs time difference)<br><font color=red>[-2.0/+2.0]</font>&nbsp; calib_plan validity defined, but no extended validity</font>"
	CALCHECK_COMMENT2=""
else
	CALCHECK_COMMENT=""
	CALCHECK_COMMENT2=""
fi

if [ $NAME = CALSELECTOR ]
then
	TIME_MATCH1="<br><br>Time match rules:<br><font color=red>GT</font>: no validity for this static mcalib defined"
	TIME_MATCH2="<br><font color=red>T</font>: no validity for this mcalib defined<br><font color=#9999FF><b><</b></font>&nbsp;PREVIOUS time match"
	if [ -s $TMP_DIR/cm_rawTypes2 ]
	then
		EXPOSE="<br><b><font color=#9999FF>EXPOSE:</font></b> marks those non-SCIENCE RAW_TYPEs which can be exceptionally exposed to CALSELECTOR."
	fi
else
	TIME_MATCH1=""
	TIME_MATCH2=""
fi

cat >> $TMP_DIR/cm_cascade.html <<EOT
</table>
<font size=2>
This tool provides some analysis results, marked in red:<br>	<!--LOCAL-->
<font color=red>0,0</font> &nbsp; &nbsp; This product match is obsolete and could be removed.<br> <!--LOCAL-->
<font color=red>M 0,1</font> &nbsp; &nbsp; This product match is defined more than once, there could be a logical problem..<br> <!--LOCAL-->
<p>
<font size=1>
Mouse over ...<br>
- a RAW_TYPE to see the classification rule (<font color=red>M</font> marks a multiple definition)<br>
- a grouping rule to see the complete grouping rule<br>
- a matching rule (e.g. '1,1') to see the product matching rule.<br>
Product tags etc. might be cut off, in that case mouse over the cell to see the full entry.
$EXPOSE
$TIME_MATCH1
$CALCHECK_COMMENT2
$TIME_MATCH2
$CALCHECK_COMMENT
</font>
<p>
<table style="border-collapse: collapse;" border=1 bordercolor=#333333>
<tr>
  <td align=left><font size=1><a href=#bottom>bottom</a> | <a href=#right>right</a></font></td>
  <td COLSPAN=299 align=right><font size=1><a href=#top>left</a>&nbsp; &nbsp; &nbsp;<a name=right></a></font></td>
</tr>
EOT

# RAW_TYPE
cat $TMP_DIR/cm_rawTypeRules | sed "s/^.*/<td nowrap>&<\/td>/" | tr "\012" " " | sed "s/^.*/&END\n/" | sed "s/ END//" | sed "s|^.*|<tr bgcolor=#cccccc style=\"font-size:small;\"><td><b>RAW_TYPE</b></td>&</tr>|" >> $TMP_DIR/cm_cascade.html 

# DO_CLASS: do not shorten since they might exist in multiplex
rm -f $TMP_DIR/cm_rawTypes1
cat $TMP_DIR/cm_rawTypes | awk '{print $1,$2,$3,$4,$2}' > $TMP_DIR/cm_rawTypes1

# CALCHECKER has no DO_CLASS 
if [ $DO_CLASS = YES ]
then
	cat $TMP_DIR/cm_rawTypes1 | awk '{print "<td>"$2"</td>"}' | sed "s/,/, /"g |\
 tr "\012" " " | sed "s/^.*/&END\n/" | sed "s/ END//" | sed "s/,/,<br>/"g |\
 sed "s|^.*|<tr bgcolor=#eeeeee valign=top style=\"font-size:x-small;\"><td><b>DO_CLASS</b></td>&</tr>|" | sed "s/none/NONE/"g | sed "s/<td><a title=NONE>NONE/<td bgcolor=#FFFFFF><font color=#CCCCCC><i>NONE/"g >> $TMP_DIR/cm_cascade.html
fi

# CATG: mark EXPOSE_TO_CALSELECTOR=T
if [ -s  $TMP_DIR/cm_rawTypes2 ]
then
	for RT in `cat $TMP_DIR/cm_rawTypes2 | awk '{print $1}'`
	do
		sed -i -e "/^$RT /s|^.*|& EXPOSE_TO_CALSELECTOR=T|" $TMP_DIR/cm_rawTypes
	done
fi

# CATG: fill the row
cat $TMP_DIR/cm_rawTypes | awk '{print $4,$5}' | tr "\012" " " | sed "s/^.*/&END\n/" | sed "s/ END//" |\
 sed "s|CALIB|</td><td bgcolor=#33FF33>CALIB|g" |\
 sed "s|SCIENCE|</td><td bgcolor=#9999FF>SCIENCE|g" |\
 sed "s|ACQUISITION|</td><td bgcolor=orange>ACQUISITION|g" |\
 sed "s|EXPOSE_TO_CALSELECTOR=T|<font color=#9999FF><b><a title=\"EXPOSE_TO_CALSELECTOR=T\">\&nbsp;\&nbsp;EXPOSE</a><b></font>|g" |\
 sed "s|^.*|<tr style=\"font-size:x-small;\" bgcolor=#eeeeee><td>CATG&</td></tr>|" \
 >> $TMP_DIR/cm_cascade.html
	
# group rules
echo "<tr bgcolor=#eeeeee style=\"font-size:x-small;\"><td>Grouping rule</td>" >> $TMP_DIR/cm_cascade.html
for RT in `cat $TMP_DIR/cm_rawTypes | awk '{print $1}'`
do
	MATCH=`grep "^$RT " $TMP_DIR/cm_groupRules | awk '{print $2}' | head -1`
	if [ "Q$MATCH" = Q ]
	then
		MATCH="single (implicit)"
	fi
# rules have possibly 'as TPL_A,tpl' ...
	CHECK_DUPL=`grep "^$RT " $TMP_DIR/cm_groupRules | awk '{print $3}' | wc -l`
	if [ $CHECK_DUPL -gt 1 ] 
	then
		echo "   ***ERROR: It looks like two ACTIONs are defined for the same RAW_TYPE:"
		echo "RAW_TYPE GRP_RULE			tpl  action"
		echo "====================================================="
		grep "^$RT " $TMP_DIR/cm_groupRules
		echo "   The tool can't cope with that; only the first one is taken.
"
	fi

	GRP_RULE=`grep "^$RT " $TMP_DIR/cm_groupRules | awk '{print $3}' | sed "s/,/ /" | awk '{print $1}' | head -1`
	if [ Q$GRP_RULE = Q ] || [ Q$GRP_RULE = QNONE ]
	then
# ... or just TPL.START or ARCFILE
		CHECK_TPL=`grep "^$RT " $TMP_DIR/cm_groupRules | awk '{print $2}' | grep TPL.START | head -1`
		if [ "Q$CHECK_TPL" != Q ]
		then
			GRP_RULE="TPL.START"
		else
			GRP_RULE="<i>single</i>"
		fi
	fi
	echo "<td><a title=\"$MATCH\">${GRP_RULE}</a></td>" >> $TMP_DIR/cm_cascade.html
done
echo "</tr>" >> $TMP_DIR/cm_cascade.html

# Recipe: only for DFOS_OPS or CALSELECTOR
if [ $NAME = DFOS_OPS ] || [ $NAME = CALSELECTOR ]
then
	echo "<tr bgcolor=#eeeeee style=\"font-size:x-small;\"><td>Recipe</td>" >> $TMP_DIR/cm_cascade.html
	for RT in `cat $TMP_DIR/cm_rawTypes | awk '{print $1}'`
	do
		CHECK_MORE=`grep "^$RT " $TMP_DIR/cm_recipe | awk '{print $2}' | wc -w`
		if [ $CHECK_MORE -gt 1 ]
		then
			echo "ERROR: there is more than one recipe defined for $RT:"
			grep "^$RT " $TMP_DIR/cm_recipe | awk '{print $1,$2}' | sed "s/^.*/   &/"
			echo "We cannot distinguish them, you should have only one association rule per raw_type. Hit return:"
			read input
		fi
		CHECK_DEFINED=`grep "^$RT " $TMP_DIR/cm_recipe | awk '{print $2}'`
		
		if [ "Q$CHECK_DEFINED" = Q ] || [ "Q$CHECK_DEFINED" = Qnone ]
		then
			echo "<td bgcolor=#FFFFFF><font color=#BBBBBB><i>none</i></td>" >> $TMP_DIR/cm_cascade.html
		else
			grep "^$RT " $TMP_DIR/cm_recipe | awk '{print $2}' | sed "s/^.*/<td>&<\/td>/" >> $TMP_DIR/cm_cascade.html
		fi
	done
	echo "</td></tr>" >> $TMP_DIR/cm_cascade.html
fi

# index
cat $TMP_DIR/cm_rawTypes | awk '{print NR}' | tr "\012" " " | sed "s/^.*/&END\n/" | sed "s/ END//" | sed "s| |</td><td align=center><b>|g" | sed "s|^.*|<tr bgcolor=#eeeeee style=\"font-size:x-small;\"><td>Index</td><td align=center><b>&</td></tr>|" >> $TMP_DIR/cm_cascade.html

# empty row
echo "<tr><td COLSPAN=299><br><b><font size=2>Calibration cascade: </td></tr>" >> $TMP_DIR/cm_cascade.html

# section calibs
if [ $RAW2RAW = NO ]
then
	echo "<tr><td><font size=2><a href=./list_static_mcals_${INSTRUMENT}.txt>static mcalibs:</a></td><td COLSPAN=299><font size=2>master calibs:</font></td></tr>" >> $TMP_DIR/cm_cascade.html
elif [ $RAW2RAW = YES ] && [ $RASSOC = YES ]
then
	echo "<tr><td><font size=2>static mcalibs:</td><td COLSPAN=299><font size=2>calib matches:</font></td></tr>" >> $TMP_DIR/cm_cascade.html
else
	echo "<tr><td><font size=2>&nbsp;</td><td COLSPAN=299><font size=2>calib matches:</font></td></tr>" >> $TMP_DIR/cm_cascade.html
fi

# ===========================================================================
# 3.2 Output table: products, dependencies
# 3.2.1 All products
#    Matrix: X - columns
#            Y - rows
# ===========================================================================
# gencalibs: arranged stacked in 1st column
# $TMP_DIR/cm_prodmatrix1: contains all created products and gencals in X,Y

echo "- Main part of cascade: calib matrix ..."
echo "   gencalibs ..."

rm -f $TMP_DIR/cm_prodmatrix*
COUNTERX=1
COUNTERY=1
if [ -s $TMP_DIR/cm_gencalibs ]
then
	for GC in `cat $TMP_DIR/cm_gencalibs`
	do
		echo "GENCALIB $COUNTERX $COUNTERY $GC" >> $TMP_DIR/cm_prodmatrix1
		COUNTERY=`echo $COUNTERY | awk '{print $1+1}'`
	done
fi
COUNTERX=`echo $COUNTERX | awk '{print $1+1}'`

# mcalibs from cm_assocRules1: arranged below gencalibs, in columns defined by raw_type
case $RASSOC in
 "NO"  ) echo "   mcalibs: products ..." ;;
 "YES" ) echo "   calibs: raw ..." ;;
esac

for RT in `cat $TMP_DIR/cm_rawTypes | awk '{print $1}'`
do
	rm -f $TMP_DIR/cm_products
		
	#was: grep "^$RT " $TMP_DIR/cm_assocRules1 | awk '{print $3}' | grep -v "^ *$"  > $TMP_DIR/cm_products
	if [ $RASSOC = YES ]
	then
		CHECK_RASSOC=`grep "^$RT " $TMP_DIR/cm_assocRules1 | awk '{print $3}'`
		grep "^$RT " $TMP_DIR/cm_assocRules1 | awk '{print $3}' | grep -v "^ *$"  > $TMP_DIR/cm_products
		grep "^${RT}_RASSOC" $TMP_DIR/cm_assocRules1 | awk '{print $3}' | grep -v "^ *$"  >> $TMP_DIR/cm_products
	else
		grep "^$RT " $TMP_DIR/cm_assocRules1 | awk '{print $3}' | grep -v "^ *$"  > $TMP_DIR/cm_products
	fi

	if [ -s $TMP_DIR/cm_products ]
	then
		for P in `cat $TMP_DIR/cm_products`
		do
			echo "$RT $COUNTERX $COUNTERY $P" >> $TMP_DIR/cm_prodmatrix1
			COUNTERY=`echo $COUNTERY | awk '{print $1+1}'`
		done
	fi
	COUNTERX=`echo $COUNTERX | awk '{print $1+1}'`
done
COUNTERX=`echo $COUNTERX | awk '{print $1-1}'`
COUNTERY=`echo $COUNTERY | awk '{print $1-1}'`
ENDX=$COUNTERX
ENDY=$COUNTERY

# ===========================================================================
# 3.2.2 All matches
# ===========================================================================
# $TMP_DIR/cm_prodmatrix2: contains all hits per raw_type in X,Y
# $TMP_DIR/cm_prodmatrix3: match conditions for these hits
# $TMP_DIR/cm_prodmatrix4: validity for these hits (CALCHECKER only)
# $TMP_DIR/cm_mcalibs:     contains all mcalibs per raw_type

case $RASSOC in
	"NO"  ) echo "   mcalibs: matches ..." ;;
	"YES" ) echo "   calibs: matches ..." ;;
esac

COUNTERX=2
COUNTERY=1
for RT in `cat $TMP_DIR/cm_rawTypes | awk '{print $1}'`
do
	rm -f $TMP_DIR/cm_mcalibs
	grep "^$RT " $TMP_DIR/cm_allmcalibs | awk '{print $2,$3,$4}' | sed "s/_MASSOC//"  > $TMP_DIR/cm_mcalibs
	if [ -s $TMP_DIR/cm_mcalibs ]
	then
		for M in `cat $TMP_DIR/cm_mcalibs | awk '{print $1}'`
		do
			rm -f $TMP_DIR/cm_list_MC_Y $TMP_DIR/cm_check_multiple
# for RAW2RAW: remove _RASSOC
			M1=`echo $M | sed "s/_RASSOC//"`

# for CALCHECKER: replace M1 by appropriate RT
			if [ $NAME = CALCHECKER ]
			then
				M2=`grep " ${M1}$" $TMP_DIR/cm_assocRules1 | awk '{print $1}'`
			fi

			grep " ${M}$" $TMP_DIR/cm_prodmatrix1 | awk '{print $3}' | sort -u > $TMP_DIR/cm_list_MC_Y
			grep "^${M} " $TMP_DIR/cm_mcalibs | awk '{print $2,$3}' > $TMP_DIR/cm_check_multiple
			CHECK_NUM=`grep "^${M} " $TMP_DIR/cm_mcalibs | awk '{print $2,$3}' | wc -l`
			if [ $CHECK_NUM -gt 1 ]
			then
				echo "   WARNING: multiple product match rule found for $RT <-> $M (we consider only the first one):" 
				cat $TMP_DIR/cm_check_multiple | sed "s/^.*/    &/" | sed "s/-999 -999/unconstrained/"
				NUM=`grep "^${M} " $TMP_DIR/cm_mcalibs | awk '{print $2,$3}' | head -1`
				NUM="multiple$NUM"
			else
				NUM=`grep "^${M} " $TMP_DIR/cm_mcalibs | awk '{print $2,$3}'`
			fi

			if [ -s $TMP_DIR/cm_list_MC_Y ]
			then
				case $NAME in
				 "DFOS_OPS"    ) MATCH_RULE=`grep "^$RT ${M1} " $TMP_DIR/cm_assocRules3 | sed "s/^$RT ${M1} /PRO.CATG==$M1 and /" | sed "s/and $//" | head -1` ;;
				 "CALSELECTOR" ) MATCH_RULE=`grep "^$RT ${M1} " $TMP_DIR/cm_assocRules3 | sed "s/^$RT ${M1} /PRO.CATG==$M1 and /" | sed "s/and $//" | head -1` ;;
				 "CALCHECKER"  ) MATCH_RULE=`grep "^$RT ${M1} " $TMP_DIR/cm_assocRules3 | sed "s/^$RT ${M1} /RAW.TYPE==$M2 and /" | sed "s/and $//" | head -1` ;;
				 #R2R: "CALSELECTOR" ) MATCH_RULE=`grep "^$RT ${M1} " $TMP_DIR/cm_assocRules3 | sed "s/^$RT ${M1} / /" | head -1` ;;
				esac

				if [ $CHECK_NUM -gt 1 ]
				then
					MATCH_RULE="multiple, only first rule displayed: $MATCH_RULE"
				fi

				CHECK_MULTIPLE=`grep "^$RT ${M}_MASSOC " $TMP_DIR/cm_assocRules2 | awk '{print $2}' | wc -l`
				if [ $CHECK_MULTIPLE -gt 1 ]
				then
					echo "   INFO: the match $RT ${M}_MASSOC is defined more than once (this may be legal for OCA but an issue for the calibmap):"
					grep "^$RT ${M}_MASSOC " $TMP_DIR/cm_assocRules2 | sed "s/^.*/    &/"
					echo "    We will display only the first match."
				fi

				MASSOC_YN=`grep "^$RT ${M}_MASSOC " $TMP_DIR/cm_assocRules2 | awk '{print $2}' | head -1`
				if [ Q$MASSOC_YN != Q ]
				then
					MASSOC_YN=MASSOC
				fi

				if [ $NAME = CALCHECKER ]
				then
					VALIDITY=`grep "^$RT ${M1} " $TMP_DIR/cm_assocRules4 | sed "s/^$RT ${M1} //"`
				fi

				for MC_Y in `cat $TMP_DIR/cm_list_MC_Y`
				do
					CHECK_PREVIOUS=""
					if [ -s $TMP_DIR/cm_prodmatrix2 ]
					then
						CHECK_PREVIOUS=`grep " $COUNTERX $MC_Y HIT" $TMP_DIR/cm_prodmatrix2`
					fi

					if [ "Q$CHECK_PREVIOUS" = Q ]
					then
						echo "$RT $COUNTERX $MC_Y HIT ${NUM}$MASSOC_YN" >> $TMP_DIR/cm_prodmatrix2
						echo "$RT $COUNTERX $MC_Y HIT $MATCH_RULE" >> $TMP_DIR/cm_prodmatrix3

						if [ $NAME = CALCHECKER ]
						then
							echo "$RT $COUNTERX $MC_Y HIT $VALIDITY" >> $TMP_DIR/cm_prodmatrix4
						fi
					fi
				done
			fi
			COUNTERY=`echo $COUNTERY | awk '{print $1+1}'`
		done
	fi
	COUNTERX=`echo $COUNTERX | awk '{print $1+1}'`
done

# RAW2RAW: replace pro.catg by raw_type in $TMP_DIR/cm_prodmatrix1
if [ $RAW2RAW = YES ] && [ $RASSOC = NO ]
then
	rm -f $TMP_DIR/cm_prodmatrix10
	for L in `cat $TMP_DIR/cm_prodmatrix1 | sed "s/ /XYZ/g"`
	do
		RT=`echo $L  | sed "s/XYZ/ /g" | awk '{print $1}'`
		MIN=`echo $L | sed "s/XYZ/ /g" | awk '{print $2}'`
		MAX=`echo $L | sed "s/XYZ/ /g" | awk '{print $3}'`
		echo "$RT $MIN $MAX $RT" >> $TMP_DIR/cm_prodmatrix10
	done
	mv $TMP_DIR/cm_prodmatrix10 $TMP_DIR/cm_prodmatrix1
fi

# ===========================================================================
# 3.2.3 Merge cm_prodmatrix1 and cm_prodmatrix2 into cm_prodmatrix
#       cm_prodmatrix contains X,Y for mcalib name, and for matches ("HIT")
# ===========================================================================

rm -f $TMP_DIR/cm_prodmatrix
COUNTERY=1
while [ $COUNTERY -le $ENDY ]
do
	COUNTERX=1
	while [ $COUNTERX -le $ENDX ]
        do
		grep " $COUNTERX $COUNTERY " $TMP_DIR/cm_prodmatrix1 >> $TMP_DIR/cm_prodmatrix
		grep " $COUNTERX $COUNTERY " $TMP_DIR/cm_prodmatrix2 >> $TMP_DIR/cm_prodmatrix
		COUNTERX=`echo $COUNTERX | awk '{print $1+1}'`
	done
	COUNTERY=`echo $COUNTERY | awk '{print $1+1}'`
done

# cleanup for defined but unused gencalibs or master_calibs
for P in `grep "^GENCALIB " $TMP_DIR/cm_prodmatrix | awk '{print $4}'`
do
	PINDEX=`grep " ${P}$" $TMP_DIR/cm_prodmatrix  | awk '{print $3}'`
	CHECK_HIT=`grep " $PINDEX HIT " $TMP_DIR/cm_prodmatrix`
	if [ "Q$CHECK_HIT" = Q ]
	then
		if [ $INS_MODE = ALL ]
		then
			echo "***INFO: $P not used in this cascade (or not predicted as product in OCA rule set), skipped."
		fi
		sed -i -e "/ ${P}$/d" $TMP_DIR/cm_prodmatrix
	fi
done

# same for RASSOC
for P in `grep "^GENCALIB " $TMP_DIR/cm_prodmatrix | awk '{print $4}'`
do
	PINDEX=`grep " ${P}$" $TMP_DIR/cm_prodmatrix  | awk '{print $3}'`
	CHECK_HIT=`grep " $PINDEX HIT " $TMP_DIR/cm_prodmatrix`
	if [ "Q$CHECK_HIT" = Q ]
	then
		if [ $INS_MODE = ALL ]
		then
			echo "***INFO: $P not used in this cascade (or not predicted as product in OCA rule set), skipped."
		fi
		sed -i -e "/ ${P}$/d" $TMP_DIR/cm_prodmatrix
	fi
done

# ===========================================================================
# 3.3 Construct the product matrix
#
# start at bottom upwards, per column:
# - cell (empty or minmax) and memory=0: index-1
# - cell empty and memory=1: set marker; memory=0; index-1
# - cell has minmax and memory=1: set minmax+marker; memory=0; index-1
# - cell is product: memory=1; index-1

# start right towards left, per row:
# - cell empty and memory=0: index-1
# - cell empty and memory=1: set marker; index-1
# - cell is product and memory=1: memory=0; index-1
# - cell is product and memory=0: index-1
# - cell has minmax: set minmax+marker; memory=1; index-1

if [ $INS_MODE = ALL ]
then
	echo "
- Put calib matrix together ..."
else
	echo "
- Put calib matrix together (the indexes refer to the full cascade, not to the selected mode; 
  the products are for the selected mode) ..."
fi

COUNTERX=1
COUNTERY=1

# Y: rows; X: columns
while [ $COUNTERY -le $ENDY ]
do
	rm -f $TMP_DIR/cm_row $TMP_DIR/cm_row1
	echo "<tr style=\"font-size:x-small;\">" > $TMP_DIR/cm_row

	while [ $COUNTERX -le $ENDX ]
	do
		FLAG=`grep " $COUNTERX $COUNTERY " $TMP_DIR/cm_prodmatrix | awk '{print $1}'`
		CELL=`grep " $COUNTERX $COUNTERY " $TMP_DIR/cm_prodmatrix | awk '{print $4}'`
		CHECK_CELL=`echo $CELL | wc -w`
		COUNTERX1=`echo $COUNTERX | awk '{print $1-1}'`
		ERROR_MARK=NO

# check for multiple entries in cell
		if [ $CHECK_CELL -gt 1 ]
		then
			echo "***ERROR: there is more than one entry for this cell in row $COUNTERY, index $COUNTERX1:
$CELL
('HIT' means a product match to some other product).
Presumably you have used the same pro.catg for a product match and a virtual product.  Check your configuration. We consider only the first entry."
			CELL=`echo $CELL | awk '{print $1}'`
			FLAG=`echo $FLAG | awk '{print $1}'`
			ERROR_MARK=YES
		fi

		if [ $COUNTERX = 1 ]
		then
			MCALIB="$CELL"
		fi

# shorten entries
		if [ $KEEP_SHORT = YES ]
		then
			CELL_LENGTH=`echo $CELL | wc -c | awk '{print $1-1}'`
			if [ $CELL_LENGTH -gt $SHORT_CHAR ]
			then
				CELL1="`echo $CELL | cut -c1-${SHORT_CHAR}`..."
			else
				CELL1=$CELL
			fi
		else
			CELL1=$CELL
		fi

		CATG=`grep "^$FLAG " $TMP_DIR/cm_rawTypes | awk '{print $4}'` 
		NUM=`grep " $COUNTERX $COUNTERY " $TMP_DIR/cm_prodmatrix | awk '{print $5","$6}' | sed "s/MASSOC//"`
		NUM1=`echo $NUM | sed "s/multiple.*/multiple/"`
		NUM2=`echo $NUM | sed "s/multiple/M /" | sed "s/-999,-999/unconstrained/"`
		RASSOC_YN=`grep " $COUNTERX $COUNTERY " $TMP_DIR/cm_prodmatrix | grep RASSOC | sed "s/^.*RASSOC/<font color=#9999FF><i>RASSOC<\/i><\/font>/"`
		MASSOC_YN=`grep " $COUNTERX $COUNTERY " $TMP_DIR/cm_prodmatrix | grep MASSOC | sed "s/^.*MASSOC/<font color=#9999FF><i>MASSOC<\/i><\/font>/"`

		if [ Q$CELL = Q ]
		then
			echo "<td>&nbsp;</td>" >> $TMP_DIR/cm_row
		elif [ $CELL = HIT ]
		then
# get match conditions
			MATCH_RULE=`grep " $COUNTERX $COUNTERY " $TMP_DIR/cm_prodmatrix3 | sed "s/^.* $COUNTERX $COUNTERY HIT //"`
			if [ "Q$MATCH_RULE" = Q ]
			then
				MATCH_RULE=none
			fi

# VALIDITY
			VALIDITY=""
# CALSELECTOR: check for time match rules and flag issues
# gencalibs
			if [ $NAME = CALSELECTOR ] && [ Q$MCALIB != Q ]
			then
				CHECK_TRULE=`grep "^$FLAG[[:space:]]*${MCALIB}[[:space:]]" $TMP_DIR/cm_gencal_wo_MJD | awk '{print $1}'`
				if [ Q$CHECK_TRULE != Q ]
				then
					VALIDITY=" <a title=\"no time match rule for this gencalib defined\"><font size=1 color=red>GT</font></a>"
				else
# find: 'MJD-OBS < inputFile.MJD-OBS' and 'inputFile.MJD-OBS > MJD-OBS'
					CHECK_TRULE=`echo $MATCH_RULE | egrep "MJD-OBS[[:space:]]*<[[:space:]]*inputFile.MJD-OBS|inputFile.MJD-OBS[[:space:]]*>[[:space:]]*MJD-OBS"`
					if [ "Q$CHECK_TRULE" != Q ]
					then
						VALIDITY="<a title=\"PREVIOUS time match rule ok\"><font color=#9999FF><b>&lt;</b></font></a>"
					else
						VALIDITY="<a title=\"wrong time match rule? should be: MJD-OBS < inputFile.MJD-OBS\"><font color=red><b>?</b></font></a>"
					fi
				fi

# dynamic calibs: should have tryBetween
			elif [ $NAME = CALSELECTOR ]
			then
				CHECK_TRULE=`echo $MATCH_RULE | grep MJD-OBS | awk '{print $1}'`
				if [ "Q$CHECK_TRULE" = Q ]
				then
					VALIDITY="<a title=\"no time match rule for this calib defined\"><font size=1 color=red> <b>T</b></font></a>"
				else
					VALIDITY=`echo "$MATCH_RULE" | grep "MJD-OBS < inputFile.MJD-OBS"`
# could be "<"
					if [ "Q$VALIDITY" != Q ]
					then
						VALIDITY="<a title=\"PREVIOUS time match rule ok\"><font color=#9999FF> <b><</b></font></a>"
					else
# between: VALIDITY1; tryBetween: VALIDITY2
# we assume that between comes first and then tryBetween; otherwise the code needs to become more complicated

# getBetween: delivers $TRYBETW, $BETWEEN
						rm -f $TMP_DIR/cm_check_between
						getBetween "$MATCH_RULE"

						if [ -s $TMP_DIR/cm_check_between ]
						then
							TRYBETW=`grep TRYBETWEEN $TMP_DIR/cm_check_between`
							BETWEEN=`grep BETWEEN $TMP_DIR/cm_check_between | grep -v TRY`
						fi

						VALIDITY1=`echo $BETWEEN | sed "s/BETWEEN//" | sed "s|+|/+|"`
						VALIDITY2=`echo $TRYBETW | sed "s/TRYBETWEEN//" | sed "s|+|/+|"`

						if [ "Q$VALIDITY1" != Q ] && [ "Q$VALIDITY2" != Q ]
						then
							VALIDITY="<a title=\"extended validity: ${VALIDITY1}; calib_plan validity: ${VALIDITY2}\"><font color=#9999FF><b> ||${VALIDITY2}</b></font></a>"
						elif [ "Q$VALIDITY1" != Q ] && [ "Q$VALIDITY2" = Q ]
						then
							VALIDITY="<a title=\"extended validity: ${VALIDITY1}; no calib_plan validity!\"><font color=red><b> (${VALIDITY1}) </b></font></a>"
						elif [ "Q$VALIDITY1" = Q ] && [ "Q$VALIDITY2" != Q ]
						then
							VALIDITY="<a title=\"no extended validity; calib_plan validity: ${VALIDITY2}\"><font color=red> [${VALIDITY2}] </font></a>"
						fi
					fi
				fi
			fi

# CALCHECKER: get validity
			if [ $NAME = CALCHECKER ] && [ $CATG = SCIENCE ]
			then
				VALIDITY=`grep " $COUNTERX $COUNTERY " $TMP_DIR/cm_prodmatrix4 | awk '{print "<font color=#9999FF><b> || </a><a title=\"validity of association\">"$5"</b></font>"}'`
			fi

# MATCH_RULE
			if [ "Q${MATCH_RULE}" = Qnone ]
			then
				BGCOLOR=#FFCCCC
				MATCH_RULE="none"
			else
				BGCOLOR=#EEEEEE
			fi

			case $NAME in
			 "DFOS_OPS"   ) MATCH_STRING="match rule:" ; ASSOC_YN=$MASSOC_YN ; ASSOC_STRING="product used as MASSOC";;
			 "CALCHECKER" ) MATCH_STRING="translated match rule:" ; ASSOC_YN=$MASSOC_YN ; ASSOC_STRING="product used as MASSOC";;
			 #R2R"CALSELECTOR") MATCH_STRING="match rule:" ; ASSOC_YN=$RASSOC_YN ; ASSOC_STRING="RASSOC: not needed for reduction";;
			 "CALSELECTOR") MATCH_STRING="match rule:" ; ASSOC_YN=$MASSOC_YN ; ASSOC_STRING="product used as MASSOC";;
			esac

# flag red if '0,0'
			if [ $NUM = "0,0" ]
			then
				echo "<td align=center bgcolor=${BGCOLOR} nowrap><font size=1 color=red><a title=\"$MATCH_STRING ${MATCH_RULE}\">${NUM}${VALIDITY}</a><a title=\"${ASSOC_STRING}\"> $ASSOC_YN</a></td>" >> $TMP_DIR/cm_row
# also flag red if multiple
			elif [ $NUM1 = "multiple" ]
			then
				echo "<td align=center bgcolor=${BGCOLOR} nowrap><font size=1 color=red><a title=\"$MATCH_STRING ${MATCH_RULE}\">${NUM2}${VALIDITY}</a><a title=\"${ASSOC_STRING}\"> $ASSOC_YN</a></td>" >> $TMP_DIR/cm_row
# -999,-999: display as 'unconstrained'
			elif [ $NUM1 = "-999,-999" ]
			then
				echo "<td align=center bgcolor=${BGCOLOR} nowrap><font size=1 color=red><a title=\"$MATCH_STRING ${MATCH_RULE}\">${NUM2}${VALIDITY}</a><a title=\"${ASSOC_STRING}\"> $ASSOC_YN</a></td>" >> $TMP_DIR/cm_row
			else
				echo "<td align=center bgcolor=${BGCOLOR} nowrap><font size=1><a title=\"$MATCH_STRING ${MATCH_RULE}\">${NUM}${VALIDITY}</a><a title=\"${ASSOC_STRING}\"> $ASSOC_YN</a></td>" >> $TMP_DIR/cm_row
			fi

# FAINTCALIB not used currently
		elif [ $FLAG = FAINTCALIB ]
		then
			echo "<td bgcolor=#FFFFFF><font color=#CCCCCC nowrap><i><a title=\"$CELL: defined but not used\">${CELL1}</a></td>" >> $TMP_DIR/cm_row
		else
# check if $CELL used anywhere in the cascade
			CHECK_USED=`grep " $COUNTERY HIT" $TMP_DIR/cm_prodmatrix`
			case $NAME in
			 "CALCHECKER" ) PRODUCTS="products" ;;
			 *            ) PRODUCTS="" ;;
			esac

			if [ "Q$CHECK_USED" = Q ]
			then
				echo "    row $COUNTERY of $ENDY: $CELL	(not used in cascade) ..."
				if [ $NAME = CALCHECKER ]
				then
					echo "<td bgcolor=#CCCCCC nowrap><b>$COUNTERY</b> <a title=\"$CELL \"$PRODUCTS (not used in cascade but maybe for CAL4CAL)\"><i>${CELL1}</i></a></td>" >> $TMP_DIR/cm_row
				else
					echo "<td bgcolor=#CCCCCC nowrap><b>$COUNTERY</b> <a title=\"$CELL (this product not used in cascade)\"><i>${CELL1}</i></a></td>" >> $TMP_DIR/cm_row
				fi
			else
				if [ $ERROR_MARK = NO ]	
				then
					echo "    row $COUNTERY of $ENDY: $CELL ..."
					echo "<td bgcolor=#CCCCCC nowrap><b>$COUNTERY</b> <a title=\"$CELL $PRODUCTS \">${CELL1}</a></td>" >> $TMP_DIR/cm_row
				else
					echo "    row $COUNTERY of $ENDY: $CELL (error) ..."
					echo "<td bgcolor=#CCCCCC nowrap><b>$COUNTERY</b> <a title=\"$CELL $PRODUCTS: an error occurred with multiple entries; see log\"><font color=red>${CELL1}</font></a></td>" >> $TMP_DIR/cm_row
				fi
			fi
		fi
		COUNTERX=`echo $COUNTERX | awk '{print $1+1}'`
	done
	echo "</tr>" >> $TMP_DIR/cm_row

	cat $TMP_DIR/cm_row | tr "/012" " " > $TMP_DIR/cm_row1
	CHECK_EMPTY=`grep [A-Z] $TMP_DIR/cm_row1`
	if [ "Q$CHECK_EMPTY" != Q ]
	then
		cat $TMP_DIR/cm_row >> $TMP_DIR/cm_cascade.html
	fi

	COUNTERX=1
	COUNTERY=`echo $COUNTERY | awk '{print $1+1}'`
done

# RT comment section
echo "<tr><td COLSPAN=299><br><b><font size=2>Comments: </td></tr>" >> $TMP_DIR/cm_cascade.html
echo "<tr><td>&nbsp;</td>" >> $TMP_DIR/cm_cascade.html

for RT in `cat $TMP_DIR/cm_rawTypes | awk '{print $1}'`
do
	RT_COMMENT="&nbsp;"
	WIDTH=""
	if [ -s $INFO_FILE ]
	then
		RT_COMMENT=`grep "^RT_COMMENT" $INFO_FILE | grep "[[:space:]]$RT[[:space:]]" | sed "s/\&\&$//" | sed "s/^.*\&\&//"`
		if [ "Q$RT_COMMENT" = Q ]
		then
			RT_COMMENT="&nbsp;"
			BGCOLOR=white
		else
			BGCOLOR=#FFFFCC
			WIDTH=60
		fi
	fi
	echo "<td bgcolor=$BGCOLOR valign=top width=$WIDTH><font size=1>$RT_COMMENT</font></td>" >> $TMP_DIR/cm_cascade.html
done
echo "</tr>" >> $TMP_DIR/cm_cascade.html

# Analysis section
echo "<tr><td COLSPAN=299><br><b><font size=2>Analysis (technical consistency checks): </td></tr>" >> $TMP_DIR/cm_cascade.html

# check if a rawtype has no products defined
echo ""
rm -f $TMP_DIR/cm_row
if [ $NAME = CALSELECTOR ]
then
	echo "<tr style=\"font-size:x-small;\"><td>raw_type* (CALIB only)</td>" > $TMP_DIR/cm_row
	COMMENT1="*<font size=1>raw_type: is raw_type used in cascade? (CALIB only)</font>"
else
	echo "<tr style=\"font-size:x-small;\"><td>products* (CALIB only)</td>" > $TMP_DIR/cm_row
	COMMENT1="*<font size=1>products: does raw_type have a product? (CALIB only)</font>"
fi

echo "- Bottom part of cascade: analysis ..."
echo "   1st analysis column (does raw_type have a product? CALIB only) ..." 
COUNTERX=2
while [ $COUNTERX -le $ENDX ]
do
	INDEX1=`echo $COUNTERX | awk '{print $1-1}'`
	RAWTYPE=`cat $TMP_DIR/cm_rawTypes | awk '{if (NR==index1) print $1}' index1=$INDEX1`
	CATG=`grep "^$RAWTYPE " $TMP_DIR/cm_rawTypes | awk '{print $4}' | head  -1`
	CHECK_PRO=`grep "^$RAWTYPE " $TMP_DIR/cm_assocRules1 | awk '{print $3}' | head -1`

	if [ Q$CHECK_PRO = Q ] && [ $CATG = CALIB ]
	then
		if [ $NAME = CALSELECTOR ]
		then
			echo "    col $COUNTERX of $ENDX: raw_type $RAWTYPE (not used in cascade)"
			echo "<td bgcolor=#FFCCCC align=center><a title=\"this raw_type is not used in the cascade, can't analyze dependencies\">not used</a></td>" >> $TMP_DIR/cm_row
		else
			echo "    col $COUNTERX of $ENDX: raw_type $RAWTYPE (no products defined)"
			echo "<td bgcolor=#FFCCCC align=center><a title=\"no product defined for this raw_type (HC data?), can't analyze dependencies\">no product</a></td>" >> $TMP_DIR/cm_row
		fi
	elif [ $CATG = CALIB ]
	then
		echo "<td align=center><font color=#BBBBBB><a title=\"product(s) defined for this raw_type\">OK</a></font></td>" >> $TMP_DIR/cm_row
	else
		echo "<td align=center><font color=#DDDDDD><i><a title=\"no check done for SCIENCE\">n/a</a></i></font></td>" >> $TMP_DIR/cm_row
	fi
	
	COUNTERX=`echo $COUNTERX | awk '{print $1+1}'`
done
echo "</tr>" >> $TMP_DIR/cm_row
cat $TMP_DIR/cm_row >> $TMP_DIR/cm_cascade.html
echo "   ... done."

# check if a raw_type requires products undefined in matrix
rm -f $TMP_DIR/cm_row
echo "<tr style=\"font-size:x-small;\"><td>mcalibs**</td>" > $TMP_DIR/cm_row
COMMENT2="<font size=1>**mcalibs: are all required mcalibs, per raw_type, somewhere listed as products?</font>"

echo "   2nd analysis column (per raw_type: are all required mcalibs somewhere listed as products?"
COUNTERX=2
while [ $COUNTERX -le $ENDX ]
do
	rm -f $TMP_DIR/cm_vprod $TMP_DIR/cm_undefprod
	INDEX1=`echo $COUNTERX | awk '{print $1-1}'`
	RAWTYPE=`cat $TMP_DIR/cm_rawTypes | awk '{if (NR==index1) print $1}' index1=$INDEX1`
	grep "^$RAWTYPE " $TMP_DIR/cm_assocRules2 | awk '{print $2}' | grep -v RASSOC | sed "s/_MASSOC//" | sort -u > $TMP_DIR/cm_vprod
	if [ -s $TMP_DIR/cm_vprod ]
	then
		for P in `cat $TMP_DIR/cm_vprod`
		do
			CHECK_VCAL=`grep " $P$" $TMP_DIR/cm_assocRules1 | head -1  | awk '{print $1}'`
			if [ Q$CHECK_VCAL = Q ]
			then
				CHECK_VCAL=`grep "^$P$" $TMP_DIR/cm_gencalibs | head -1`
			fi

			if  [ Q$CHECK_VCAL = Q ]
			then
				echo $P >> $TMP_DIR/cm_undefprod
				echo "    col $COUNTERX of $ENDX: raw_type $RAWTYPE uses undefined mcalib $P"
			fi
		done
	fi
	
	if [ -s $TMP_DIR/cm_undefprod ]
	then
		UNDEF=`cat $TMP_DIR/cm_undefprod | tr "\012" "|" | sed "s/|$//" | sed "s/|/ <br> /g"`
	 	echo "<td bgcolor=#FFCCCC align=center><a title=\"these products are required but not defined\">${UNDEF}</a></td>" >> $TMP_DIR/cm_row
	elif [ -s $TMP_DIR/cm_vprod ]
	then
		echo "<td align=center><font color=#BBBBBB><a title=\"all required products are defined in the cascade\">OK</a></font></td>" >> $TMP_DIR/cm_row
	else
		echo "<td align=center><font color=#DDDDDD><i><a title=\"no products required\">n/a</a></i></font></td>" >> $TMP_DIR/cm_row
	fi
	COUNTERX=`echo $COUNTERX | awk '{print $1+1}'`
done

echo "</tr>" >> $TMP_DIR/cm_row
cat $TMP_DIR/cm_row >> $TMP_DIR/cm_cascade.html

echo "  ... done."

# end of HTML table
cat >> $TMP_DIR/cm_cascade.html <<EOT
<tr>
  <td COLSPAN=99 align=right bgcolor=#CCCCCC><font size=1 color=#FFFFFF><b>powered by QC</b> [createCalibMap v${TOOL_VERSION}] last update: `date -u +%Y-%m-%d"T"%H:%M:%S`</font></td>
</tr>
</table>
$COMMENT1<br>
$COMMENT2<br>

<font size=1><a name=bottom></a> <a href=#top>top</a></font>
</html>
EOT

mv $TMP_DIR/cm_cascade.html $RLS_PATH/cascade_${INSTRUMENT}_${INS_MODE}.html

# ===========================================================================
# 4. scp to $DFO_WEB_SERVER and finish
# 4.1 scp
# ===========================================================================

# current CALSELECTOR DATE
CURRENT_DATE=`ls -d $DFO_CONFIG_DIR/CALSELECTOR/20* | tail -1`
CURRENT_DATE=`basename $CURRENT_DATE`
HIGHLIGHT="style=\"background-color: #66CCFF;\""
BGK1=""
BKG2=""
BKG3=""
case $NAME in
 "DFOS_OPS"   ) BKG1=$HIGHLIGHT ;; 
 "CALCHECKER" ) BKG2=$HIGHLIGHT ;;
 "CALSELECTOR") BKG3=$HIGHLIGHT ;;
esac

# determine current rule to be highlighted
sed "/OCA rule set:/s|${RLS_PATH}/||"g $RLS_PATH/cascade_${INSTRUMENT}_${INS_MODE}.html |\
 sed "s|CROSSNAV|<font size=2><a href=\"${WEB_URL}/DFOS_OPS/cascade_${DFO_INSTRUMENT}_ALL.html\" $BKG1>DFOS_OPS</a> \| <a href=\"${WEB_URL}/CALCHECKER/cascade_${DFO_INSTRUMENT}_ALL.html\" $BKG2>CALCHECKER</a> \| <a href=\"${WEB_URL}/CALSELECTOR/${DFO_INSTRUMENT}/${CURRENT_DATE}/cascade_${DFO_INSTRUMENT}_ALL.html\" $BKG3>CALSELECTOR (current)</a> \|\| select other instrument: <a href=${WEB_URL}/oca_rule_sets.html>OCA</a> </font>|" |\
 grep -v "<!--LOCAL-->" \
> $TMP_DIR/cm_cascade.html
chmod u+w $RLS_FILE

if [ $SCP = YES ]
then
	echo "- scp to ${DFO_WEB_SERVER} ..."
	ssh -o BatchMode=yes ${DFO_WEB_SERVER} "bin/qcDircheck ${WEB_DIR}/${NAME}"
	if [ $NAME = CALSELECTOR ]
	then
		ssh -o BatchMode=yes ${DFO_WEB_SERVER} "bin/qcDircheck ${WEB_DIR}/${NAME}/${INSTRUMENT}"
		ssh -o BatchMode=yes ${DFO_WEB_SERVER} "bin/qcDircheck ${WEB_DIR}/${NAME}/${INSTRUMENT}/${START_DATE}"
		scp -o BatchMode=yes $TMP_DIR/cm_cascade.html ${DFO_WEB_SERVER}:${WEB_DIR}/${NAME}/${INSTRUMENT}/${START_DATE}/cascade_${INSTRUMENT}_${INS_MODE}.html
		scp -o BatchMode=yes $RLS_FILE ${DFO_WEB_SERVER}:${WEB_DIR}/${NAME}/${INSTRUMENT}/${START_DATE}
		$DFO_GUI_DIR/refresh_browser ${WEB_URL}/${NAME}/${INSTRUMENT}/${START_DATE}/cascade_${INSTRUMENT}_${INS_MODE}.html
	else
		scp -o BatchMode=yes $TMP_DIR/cm_cascade.html ${DFO_WEB_SERVER}:${WEB_DIR}/${NAME}/cascade_${INSTRUMENT}_${INS_MODE}.html
		scp -o BatchMode=yes $RLS_FILE ${DFO_WEB_SERVER}:${WEB_DIR}/${NAME}
		$DFO_GUI_DIR/refresh_browser ${WEB_URL}/${NAME}/cascade_${INSTRUMENT}_${INS_MODE}.html
	fi

	if [ $NAME = DFOS_OPS ]
	then
		cat > $TMP_DIR/list_static_mcals_${INSTRUMENT}.txt <<EOT
# This is the list of pro.catgs of static calibrations for instrument $INSTRUMENT.
# It is derived from the DFOS_OPS OCA rules.
# Last created: `date -u +%Y-%m-%d"T"%H:%M:%S`
EOT
		cat $TMP_DIR/cm_gencalibs >> $TMP_DIR/list_static_mcals_${INSTRUMENT}.txt
		scp -o BatchMode=yes $TMP_DIR/list_static_mcals_${INSTRUMENT}.txt ${DFO_WEB_SERVER}:${WEB_DIR}/${NAME}/
	fi
	

	case $NAME in
	 "CALSELECTOR" ) CPATH=$NAME/${INSTRUMENT} ;;
	 *             ) CPATH=$NAME ;;
	esac

	echo "
Check out cascade_${INSTRUMENT}_${INS_MODE}.html .  "
else
	mv $TMP_DIR/cm_cascade.html $RLS_PATH/cascade_${INSTRUMENT}_${INS_MODE}.html
	$DFO_GUI_DIR/refresh_browser $RLS_PATH/cascade_${INSTRUMENT}_${INS_MODE}.html
	echo "
Check out $RLS_PATH/cascade_${INSTRUMENT}_${INS_MODE}.html .
No files exported.  "
fi

# ===========================================================================
# 4.2 For NAME=CALSELECTOR: coversheet to manage versions
# ===========================================================================

if [ $NAME = CALSELECTOR ]
then
	cat > $TMP_DIR/cm_cascade.html <<EOT
<html>
<!-- created by createCalibMap v${TOOL_VERSION} -->
<title>$INSTRUMENT $NAME calibration cascades</title>
<h2>$INSTRUMENT $NAME calibration cascades</h2>
<font size=2>These rule files cover the raw2master mode.<p>
If several versions exist, each version is valid between the listed start date and the date of the next version. For instance,<br> 
if a rule exists with start date 2004-03-28 and another version with start date 2008-04-01, then the older rule applies to all science<br>
data between 2004-03-28 and the night before 2008-04-01. For science data from 2008-04-01 on, the new version is applicable.<p>
The validity ranges
are automatically taken into account by the calSelector tool. 
</font>
<table>
  <tr><td><font size=2><a href=${WEB_URL}/oca_rule_sets.html>back</a> to main page</td></tr>
  <tr><td><font size=2><p><b>Select version of calib map:</b></td></tr>
  <tr bgcolor=#CCCCCC><td><font size=2>Calib map/start-date</font></td><td><font size=2>OCA file</font></td><td><font size=2>Comment</font></td></tr>
EOT

	rm -f $TMP_DIR/ha_versions
	grep "^START_DATE" $RLS_PATH1/config.createCalibMap.calsel | awk '{print $2}' > $TMP_DIR/ha_versions
	for S in `cat $TMP_DIR/ha_versions`
	do
# Check if RLS really exists
		if [ ! -s ${RLS_PATH1}/$S/${INSTRUMENT}_raw2master.${S}.RLS ]
		then
			echo "***ERROR: $S/${INSTRUMENT}_raw2master.${S}.RLS is configured in ${RLS_PATH1}/config.createCalibMap.calsel but does not exist.
Fix your configuration and then try again."
			exit -1
		fi
		COMMENT=`grep "^START_DATE" $RLS_PATH1/config.createCalibMap.calsel | grep "$S" | sed "s/&&$//" | sed "s/^.*&&//"`
		cat >> $TMP_DIR/cm_cascade.html <<EOT
<tr bgcolor=#EEEEEE>
  <td>
    <font size=2><a href=$S/cascade_${INSTRUMENT}_ALL.html>$S</a></font>
  </td>
  <td>
    <font size=2><a href=$S/${INSTRUMENT}_raw2master.${S}.RLS>${INSTRUMENT}_raw2master.${S}.RLS</a></font>
  </td>
  <td>
    <font size=2>$COMMENT</font>
  </td>
</tr>

<tr>
  <td COLSPAN=99 align=right><font size=1 color=#FFFFFF><b>powered by QC</b> [createCalibMap v${TOOL_VERSION}] last update: `date -u +%Y-%m-%d"T"%H:%M:%S`</font></td>
</tr>

EOT
	done

	cat >> $TMP_DIR/cm_cascade.html <<EOT
</table>
</html> 
EOT

	if [ Q$INS_MODE = QALL ]
	then
		if [ $SCP = YES ]
		then
			scp -o BatchMode=yes $TMP_DIR/cm_cascade.html ${DFO_WEB_SERVER}:${WEB_DIR}/${NAME}/${INSTRUMENT}/cascade_${INSTRUMENT}_ALL.html
			$DFO_GUI_DIR/refresh_browser "${WEB_URL}/${NAME}/${INSTRUMENT}/cascade_${INSTRUMENT}_ALL.html"
		else
			$DFO_GUI_DIR/refresh_browser "$DFO_CONFIG_DIR/CALSELECTOR/$START_DATE/cascade_${INSTRUMENT}_ALL.html"
		fi
			
		echo "Please check out the result page. If something is not ok, please check out 
$DFO_CONFIG_DIR/CALSELECTOR/config.createCalibMap.calsel, fix the content there, 
and then call the tool again.

Hit return if all is ok:"
        	read input
	fi
fi

# ===========================================================================
# 4.3 If mode=ALL, offer to call individual modes now
# ===========================================================================

if [ Q$INS_MODE != QALL ]
then
	exit
fi

echo "
INS_MODE = ALL: You could now create all sub-cascades as configured under 'ALL_MODES' in 
$RLS_PATH/config.createCalibMap. Just call

$TOOL_NAME -r $RLS_FILE -A 

"

exit
